Authentication
Audience: ๐ Integration Client (session/cookie auth at the end is ๐๏ธ/UI only)
BankConnector has three principal types. As an integration client building a machine-to-machine connection, you care about exactly one: the API key.
| Principal | How | Who |
|---|---|---|
apikey | X-API-Key: key_โฆ | ๐ your integration โ this is you |
session | cookie / bearer token after login | humans in the web UI |
system-admin | separate login or X-System-Key | ๐๏ธ operator only |
Your API key
An API key is a single header:
X-API-Key: key_<64 hex characters>
Key facts:
- The key is platform-bound. It carries 256 bits of entropy (
key_+ 64 hex). - The key implies your tenant. There is no tenant header. You pass
platformIdandcompanyIdin the request body or query; the server rejects any request whose stated scope doesn't match the key's platform (403 forbidden). - There is no expiry, no TTL, and no refresh. A key is valid until revoked. Rotation is manual: create a new key, cut over, revoke the old one.
- The key is stored only as a SHA-256 digest server-side. It is shown to you once, at creation. If you lose it, you rotate โ it cannot be recovered.
โ ๏ธ Scope reality (important): an API key is pinned to a platform, and the
companyIdis free within that platform. If your company shares a platform with other companies, your key can address those other companies by passing a differentcompanyId. If you require hard isolation, you should be the only company on your own platform. Confirm your tenancy model with your operator.
How a key is issued
A workspace (platform) admin creates it in the UI or via:
POST /platforms/<platformId>/api-keys
Body: { "label": "erp-production" }
โ 201 { "id": "apk_...", "key": "key_...", "label": "...", "createdAt": "..." }
The raw key is in that response and nowhere else afterwards. Listing keys (GET /platforms/<platformId>/api-keys) returns metadata only โ id, label, createdAt, lastUsedAt. Revoking is a soft delete (kept for audit).
Note that key management is a human action (session admin, 403 for API keys). Your integration uses a key; it doesn't mint one.
Required headers for a machine client
For a normal JSON request you need only:
X-API-Key: key_โฆ
Content-Type: application/json # for JSON bodies (some routes take raw XML)
Idempotency-Key: <key> # on POST /journal/payments โ see Idempotency
You do not send cookies, CSRF tokens, or an Origin. Server-to-server callers send no browser Origin, so the origin guard passes automatically. CSRF applies only to cookie-based browser sessions.
Optional headers worth knowing
| Header | Purpose |
|---|---|
BankConnector-Version: YYYY-MM-DD | pin the API version (baseline 2026-06-01). Echoed back on every response, including errors. A malformed date is a 400. |
X-Request-ID | set by the server on every response. Log it โ support can look up any request by it. |
Idempotency-Replayed: true | response header telling you a payment was a replay, not a fresh execution. |
What an API key cannot do
API keys are for machine tasks โ payments, webhooks, user provisioning, exports. They are deliberately blocked (403) from customer-decision routes that must be performed by a human in the UI:
- Bank connection setup and activation
- Approval-policy management
They also can't call session-only identity routes (/auth/me, /me/sessions, /2fa/*) โ those return 401 for a key.
Practical consequence: a human at your company sets up and activates the bank connection once, in the web UI. After that, your API key drives day-to-day payment traffic. Plan your onboarding around that split.
Auth failures
| Situation | Status | code |
|---|---|---|
| Missing / invalid key | 401 | unauthorized |
| Key valid but wrong scope | 403 | forbidden |
| Key rejected on a session-only route | 403 | admin_required |
A 401 means re-authenticate (check the key). A 403 means you'll never get in with this request as written โ don't retry it unchanged.
Appendix โ session/cookie auth (๐๏ธ / UI only)
Human logins use POST /auth/login {subdomain,email,password}, often followed by a TOTP 2FA step, returning a bc_session cookie + a bc_csrf token. Sessions are 8 h absolute / 30 min idle. This path is for the web UI and for humans performing approvals โ not for your integration. It's documented in the API Reference if you need it.