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-Idheader and a secret in theX-API-Keyheader, 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.
| Endpoint | What it does |
|---|---|
GET /v1/institutions | List institutions |
POST /v1/connect/sessions | Start a Connect session |
POST /v1/connect/exchange | Exchange a public token |
GET /v1/connections | List connections |
GET /v1/connections/{connection_id} | Get a connection |
DELETE /v1/connections/{connection_id} | Remove a connection |
GET /v1/connections/{connection_id}/accounts | List accounts |
POST /v1/connections/{connection_id}/sync | Sync transactions |
POST /v1/connections/{connection_id}/refresh | Refresh a connection |
GET /v1/institutions/{institution_id}/export-recipe | Get an export recipe |
GET /v1/institutions/{institution_id}/manifest | Get a signed manifest |
POST /v1/institutions/{institution_id}/statements | Read a statement |
POST /v1/institutions/{institution_id}/statement-plan | Plan 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
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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.
| Field | Type | Description |
|---|---|---|
institution_id | string | The 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_urirequired | string | Where Connect sends the browser when it finishes. Must be registered for your key. |
state | string | Anything you like, sent back on the redirect, to tie it to the person who started it. At most 512 characters. |
products | array of Product | What to ask the person for beyond accounts and transactions. Connect tells them before they sign in. Omit it for accounts and transactions only. |
max_accounts | integer | The 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_id | string | A 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
| Status | When |
|---|---|
400 | The request can't be carried out as sent; error.message says why. |
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
413 | The body is over this route's limit, given as x-body-limit. |
422 | The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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.
| Field | Type | Description |
|---|---|---|
public_tokenrequired | string | The public_token query parameter Connect sent to your redirect_uri. |
Returns
200 The new connection. ExchangeResponse
Errors
| Status | When |
|---|---|
400 | The request can't be carried out as sent; error.message says why. |
401 | The API key is missing, unknown, expired or revoked. |
413 | The body is over this route's limit, given as x-body-limit. |
422 | The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
connection_idrequired | string | The id from Exchange a public token. |
Returns
200 The connection's state. ConnectionStatus
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
connection_idrequired | string | The id from Exchange a public token. |
Returns
200 What the removal did. RemovalOutcome
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
connection_idrequired | string | The id from Exchange a public token. |
Returns
200 The accounts. array of Account
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
409 | The 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. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
502 | Signed in, and then the read failed. Nothing was stopped; error.code says why. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
connection_idrequired | string | The id from Exchange a public token. |
Query parameters
| Name | Type | Description |
|---|---|---|
cursor | string | The cursor from this connection's last sync. Omit it the first time. |
Returns
200 What changed, and the next cursor. SyncResult
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
409 | The 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. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
502 | Signed in, and then the read failed. Nothing was stopped; error.code says why. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
connection_idrequired | string | The id from Exchange a public token. |
Query parameters
| Name | Type | Description |
|---|---|---|
cursor | string | The cursor from this connection's last sync. Omit it the first time. |
Returns
200 The accounts, and what changed. RefreshResult
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
409 | The 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. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
502 | Signed in, and then the read failed. Nothing was stopped; error.code says why. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
institution_idrequired | string | An institution's id, from List institutions. |
Returns
200 The recipe, for the SDK. ExportRecipe
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
institution_idrequired | string | An institution's id, from List institutions. |
Returns
200 The signed manifest: payload and signature, both base64url. any
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
institution_idrequired | string | An institution's id, from List institutions. |
Request body
JSON, a StatementUpload. At most 1.5 MiB.
| Field | Type | Description |
|---|---|---|
statement_base64required | string | The file's bytes, base64, with no data: prefix. At most 1 MiB decoded. At most 1398104 characters. |
cursor | string | The cursor the last statement or plan returned. Empty the first time. At most 65536 characters. |
page_balances | array of PageReading | What 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
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
413 | The body is over this route's limit, given as x-body-limit. |
422 | The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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
| Name | Type | Description |
|---|---|---|
institution_idrequired | string | An institution's id, from List institutions. |
Request body
JSON, a StatementPlanRequest. At most 128 KiB.
| Field | Type | Description |
|---|---|---|
cursor | string | The cursor the last statement or plan returned. Empty the first time. At most 65536 characters. |
accounts | array of PageReading | Every account the page shows. Only account and currency are read; the first 50 are read. |
offered_months | array of string | yyyy-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
| Status | When |
|---|---|
401 | The API key is missing, unknown, expired or revoked. |
404 | Nothing by that id that this key may see. Another key's connection is also 404. |
413 | The body is over this route's limit, given as x-body-limit. |
422 | The body didn't match the expected shape, or a statement couldn't be read. For a shape error, detail lists each field. |
429 | Refused 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. |
500 | Something failed on our side. Try again; if it keeps happening, write to hello@alkirai.com with the request ID. |
503 | AlkiraiLink 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.
| Field | Type | Description |
|---|---|---|
account_idrequired | string | Stable: the same account always has the same id, so key your records on it. |
namerequired | string | The account's name at the institution. |
typerequired | AccountType | What kind of account it is. |
subtype | string | The institution's own product name, or empty. |
mask | string | The account number's last digits. Never the full number. |
currencyrequired | string | ISO 4217 currency code. A connection can hold accounts in several currencies, so convert before adding balances up. |
balance_current | number or null | The balance, in currency. Null when the institution doesn't say. |
balance_available | number or null | What can be spent now, when the institution says. |
balance_limit | number or null | The credit limit, as a positive number, when there is one. |
AccountPlan
The months to export for one account.
| Field | Type | Description |
|---|---|---|
accountrequired | string | The digits the request named it by. |
currencyrequired | string | ISO 4217 currency code. |
fetch_monthsrequired | array of string | Months to export, oldest first. |
complete_months | array of string | Months the cursor already holds in full, oldest first. |
AccountType
What kind of account it is: depository (current and savings), credit, loan, investment or other.
depositorycreditloaninvestmentother
ConnectionList
This key's connections.
| Field | Type | Description |
|---|---|---|
connectionsrequired | array of ConnectionStatus | One 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.
activestoppedat_limit
ConnectionStatus
A connection's state, read without signing in.
| Field | Type | Description |
|---|---|---|
connection_idrequired | string | The connection's id. |
institution_idrequired | string | The institution it connects. |
ownerrequired | string | The caller that made it, which is always the key's own. |
created_at | string or null | When the person connected (ISO 8601, UTC). Reconnecting makes a new connection. |
staterequired | ConnectionState | What the next sync would meet. |
error | ErrorBody or null | Why the connection is stopped. Only on a stopped connection. |
sign_insrequired | SignInUsage | Its sign-ins against the institution's budget. |
ErrorBody
What went wrong.
| Field | Type | Description |
|---|---|---|
coderequired | ErrorCode | What happened. Branch on this. |
messagerequired | string | For you, the developer. Never show it to the person. |
retryable | boolean | Whether the same request may succeed later with nobody doing anything. Default false. |
request_id | string | Quote it when you write to us. Also sent as the X-Request-Id header. |
type | ErrorType or null | Whose problem it is. |
user_action | UserAction or null | What the person has to do. |
display_message | string or null | A sentence safe to show the person, or null when there is nothing they should see. |
retry_after | integer or null | Seconds to wait, as in the Retry-After header, when known. |
stopped_at | string or null | When 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_credentialschallenge_failedsession_expiredaccount_lockedmfa_requiredinstitution_downconnector_brokenrate_limitedunsupportedinternalsign_in_incompleteconsent_requireddifferent_logininvalid_requestunauthorizedforbiddennot_foundexpiredservice_unavailable
ErrorEnvelope
The body of every failed response.
| Field | Type | Description |
|---|---|---|
detailrequired | string or array of object | The same as error.message, except on a 422 for the request's shape, where it lists each field that didn't match. |
errorrequired | ErrorBody | What 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_errorinstitution_errorrate_limit_errorinvalid_requestapi_error
ExchangeRequest
The token from your redirect.
| Field | Type | Description |
|---|---|---|
public_tokenrequired | string | The public_token query parameter Connect sent to your redirect_uri. |
ExchangeResponse
The new connection.
| Field | Type | Description |
|---|---|---|
connection_idrequired | string | Keep this: every Connections call takes it. |
institution_idrequired | string | The institution connected. |
institution_name | string | Its name, to label the connection. Can be empty, so keep a fallback. |
unattended_blocked | string or null | Set 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.
serverclient
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).
referencesame_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_nameaddressholder_namesaccount_number
Institution
An institution AlkiraiLink can connect.
| Field | Type | Description |
|---|---|---|
institution_idrequired | string | Its id, used everywhere else. |
namerequired | string | Its name, to show. |
countryrequired | string | ISO 3166-1 alpha-2 country code. |
logo_url | string | A logo to show, or empty. |
beta | boolean | True until the institution is generally available. Tell people before they rely on a beta connection. Default true. |
supports_transactions | boolean | Whether connections here return transactions. Default true. |
supports_balances | boolean | Whether connections here return balances. Default true. |
sync_mode | SyncMode | Whether it can refresh with nobody present. Default "unattended". |
runs_on | Execution | Where the sign-in happens. Default "server". |
sign_in_url | string or null | For a client institution, the page the SDK opens for the person to sign in. Null otherwise. |
identity | array of IdentityField | Which 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.
| Field | Type | Description |
|---|---|---|
institution_id | string | The 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_urirequired | string | Where Connect sends the browser when it finishes. Must be registered for your key. |
state | string | Anything you like, sent back on the redirect, to tie it to the person who started it. At most 512 characters. |
products | array of Product | What to ask the person for beyond accounts and transactions. Connect tells them before they sign in. Omit it for accounts and transactions only. |
max_accounts | integer | The 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_id | string | A 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.
| Field | Type | Description |
|---|---|---|
link_tokenrequired | string | Identifies this Connect session. |
link_urlrequired | string | Open this in the person's browser or web view. |
expires_inrequired | integer | Seconds until the session expires. |
PageReading
One account as the institution's page showed it, read by the SDK while the person was signed in.
| Field | Type | Description |
|---|---|---|
account | string | The account number's last three or four digits, as the page showed them. |
currency | string | ISO 4217 currency code, as the page showed it. |
amount | string | The balance exactly as the page showed it, such as "1,234.56". |
PersonalFinanceCategory
A transaction's category.
| Field | Type | Description |
|---|---|---|
primaryrequired | string | The broad category, such as RENT_AND_UTILITIES or INCOME. |
detailedrequired | string | The 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_levelrequired | string | How 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. |
version | string | The 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.
| Field | Type | Description |
|---|---|---|
accountsrequired | array of Account | The connection's accounts. |
transactionsrequired | SyncResult | Exactly what Sync transactions returns for the same cursor. |
RemovalOutcome
What removing a connection did.
| Field | Type | Description |
|---|---|---|
removedrequired | boolean | Always true: the connection and its sign-in details are gone. |
action_required | string | Something 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.
balancedoffunchecked
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.
| Field | Type | Description |
|---|---|---|
recentrequired | integer | Sign-ins counted in the current window. |
limit | integer or null | How many the window allows. Null when the institution no longer exists. |
window_hours | number or null | The window, in hours. |
last_at | string or null | When the latest counted sign-in started (ISO 8601, UTC). |
next_at | string or null | The earliest the next sign-in is allowed, when the budget is spent (ISO 8601, UTC). |
StatementCoverage
What one file says about itself.
| Field | Type | Description |
|---|---|---|
account_idrequired | string | The account the file belongs to. |
period_start | string (date) or null | The first day the file says it covers. |
period_end | string (date) or null | The last day the file says it covers. |
exported_on | string (date) or null | The day the institution produced the file. |
balance_on | string (date) or null | The 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_balance | RunningBalance | Whether the file's running balance follows from row to row. Default "unchecked". |
first_break | string (date) or null | The first date the running balance doesn't follow, when it doesn't. |
months | array of StatementMonth | Each month the file covers. |
recorded | boolean | Whether 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.
| Field | Type | Description |
|---|---|---|
monthrequired | string | yyyy-mm. |
covered_fromrequired | string (date) | The first day of the month the file holds. |
covered_throughrequired | string (date) | The last day of the month the file holds. |
completerequired | boolean | Whether the file holds the whole month, settled. Never true for the current month. |
StatementPlan
Which months to export.
| Field | Type | Description |
|---|---|---|
accountsrequired | array of AccountPlan | One per usable account in the request, in its order. An account left out couldn't be matched: export every month for it. |
cursor_reset | boolean | True when the cursor you sent couldn't be read and was treated as empty. Default false. |
StatementPlanRequest
What the page shows, and your cursor.
| Field | Type | Description |
|---|---|---|
cursor | string | The cursor the last statement or plan returned. Empty the first time. At most 65536 characters. |
accounts | array of PageReading | Every account the page shows. Only account and currency are read; the first 50 are read. |
offered_months | array of string | yyyy-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.
| Field | Type | Description |
|---|---|---|
accountsrequired | array of Account | The file's account. |
transactionsrequired | array of Transaction | Every row in the file. Upsert by transaction_id. |
statementrequired | StatementCoverage | What the file says it covers. |
errors | array of string | Lines that couldn't be read. Any line error keeps the file's months out of the cursor, so they are fetched again. |
cursorrequired | string | Store it and send it with the next statement or plan. |
cursor_reset | boolean | True 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.
| Field | Type | Description |
|---|---|---|
statement_base64required | string | The file's bytes, base64, with no data: prefix. At most 1 MiB decoded. At most 1398104 characters. |
cursor | string | The cursor the last statement or plan returned. Empty the first time. At most 65536 characters. |
page_balances | array of PageReading | What 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.
unattendedattended
SyncResult
What changed since the cursor you sent.
| Field | Type | Description |
|---|---|---|
added | array of Transaction | New transactions. |
modified | array of Transaction | Transactions you have that changed. Replace them by transaction_id. |
removed_ids | array of string | Transactions to delete, by transaction_id. |
cursor | string | Store it and send it next time. |
partial_failure | string or null | Set when the read stopped partway. What arrived is real: store it and the cursor, and sync again later. |
Transaction
One transaction.
| Field | Type | Description |
|---|---|---|
transaction_idrequired | string | Stable across syncs, so upsert by it. |
account_idrequired | string | The account it belongs to. |
amountrequired | number | Positive for money leaving the account, negative for money arriving. |
currencyrequired | string | ISO 4217 currency code. |
daterequired | string (date) | The date it posted. |
descriptionrequired | string | The institution's description of it. |
merchant_name | string | A 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. |
pending | boolean | True while it has not posted. Default false. |
raw_category | string | The institution's own category, unchanged, or empty. |
personal_finance_category | PersonalFinanceCategory or null | What 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_number | string | The 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_id | string | Rows 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_basis | GroupBasis or null | How 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. |
role | TransactionRole or null | fee 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.
feetax
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.
reconnectcontact_institutionsign_innone