Download OpenAPI specification:
AISP API for contracted partners: create a client, connect to a bank (directly or via the hosted connect flow), retrieve accounts and transactions, refresh or reconnect (capability-gated), and revoke consent.
This version is current for the connection lifecycle actions - create,
refresh, reconnect, revoke and delete - which exist only on /v1. Connect
sessions, partner config, providers, clients and all reads have their home on
/v2 (see the Partner API v2 reference); the /v1 connect-session and
partner-config paths are transitional aliases.
Sandbox and live mode are selected by the API key prefix (bb_test_… /
bb_live_…), never by the host. Guides:
https://aisp-docs.bbapi.io/guide/getting-started
The contract evolves additively: new endpoints, optional fields, envelope fields and enum values may be added without notice, and clients must ignore what they do not recognize.
Versioning is selective and applied per path — the /v1/ segment belongs to
each individual path, not to the base URL. Individual endpoints may advance to
/v2/ independently; do not hardcode /v1/ as a shared client-side prefix.
Every request requires X-Api-Key. Client-scoped endpoints additionally require
the X-Client-Id header. Production traffic passes our API gateway with
per-partner rate limits; optional enterprise hardening (mTLS, IP allowlisting)
is configured at the infrastructure level, not in this API.
Every error response carries a stable machine-readable error.code (see the
ErrorCode schema) alongside an informational errorDesc string. Clients and
SDKs MUST branch on error.code only and MUST NOT parse errorDesc. Every
response includes an X-Request-Id correlation header. 401 and 429 are
produced by the API gateway and may not carry the full envelope.
POST /v1/connections, POST /v1/connections/{connectionId}/reconnect and
POST /v1/connect-sessions accept an Idempotency-Key header (24 h window,
scoped per partner): a replay with the same key returns the original
response. They differ on a key replayed with a different request.
POST /v1/connections and
POST /v1/connections/{connectionId}/reconnect fingerprint the request body
and X-Client-Id and answer 422 idempotency_key_reused when either differs,
so one key can never stand for two different connections. Their replays
carry Idempotent-Replayed: true; a first-time response never has the
header. While the first request with a key is still in flight, a second
request with the same key is refused with 409 idempotency_key_in_use
rather than run twice - retry it after the first one has answered, and it
replays. POST /v1/connect-sessions does not fingerprint: it returns the
original session whatever the body says. POST /v1/clients supports upsert
semantics via externalId.
Connection lifecycle events are delivered as HTTP callbacks — see the companion Webhooks v2 reference.
Returns the banks (providers) available to this partner. sandboxOnly partners see only sandbox providers. Paginated; iterate until nextCursor is null.
| limit | integer [ 0 .. 500 ] Default: 100 Page size. Default 100 for this endpoint (raised in v1.1), max 500. |
| nextCursor | string Cursor returned by the previous page's |
| country | string Filter by ISO 3166-1 alpha-2 country code. |
| search | string Case-insensitive substring match on provider name. |
{- "limit": 100,
- "nextCursor": null,
- "data": [
- {
- "id": "ef86e35c-83f1-4b9e-bde2-cfc40b543e05",
- "name": "Komerční banka",
- "code": "kb_cz",
- "countryCode": "CZ",
- "bicCodes": [
- "KOMBCZPP"
], - "timeZone": "Europe/Prague",
- "status": "Active"
}
]
}Creates a client record for a unique end user. With externalId, the call is an upsert: if a client with the same reference exists, it is returned with HTTP 200 and no duplicate is created. Store the returned id and pass it as X-Client-Id on client-scoped endpoints.
| email required | string <email> |
| countryCode required | string ISO 3166-1 alpha-2 country code. |
| externalId | string <= 255 characters Partner's internal user identifier (field name |
{- "email": "pepa@svalovec.cz",
- "countryCode": "CZ",
- "externalId": "acme-user-8213"
}{- "id": "538efad5-0966-4ca4-86e2-0856d115cbb6",
- "email": "pepa@svalovec.cz",
- "countryCode": "CZ",
- "externalId": "acme-user-8213"
}Recovers a lost clientId mapping using the partner's own user identifier.
| externalId required | string |
{- "id": "538efad5-0966-4ca4-86e2-0856d115cbb6",
- "email": "pepa@svalovec.cz",
- "countryCode": "CZ",
- "externalId": "acme-user-8213"
}Deletes a client and purges related data per DPA/SLA. X-Client-Id must match the path parameter.
| clientId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "errorDesc": "Invalid request parameters",
- "error": {
- "code": "validation_error",
- "message": "Field 'returnUrl' is required."
}, - "requestId": "req_8f3a2c1e"
}Initializes the bank connection and returns a URL for user redirection. This is the direct integration path where the partner renders their own bank picker; for the hosted flow use POST /v1/connect-sessions. After the bank journey, the user is redirected to returnUrl with connectionId, resultCode (Ok|Error) and optional error appended. Authoritative completion signal is the webhook stream, not the redirect. Auth windows (additive): about 2 minutes to initiate bank authentication, then completion is checked ~20 minutes later (≈ 22 minutes from start). expiresAt reflects the initiate window; note that directRedirect providers return expiresAt = now, so it is not universally a "time to reach the bank".
| X-Client-Id required | string <uuid> Client ID obtained from |
| Idempotency-Key | string <= 255 characters Unique key (UUID recommended) making the request idempotent for 24 hours, scoped per partner. A replay with the same key returns the original response. |
| X-Application-Name | string Name of the partner application the end user is connecting from. Analytics metadata only — attached to the resulting connection's tracking events; omitting it has no functional effect. |
| X-Client-App-Version | string Version of the partner application. Analytics metadata only. |
| X-Client-OSVersion | string Operating-system version of the end user's device. Analytics metadata only. Note the header spelling — |
| X-Client-Platform | string Platform of the end user's device (e.g. |
| returnUrl required | string <uri> URL the user is redirected to after bank authorization, with |
| providerId required | string <uuid> Provider ID from |
| locale | string Default: "en" ISO 639-1 language code for the bank authorization UI. |
| subscribeToAllAccounts | boolean Overrides the partner-level |
| skipConsentScreen | boolean Effective only when permitted by partner configuration (compliance-gated). |
| ownershipType | string Default: "Personal" Enum: "Personal" "Shared" "Business" Parsing is case-insensitive today, and any unrecognized value silently falls back to |
{- "providerId": "ef86e35c-83f1-4b9e-bde2-cfc40b543e05",
- "locale": "en",
- "subscribeToAllAccounts": true
}{- "connectionId": "38d0322a-a01f-4ab5-811a-7014b597834a",
- "expiresAt": "2026-07-15T10:22:00Z"
}| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "id": "38d0322a-a01f-4ab5-811a-7014b597834a",
- "state": "Active"
}| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "errorDesc": "Invalid request parameters",
- "error": {
- "code": "validation_error",
- "message": "Field 'returnUrl' is required."
}, - "requestId": "req_8f3a2c1e"
}Fetches new transactions for an existing Active connection in the background. Refresh never redirects the user — if the bank requires re-authentication, the refresh fails, the connection becomes Inactive, and the recovery path is reconnect. Completion is signalled by ConnectionRefreshSuccess / ConnectionRefreshFailed webhooks (TransactionsFetching* progress events are reused; AccountsFetching* are not sent on refresh). Guards: concurrent call → refresh_in_progress; 10-minute cooldown after a successful manual refresh and per-provider daily quotas → refresh_cooldown / refresh_quota_exceeded with nextRefreshPossibleAt.
| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
| returnUrl | string <uri> Optional - refresh never redirects, so it is ignored (sending it is harmless). |
| locale | string |
{- "locale": "en"
}{- "status": "Accepted",
- "nextRefreshPossibleAt": "2026-07-15T10:20:00Z"
}Renews consent for an Inactive connection via a new bank authorization. Always redirects the user — behaves like create but keeps the same connectionId. Rejected for Disabled connections (connection_not_recoverable). For the hosted flow, create a connect session with connectionId instead of calling this endpoint: the user then gets the same hosted screens (including the account picker) as on a create.
| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
| Idempotency-Key | string <= 255 characters Unique key (UUID recommended) making the request idempotent for 24 hours, scoped per partner. A replay with the same key returns the original response. |
| returnUrl required | string <uri> Reconnect always redirects the user to the bank; a return URL is required. |
| locale | string Default: "en" |
| subscribeToAllAccounts | boolean May yield more accounts than the previous consent. With account selection enabled the accounts the user consented to before stay pre-selected and this flag has no effect — a reconnect is the only way to widen the selection. |
| skipConsentScreen | boolean Effective only when permitted by partner configuration. |
{- "locale": "en"
}{- "connectionId": "38d0322a-a01f-4ab5-811a-7014b597834a",
- "expiresAt": "2026-07-15T10:22:00Z"
}Revokes consent for the connection; the connection becomes Inactive. BudgetBakers also auto-revokes after successful data retrieval for one-shot partners (autoRevokeAfterCreate). Idempotent: revoking an already-Inactive connection succeeds with 200 and no callback (no-op). It keys off the connection status, not consent, so there is no 403 consent_inactive here.
| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "errorDesc": "Invalid connection status = 'Disabled'",
- "error": {
- "code": "connection_not_recoverable",
- "message": "Connection is Disabled and cannot be revoked."
}, - "requestId": "req_8f3a2c1e"
}Moved to /v2/connect-sessions - this /v1 path is a transitional alias of the same handler and will be removed once the SDKs retarget. Creates a session for the hosted connect flow and returns a one-time hostedUrl to open for the end user. The hosted flow renders the bank picker, consent information, bank redirect, progress and (when enabled) account selection, then redirects to returnUrl. The underlying connection is created internally once the user confirms a bank; its lifecycle (webhooks, billing) is identical to a directly created connection. Pass connectionId to reconnect an existing connection instead: the bank picker is skipped and the same screens follow, ending in the account picker. The optional client-metadata headers are stored with the session and attached to that connection's tracking events, so hosted-flow analytics match direct creation.
| X-Client-Id required | string <uuid> Client ID obtained from |
| Idempotency-Key | string <= 255 characters Unique key (UUID recommended) making the request idempotent for 24 hours, scoped per partner. A replay with the same key returns the original response. |
| X-Application-Name | string Name of the partner application the end user is connecting from. Analytics metadata only — attached to the resulting connection's tracking events; omitting it has no functional effect. |
| X-Client-App-Version | string Version of the partner application. Analytics metadata only. |
| X-Client-OSVersion | string Operating-system version of the end user's device. Analytics metadata only. Note the header spelling — |
| X-Client-Platform | string Platform of the end user's device (e.g. |
| returnUrl required | string <uri> Final destination after the hosted flow completes. Validated at session creation against the app's registered return-URL patterns (https app / universal links and custom schemes supported). The redirect appends |
| locale | string Default: "en" ISO 639-1; hosted UI language. The hosted flow ships |
| country | string ISO 3166-1 alpha-2 preselect for the bank picker. |
| providerId | string or null <uuid> When set, the bank picker is skipped and the flow starts at the consent step. |
| connectionId | string or null <uuid> Reconnect mode: when set, the session re-authorizes this existing connection instead of creating a new one, and the bank picker is skipped because the bank is implied by the connection. Mutually exclusive with |
{- "locale": "en",
- "country": "CZ"
}{- "sessionId": "cs_9c1e7ab24d",
- "expiresAt": "2026-07-15T10:35:00Z"
}Moved to /v2/connect-sessions/{sessionId} - transitional alias. For troubleshooting and server-side reconciliation. The webhook stream remains the authoritative completion signal.
| sessionId required | string |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "sessionId": "cs_9c1e7ab24d",
- "state": "Completed",
- "connectionId": "38d0322a-a01f-4ab5-811a-7014b597834a",
- "resultCode": "Ok",
- "error": null
}Accounts for the authorized connection. Not paginated; raw JSON array capped at 100 accounts per connection. (An envelope is considered for v2.)
| connectionId required | string <uuid> |
| X-Client-Id required | string <uuid> Client ID obtained from |
[- {
- "id": "5d3f1a2b-7c8e-4f90-a1b2-c3d4e5f60718",
- "name": "Current Account",
- "type": "CurrentAccount",
- "balance": 816,
- "currencyCode": "CZK",
- "iban": "CZ6508000000192000145399"
}, - {
- "id": "9e8d7c6b-5a49-4382-b1c0-d9e8f7a6b5c4",
- "name": "Savings Account",
- "type": "SavingAccount",
- "balance": 120450.5,
- "currencyCode": "CZK",
- "iban": null
}
]Transactions for an account, cursor-paginated. History depth depends on the bank provider (typically 90 days). Filter by variable symbol via the variableSymbol parameter: matching ignores leading zeros on both sides ("888" matches 888, 0888, 00888); trailing digits remain significant.
| accountId required | string <uuid> |
| limit | integer [ 0 .. 500 ] Default: 10 Maximum number of items in this page. |
| nextCursor | string Cursor returned by the previous page's |
Array of strings or numbers <= 20 items JSON array of up to 20 strings or numbers, e.g. |
| X-Client-Id required | string <uuid> Client ID obtained from |
{- "limit": 10,
- "nextCursor": "b2xkZXItcGFnZS10b2tlbg",
- "data": [
- {
- "id": "7c4e1a8b-2d9f-4e3a-b5c6-d7e8f9a0b1c2",
- "amount": -2326,
- "currencyCode": "CZK",
- "recordState": "Cleared",
- "recordDate": "2026-07-14T09:41:00Z",
- "note": "Payment card transaction",
- "counterParty": "ALBERT PRAHA",
- "enrichment": {
- "category": {
- "categoryId": 550,
- "categoryName": "food_and_drinks",
- "subcategoryId": 55001,
- "subcategoryName": "food_and_drinks__groceries"
}, - "merchant": {
- "id": "4b6a8c0e-1d3f-4a5b-9c7d-8e0f2a4b6c8d",
- "name": "Albert CZ",
}, - "recurrent": false
}, - "details": {
- "variableSymbol": null,
- "constantSymbol": null,
- "specificSymbol": null,
- "transactionCode": "PMNT-ICDT-ESCT",
- "creditorReference": null,
- "externalCategoryName": null,
- "mccCode": "5411",
- "others": null
}
}, - {
- "id": "3f5e7d9c-1b2a-4c6d-8e0f-a1b2c3d4e5f6",
- "amount": 42000,
- "currencyCode": "CZK",
- "recordState": "Cleared",
- "recordDate": "2026-07-01T06:02:00Z",
- "note": "Salary July",
- "counterParty": "ACME s.r.o.",
- "enrichment": {
- "category": {
- "categoryId": 900,
- "categoryName": "income",
- "subcategoryId": 90001,
- "subcategoryName": "income__salary"
}, - "merchant": null,
- "recurrent": true
}, - "details": {
- "variableSymbol": "888",
- "constantSymbol": "0308",
- "specificSymbol": null,
- "transactionCode": "PMNT-RCDT-ESCT",
- "creditorReference": null,
- "externalCategoryName": null,
- "mccCode": null,
- "others": null
}
}
]
}Moved to /v2/partner/config - transitional alias. Self-description of the calling partner: enabled capabilities, consent duration override, and webhook signature mode. SDKs and the hosted flow configure themselves from this. Calling a disabled capability elsewhere returns 403 capability_disabled.
{- "partnerId": "2f5a1c3e-9b7d-4e21-a6c8-0d4f5e6a7b8c",
- "name": "Acme Lending",
- "mode": "sandbox",
- "capabilities": {
- "refresh": false,
- "reconnect": false,
- "enrichment": false,
- "autoRevokeAfterCreate": true,
- "nonRegulatedProviders": false
}, - "consentDuration": "PT1H",
- "countries": null,
- "webhook": {
- "signatureVersion": "v1"
}
}