Guides
Sign-in sync
Some institutions can only be signed in to from the person's own device. For those, your app signs the person in with the AlkiraiLink mobile SDK, and your server turns what the SDK exports into the same accounts and transactions as any other institution.
GET /v1/institutions reports these institutions with runs_on: "client" and sync_mode: "attended". Connect isn't used for them: a Connect session for one answers 400. Each refresh is the person signing in, in your app.
The mobile SDK is for iOS and Android. During early access it comes from our team, with your client ID and secrets: write to hello@alkirai.com.
How a sign-in sync runs
-
Your server fetches the recipe
GET /v1/institutions/{institution_id}/export-recipereturns what the SDK needs to work in the institution's pages. Pass it to the SDK unchanged: its fields are the SDK's to read, and they change when the institution's site does.curl "https://api.alkirai.com/v1/institutions/sandbox_statements/export-recipe" \ -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \ -H "X-API-Key: $ALKIRAILINK_SECRET" -
The person signs in, in your app
The SDK opens the institution's
sign_in_urlfrom the listing, and the person signs in there as they always do. Their details stay between them and their institution. -
Your server plans which months to export
The SDK reads what the page shows and asks your app which months to export. Your server answers with
POST /v1/institutions/{institution_id}/statement-plan, from the cursor it stored. The newest month is always included.curl -X POST "https://api.alkirai.com/v1/institutions/sandbox_statements/statement-plan" \ -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \ -H "X-API-Key: $ALKIRAILINK_SECRET" \ -H "Content-Type: application/json" \ -d '{ "cursor": "<the cursor you stored, or empty>", "accounts": [ { "account": "0001", "currency": "USD" } ], "offered_months": [ "2026-09", "2026-10" ] }' -
Your server reads each statement
For each file the SDK exports, call
POST /v1/institutions/{institution_id}/statementswith the cursor the call before returned. It answers with accounts, transactions and the new cursor.curl -X POST "https://api.alkirai.com/v1/institutions/sandbox_statements/statements" \ -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \ -H "X-API-Key: $ALKIRAILINK_SECRET" \ -H "Content-Type: application/json" \ -d '{ "statement_base64": "<the exported file, base64>", "cursor": "<the cursor you stored, or empty>" }'
The cursor is yours
AlkiraiLink keeps nothing it is sent for these institutions: not the file, not the rows, not a record of which months you hold. That record is the cursor, and your server stores it per person and institution.
- Send a sign-in's files one at a time, each with the cursor the one before returned. Two sent at once with the same cursor each miss the other's months, which costs a second export, never a transaction.
transactionsis every row in the file, not a diff. Upsert bytransaction_id: the same row has the same id in every file it appears in.- A file with a line that couldn't be read, or a running balance that doesn't follow, is still read, but
recordedis false and its months are fetched again next time. - When
cursor_resetis true, the cursor you sent couldn't be read and was treated as empty. Nothing is lost: more months are exported next time. - When several files cover an account, take its balance from the one whose
statement.balance_onis latest.
Each request body is limited: 1.5 MiB for a statement, 128 KiB for a plan.