AlkiraiLinkDocs

Reference

API reference

Connect people's accounts at institutions across the Caribbean, and read their balances and transactions. Every request carries your client ID in the X-Client-Id header and a secret in the X-API-Key header, from your server only. One client ID serves both the sandbox and live; the secret decides which one you reach.

Base URL
https://api.alkirai.com
Authentication
Your client ID in the X-Client-Id header and a secret in the X-API-Key header, from your server only.
Format
JSON in and out. Every failure has the same body: see Errors.
Rate
At most 120 requests a minute from one address.
EndpointWhat it does
GET /v1/institutionsList institutions
POST /v1/connect/sessionsStart a Connect session
POST /v1/connect/exchangeExchange a public token
GET /v1/connectionsList connections
GET /v1/connections/{connection_id}Get a connection
DELETE /v1/connections/{connection_id}Remove a connection
GET /v1/connections/{connection_id}/accountsList accounts
POST /v1/connections/{connection_id}/syncSync transactions
POST /v1/connections/{connection_id}/refreshRefresh a connection
GET /v1/institutions/{institution_id}/export-recipeGet an export recipe
GET /v1/institutions/{institution_id}/manifestGet a signed manifest
POST /v1/institutions/{institution_id}/statementsRead a statement
POST /v1/institutions/{institution_id}/statement-planPlan which months to export

Institutions

Who can be connected, and how each one stays current.

List institutions

GET/v1/institutions

Every institution this key may connect. A sandbox key sees the sandbox institutions and nothing else; a live key never sees them. sync_mode and runs_on say how each institution stays current and where its sign-in happens, so you know before anybody connects.

Returns

200 The institutions this key may connect. array of Institution

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/institutions" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Connect

The hosted sign-in. The person types their details into Connect, never into your app.

Start a Connect session

POST/v1/connect/sessions

Mints a link_token and the link_url to open in the person's browser or web view. Connect takes their sign-in details and any one-time code, then sends the browser to your redirect_uri with public_token and, if you sent one, state. The redirect_uri must be registered for your key and is matched exactly. The session lasts 10 minutes. Not for an institution whose runs_on is client, which answers 400. With connection_id, Connect signs the person in again to a connection you already hold instead of making a new one; a connection that is not yours answers 404.

Request body

JSON, a LinkSessionRequest. At most 64 KiB.

FieldTypeDescription
institution_idstringThe institution to connect. Leave it out and Connect opens on a list of the institutions this key can connect, for the person to choose from.
redirect_urirequiredstringWhere Connect sends the browser when it finishes. Must be registered for your key.
statestringAnything you like, sent back on the redirect, to tie it to the person who started it. At most 512 characters.
productsarray of ProductWhat to ask the person for beyond accounts and transactions. Connect tells them before they sign in. Omit it for accounts and transactions only.
max_accountsintegerThe most accounts the person may share with you, if your product limits it. Connect holds them to it when they choose, so you never receive a connection you would have to refuse. 0, or left out, for no limit. Default 0.
connection_idstringA connection you already hold whose sign-in has stopped working, for example after the person changed their password. Connect signs them in to it again, and the exchange returns the same connection_id, with the same account ids and your cursor still valid. The person is not asked to choose accounts again, and products and max_accounts are ignored. institution_id may be left out. At most 255 characters.

Returns

200 The token and the address to open. LinkSessionResponse

Errors

StatusWhen
400The request can't be carried out as sent; error.message says why.
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
413The body is over this route's limit, given as x-body-limit.
422The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl -X POST "https://api.alkirai.com/v1/connect/sessions" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "institution_id": "sandbox_bank",
    "redirect_uri": "https://example.com/connected",
    "state": "person-42"
  }'

Exchange a public token

POST/v1/connect/exchange

Trades the public_token from your redirect for the connection_id you keep. A public token lasts 60 seconds and works once, so exchange it as soon as your redirect is called: a connection nobody exchanges is deleted after 5 minutes. After a sign-in again, it is the connection you sent, and an exchange that never happens deletes nothing.

Request body

JSON, a ExchangeRequest. At most 64 KiB.

FieldTypeDescription
public_tokenrequiredstringThe public_token query parameter Connect sent to your redirect_uri.

Returns

200 The new connection. ExchangeResponse

Errors

StatusWhen
400The request can't be carried out as sent; error.message says why.
401The API key is missing, unknown, expired or revoked.
413The body is over this route's limit, given as x-body-limit.
422The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl -X POST "https://api.alkirai.com/v1/connect/exchange" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET" \
  -H "Content-Type: application/json" \
  -d "{\"public_token\": \"$PUBLIC_TOKEN\"}"

Connections

A connection is one person's sign-in at one institution. Read its state, its accounts and its transactions.

List connections

GET/v1/connections

Every connection this key made, with each one's state. Read without signing in to any institution, so it costs no sign-ins.

Returns

200 This key's connections. ConnectionList

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/connections" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Get a connection

GET/v1/connections/{connection_id}

One connection's state and sign-in budget, read without signing in. active: a sync would sign in now. stopped: syncs are refused until something changes, and error says what. at_limit: the sign-in budget is spent until sign_ins.next_at.

Path parameters

NameTypeDescription
connection_idrequiredstringThe id from Exchange a public token.

Returns

200 The connection's state. ConnectionStatus

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/connections/$CONNECTION_ID" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Remove a connection

DELETE/v1/connections/{connection_id}

Deletes the connection and the sign-in details AlkiraiLink stored for it. Safe to repeat: removing an unknown connection still answers removed: true. When action_required is not empty, show it to the person, because something is left at the institution that only they can clear.

Path parameters

NameTypeDescription
connection_idrequiredstringThe id from Exchange a public token.

Returns

200 What the removal did. RemovalOutcome

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl -X DELETE "https://api.alkirai.com/v1/connections/$CONNECTION_ID" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

List accounts

GET/v1/connections/{connection_id}/accounts

The connection's accounts and balances. Signs in to the institution, so it spends one of the connection's sign-ins; to read accounts and transactions together, use Refresh a connection. For 15 minutes after a connect, reads are answered from the connect's own sign-in.

Path parameters

NameTypeDescription
connection_idrequiredstringThe id from Exchange a public token.

Returns

200 The accounts. array of Account

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
409The connection is stopped, or its institution needs the person there to sign in. Nothing was sent to the institution. error.code and error.user_action say what unblocks it.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
502Signed in, and then the read failed. Nothing was stopped; error.code says why.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/connections/$CONNECTION_ID/accounts" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Sync transactions

POST/v1/connections/{connection_id}/sync

Transactions added, modified and removed since cursor. Send no cursor the first time; store the one returned and send it next time. History can arrive over several syncs, so keep syncing with the cursor returned. When partial_failure is set, the diff is real but incomplete: store what arrived, keep the new cursor and sync again later. Signs in, as List accounts does.

Path parameters

NameTypeDescription
connection_idrequiredstringThe id from Exchange a public token.

Query parameters

NameTypeDescription
cursorstringThe cursor from this connection's last sync. Omit it the first time.

Returns

200 What changed, and the next cursor. SyncResult

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
409The connection is stopped, or its institution needs the person there to sign in. Nothing was sent to the institution. error.code and error.user_action say what unblocks it.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
502Signed in, and then the read failed. Nothing was stopped; error.code says why.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl -X POST "https://api.alkirai.com/v1/connections/$CONNECTION_ID/sync?cursor=$CURSOR" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Refresh a connection

POST/v1/connections/{connection_id}/refresh

Accounts and a transaction sync from one sign-in. Prefer it to List accounts followed by Sync transactions, which signs in twice. transactions is exactly what Sync transactions returns for the same cursor.

Path parameters

NameTypeDescription
connection_idrequiredstringThe id from Exchange a public token.

Query parameters

NameTypeDescription
cursorstringThe cursor from this connection's last sync. Omit it the first time.

Returns

200 The accounts, and what changed. RefreshResult

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
409The connection is stopped, or its institution needs the person there to sign in. Nothing was sent to the institution. error.code and error.user_action say what unblocks it.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
502Signed in, and then the read failed. Nothing was stopped; error.code says why.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl -X POST "https://api.alkirai.com/v1/connections/$CONNECTION_ID/refresh?cursor=$CURSOR" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Sign-in sync

Institutions whose sign-in happens on the person's own device, through the AlkiraiLink mobile SDK. Your server reads the statements the SDK exports.

Get an export recipe

GET/v1/institutions/{institution_id}/export-recipe

What the mobile SDK needs to run a sign-in sync at this institution. Fetch it from your server and pass it to the SDK unchanged: its fields are the SDK's to read, and they change when the institution's site does. Only for an institution whose runs_on is client; any other answers 404.

Path parameters

NameTypeDescription
institution_idrequiredstringAn institution's id, from List institutions.

Returns

200 The recipe, for the SDK. ExportRecipe

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/institutions/sandbox_statements/export-recipe" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Get a signed manifest

GET/v1/institutions/{institution_id}/manifest

The address the SDK opens for this institution's sign-in and its export recipe, signed by AlkiraiLink, so the SDK can check that neither was changed on the way. Fetch it from your server and pass it to the SDK byte for byte: do not parse, re-encode or reorder it. Only for an institution whose runs_on is client; any other answers 404.

Path parameters

NameTypeDescription
institution_idrequiredstringAn institution's id, from List institutions.

Returns

200 The signed manifest: payload and signature, both base64url. any

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

curl "https://api.alkirai.com/v1/institutions/sandbox_statements/manifest" \
  -H "X-Client-Id: $ALKIRAILINK_CLIENT_ID" \
  -H "X-API-Key: $ALKIRAILINK_SECRET"

Read a statement

POST/v1/institutions/{institution_id}/statements

Reads one exported statement file into accounts and transactions, and returns your cursor with the file's months added. AlkiraiLink keeps nothing it is sent: not the file, not its rows, not the cursor. transactions is every row in the file, not a diff, so upsert by transaction_id, which is the same for the same row in overlapping files. Send a sign-in's files one at a time, each with the cursor the one before returned.

Path parameters

NameTypeDescription
institution_idrequiredstringAn institution's id, from List institutions.

Request body

JSON, a StatementUpload. At most 1.5 MiB.

FieldTypeDescription
statement_base64requiredstringThe file's bytes, base64, with no data: prefix. At most 1 MiB decoded. At most 1398104 characters.
cursorstringThe cursor the last statement or plan returned. Empty the first time. At most 65536 characters.
page_balancesarray of PageReadingWhat the page showed each account to hold, from the sign-in that exported this file. Sets balance_available. The first 50 are read.

Returns

200 The file's accounts, rows and coverage, and the new cursor. StatementRead

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
413The body is over this route's limit, given as x-body-limit.
422The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

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>"
  }'

Plan which months to export

POST/v1/institutions/{institution_id}/statement-plan

Which months to export for each account, from your cursor and the months the institution's page offers. The newest month on offer is always included, because it is the one a late transaction lands in. Writes nothing.

Path parameters

NameTypeDescription
institution_idrequiredstringAn institution's id, from List institutions.

Request body

JSON, a StatementPlanRequest. At most 128 KiB.

FieldTypeDescription
cursorstringThe cursor the last statement or plan returned. Empty the first time. At most 65536 characters.
accountsarray of PageReadingEvery account the page shows. Only account and currency are read; the first 50 are read.
offered_monthsarray of stringyyyy-mm, every month the page's export offers. Empty when the page hasn't shown them yet: then subtract complete_months yourself.

Returns

200 The months to fetch, per account. StatementPlan

Errors

StatusWhen
401The API key is missing, unknown, expired or revoked.
404Nothing by that id that this key may see. Another key's connection is also 404.
413The body is over this route's limit, given as x-body-limit.
422The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field.
429Refused for now: the connection's sign-in budget is spent, another sign-in is running on it, or this address sent more than 120 requests in a minute. Wait for Retry-After when it is sent. The per-address limit is answered before the API and has no JSON body.
500Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID.
503AlkiraiLink can't take the request right now. Try again shortly.

Example

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"
    ]
  }'

Objects

Every object a request sends or a response returns. A field not marked required may be left out of a request, and is always present in a response.

Account

One account at the institution.

FieldTypeDescription
account_idrequiredstringStable: the same account always has the same id, so key your records on it.
namerequiredstringThe account's name at the institution.
typerequiredAccountTypeWhat kind of account it is.
subtypestringThe institution's own product name, or empty.
maskstringThe account number's last digits. Never the full number.
currencyrequiredstringISO 4217 currency code. A connection can hold accounts in several currencies, so convert before adding balances up.
balance_currentnumber or nullThe balance, in currency. Null when the institution doesn't say.
balance_availablenumber or nullWhat can be spent now, when the institution says.
balance_limitnumber or nullThe credit limit, as a positive number, when there is one.

AccountPlan

The months to export for one account.

FieldTypeDescription
accountrequiredstringThe digits the request named it by.
currencyrequiredstringISO 4217 currency code.
fetch_monthsrequiredarray of stringMonths to export, oldest first.
complete_monthsarray of stringMonths the cursor already holds in full, oldest first.

AccountType

What kind of account it is: depository (current and savings), credit, loan, investment or other.

  • depository
  • credit
  • loan
  • investment
  • other

ConnectionList

This key's connections.

FieldTypeDescription
connectionsrequiredarray of ConnectionStatusOne entry per connection.

ConnectionState

What the next sync would meet. active: it would sign in now. stopped: refused until the person acts, or until we fix our side; the connection's error says which. at_limit: the sign-in budget is spent until sign_ins.next_at, and nothing is wrong.

  • active
  • stopped
  • at_limit

ConnectionStatus

A connection's state, read without signing in.

FieldTypeDescription
connection_idrequiredstringThe connection's id.
institution_idrequiredstringThe institution it connects.
ownerrequiredstringThe caller that made it, which is always the key's own.
created_atstring or nullWhen the person connected (ISO 8601, UTC). Reconnecting makes a new connection.
staterequiredConnectionStateWhat the next sync would meet.
errorErrorBody or nullWhy the connection is stopped. Only on a stopped connection.
sign_insrequiredSignInUsageIts sign-ins against the institution's budget.

ErrorBody

What went wrong.

FieldTypeDescription
coderequiredErrorCodeWhat happened. Branch on this.
messagerequiredstringFor you, the developer. Never show it to the person.
retryablebooleanWhether the same request may succeed later with nobody doing anything. Default false.
request_idstringQuote it when you write to us. Also sent as the X-Request-Id header.
typeErrorType or nullWhose problem it is.
user_actionUserAction or nullWhat the person has to do.
display_messagestring or nullA sentence safe to show the person, or null when there is nothing they should see.
retry_afterinteger or nullSeconds to wait, as in the Retry-After header, when known.
stopped_atstring or nullWhen the connection was stopped (ISO 8601, UTC). Only on a stopped connection.

ErrorCode

What happened. Every code, with its type, the person's action and whether to retry, is listed in x-error-codes.

  • invalid_credentials
  • challenge_failed
  • session_expired
  • account_locked
  • mfa_required
  • institution_down
  • connector_broken
  • rate_limited
  • unsupported
  • internal
  • sign_in_incomplete
  • consent_required
  • different_login
  • invalid_request
  • unauthorized
  • forbidden
  • not_found
  • expired
  • service_unavailable

ErrorEnvelope

The body of every failed response.

FieldTypeDescription
detailrequiredstring or array of objectThe same as error.message, except on a 422 for the request's shape, where it lists each field that didn't match.
errorrequiredErrorBodyWhat went wrong, as a code to branch on.

ErrorType

Whose problem it is. connection_error: the person has to act. institution_error: the institution, or our connection to it. rate_limit_error: too many requests. invalid_request: yours to fix. api_error: ours.

  • connection_error
  • institution_error
  • rate_limit_error
  • invalid_request
  • api_error

ExchangeRequest

The token from your redirect.

FieldTypeDescription
public_tokenrequiredstringThe public_token query parameter Connect sent to your redirect_uri.

ExchangeResponse

The new connection.

FieldTypeDescription
connection_idrequiredstringKeep this: every Connections call takes it.
institution_idrequiredstringThe institution connected.
institution_namestringIts name, to label the connection. Can be empty, so keep a fallback.
unattended_blockedstring or nullSet when the connection works now but can't sync without the person, and says why. Show it to them.

Execution

Where the sign-in happens. server: AlkiraiLink signs in, after the person connects through Connect. client: the person's own device signs in, through the mobile SDK.

  • server
  • client

ExportRecipe

Read by the mobile SDK, not by your code. Pass it on unchanged; its fields change when the institution's site does.

GroupBasis

How a group was made: reference (the institution's own reference) or same_day (matched on the same account and day).

  • reference
  • same_day

IdentityField

One of the person's details, as the institution holds it. person_name: the name of the person who signed in. address: their address. holder_names: the names on each account, which can include a joint holder. account_number: each account's full number, never a card's.

  • person_name
  • address
  • holder_names
  • account_number

Institution

An institution AlkiraiLink can connect.

FieldTypeDescription
institution_idrequiredstringIts id, used everywhere else.
namerequiredstringIts name, to show.
countryrequiredstringISO 3166-1 alpha-2 country code.
logo_urlstringA logo to show, or empty.
betabooleanTrue until the institution is generally available. Tell people before they rely on a beta connection. Default true.
supports_transactionsbooleanWhether connections here return transactions. Default true.
supports_balancesbooleanWhether connections here return balances. Default true.
sync_modeSyncModeWhether it can refresh with nobody present. Default "unattended".
runs_onExecutionWhere the sign-in happens. Default "server".
sign_in_urlstring or nullFor a client institution, the page the SDK opens for the person to sign in. Null otherwise.
identityarray of IdentityFieldWhich of the person's details this institution can share, when they agree to it at Connect. Empty when it shares none.

LinkSessionRequest

What to connect, and where to send the person afterwards.

FieldTypeDescription
institution_idstringThe institution to connect. Leave it out and Connect opens on a list of the institutions this key can connect, for the person to choose from.
redirect_urirequiredstringWhere Connect sends the browser when it finishes. Must be registered for your key.
statestringAnything you like, sent back on the redirect, to tie it to the person who started it. At most 512 characters.
productsarray of ProductWhat to ask the person for beyond accounts and transactions. Connect tells them before they sign in. Omit it for accounts and transactions only.
max_accountsintegerThe most accounts the person may share with you, if your product limits it. Connect holds them to it when they choose, so you never receive a connection you would have to refuse. 0, or left out, for no limit. Default 0.
connection_idstringA connection you already hold whose sign-in has stopped working, for example after the person changed their password. Connect signs them in to it again, and the exchange returns the same connection_id, with the same account ids and your cursor still valid. The person is not asked to choose accounts again, and products and max_accounts are ignored. institution_id may be left out. At most 255 characters.

LinkSessionResponse

A Connect session.

FieldTypeDescription
link_tokenrequiredstringIdentifies this Connect session.
link_urlrequiredstringOpen this in the person's browser or web view.
expires_inrequiredintegerSeconds until the session expires.

PageReading

One account as the institution's page showed it, read by the SDK while the person was signed in.

FieldTypeDescription
accountstringThe account number's last three or four digits, as the page showed them.
currencystringISO 4217 currency code, as the page showed it.
amountstringThe balance exactly as the page showed it, such as "1,234.56".

PersonalFinanceCategory

A transaction's category.

FieldTypeDescription
primaryrequiredstringThe broad category, such as RENT_AND_UTILITIES or INCOME.
detailedrequiredstringThe precise category, such as RENT_AND_UTILITIES_TELEPHONE or INCOME_SALARY. Always one of primary's own. OTHER_OTHER when nothing in the row said what it was.
confidence_levelrequiredstringHow sure the category is: HIGH when the institution itself called the row a fee or the payee is a known business, MEDIUM when the description's words say what it was, LOW for a card purchase that names nothing more and for anything unmatched. VERY_HIGH and UNKNOWN are never sent.
versionstringThe taxonomy's version: v2. Default "v2".

Product

Something a Connect session can ask the person for beyond accounts and transactions. identity: the details the institution lists under identity.

  • identity

RefreshResult

Accounts and a sync, from one sign-in.

FieldTypeDescription
accountsrequiredarray of AccountThe connection's accounts.
transactionsrequiredSyncResultExactly what Sync transactions returns for the same cursor.

RemovalOutcome

What removing a connection did.

FieldTypeDescription
removedrequiredbooleanAlways true: the connection and its sign-in details are gone.
action_requiredstringSomething left at the institution that only the person can clear, in words to show them. Empty when there is nothing.

RunningBalance

Whether a file's running balance follows from row to row. balanced: every row follows the one before. off: one doesn't, see first_break. unchecked: too few rows to tell.

  • balanced
  • off
  • unchecked

SignInUsage

A connection's sign-ins against its institution's budget. Each institution sets how many sign-ins one connection may make in a window, and the connect's own sign-in counts.

FieldTypeDescription
recentrequiredintegerSign-ins counted in the current window.
limitinteger or nullHow many the window allows. Null when the institution no longer exists.
window_hoursnumber or nullThe window, in hours.
last_atstring or nullWhen the latest counted sign-in started (ISO 8601, UTC).
next_atstring or nullThe earliest the next sign-in is allowed, when the budget is spent (ISO 8601, UTC).

StatementCoverage

What one file says about itself.

FieldTypeDescription
account_idrequiredstringThe account the file belongs to.
period_startstring (date) or nullThe first day the file says it covers.
period_endstring (date) or nullThe last day the file says it covers.
exported_onstring (date) or nullThe day the institution produced the file.
balance_onstring (date) or nullThe date the account's balance is as of. When you read several files, take the balance from the one with the latest date here.
running_balanceRunningBalanceWhether the file's running balance follows from row to row. Default "unchecked".
first_breakstring (date) or nullThe first date the running balance doesn't follow, when it doesn't.
monthsarray of StatementMonthEach month the file covers.
recordedbooleanWhether the cursor took this file's months. False for a file with a line error or a running balance that doesn't follow. Default false.

StatementMonth

One month a file covers.

FieldTypeDescription
monthrequiredstringyyyy-mm.
covered_fromrequiredstring (date)The first day of the month the file holds.
covered_throughrequiredstring (date)The last day of the month the file holds.
completerequiredbooleanWhether the file holds the whole month, settled. Never true for the current month.

StatementPlan

Which months to export.

FieldTypeDescription
accountsrequiredarray of AccountPlanOne per usable account in the request, in its order. An account left out couldn't be matched: export every month for it.
cursor_resetbooleanTrue when the cursor you sent couldn't be read and was treated as empty. Default false.

StatementPlanRequest

What the page shows, and your cursor.

FieldTypeDescription
cursorstringThe cursor the last statement or plan returned. Empty the first time. At most 65536 characters.
accountsarray of PageReadingEvery account the page shows. Only account and currency are read; the first 50 are read.
offered_monthsarray of stringyyyy-mm, every month the page's export offers. Empty when the page hasn't shown them yet: then subtract complete_months yourself.

StatementRead

One statement file, read.

FieldTypeDescription
accountsrequiredarray of AccountThe file's account.
transactionsrequiredarray of TransactionEvery row in the file. Upsert by transaction_id.
statementrequiredStatementCoverageWhat the file says it covers.
errorsarray of stringLines that couldn't be read. Any line error keeps the file's months out of the cursor, so they are fetched again.
cursorrequiredstringStore it and send it with the next statement or plan.
cursor_resetbooleanTrue when the cursor you sent couldn't be read and was treated as empty. Nothing is lost; more months are fetched next time. Default false.

StatementUpload

One exported statement file.

FieldTypeDescription
statement_base64requiredstringThe file's bytes, base64, with no data: prefix. At most 1 MiB decoded. At most 1398104 characters.
cursorstringThe cursor the last statement or plan returned. Empty the first time. At most 65536 characters.
page_balancesarray of PageReadingWhat the page showed each account to hold, from the sign-in that exported this file. Sets balance_available. The first 50 are read.

SyncMode

How an institution stays current. unattended: your app can refresh on a schedule, with nobody present. attended: every refresh needs the person, through Connect or a sign-in sync.

  • unattended
  • attended

SyncResult

What changed since the cursor you sent.

FieldTypeDescription
addedarray of TransactionNew transactions.
modifiedarray of TransactionTransactions you have that changed. Replace them by transaction_id.
removed_idsarray of stringTransactions to delete, by transaction_id.
cursorstringStore it and send it next time.
partial_failurestring or nullSet when the read stopped partway. What arrived is real: store it and the cursor, and sync again later.

Transaction

One transaction.

FieldTypeDescription
transaction_idrequiredstringStable across syncs, so upsert by it.
account_idrequiredstringThe account it belongs to.
amountrequirednumberPositive for money leaving the account, negative for money arriving.
currencyrequiredstringISO 4217 currency code.
daterequiredstring (date)The date it posted.
descriptionrequiredstringThe institution's description of it.
merchant_namestringA clean name for the business, when one can be named: a known payee, or the business a card purchase was made at. Empty for transfers, deposits, cheques and anything else that could name a person.
pendingbooleanTrue while it has not posted. Default false.
raw_categorystringThe institution's own category, unchanged, or empty.
personal_finance_categoryPersonalFinanceCategory or nullWhat kind of money this is, in the widely used personal finance category taxonomy, chosen from the institution's words with rules written for the region. A default: your own rules and your user's choices should win.
reference_numberstringThe institution's own reference, as it prints it, or empty. Not unique: a purchase and its fee can share one. Use transaction_id to tell rows apart.
group_idstringRows that belong together, such as a purchase, its fee and their reversals, share this value. Empty when nothing ties the row to another. Group by this, not by reference_number.
group_basisGroupBasis or nullHow group_id was made, or null when it is empty: reference when the institution printed one reference on every row, same_day when it printed none and the charge was matched to the only row of the kind its description names on the same account and day.
roleTransactionRole or nullfee or tax when the institution says the row is a charge on another row in its group, otherwise null.

TransactionRole

What a row is to the others in its group: fee or tax.

  • fee
  • tax

UserAction

What the person has to do. reconnect: connect again. contact_institution: clear it with the institution, then reconnect. sign_in: refresh with them there. none: nothing.

  • reconnect
  • contact_institution
  • sign_in
  • none