Banking
25 operations. All areas
- POST /v1/bank-accounts
- GET /v1/bank-accounts
- POST /v1/bank-accounts/{id}/update
- GET /v1/bank-accounts/{id}
- POST /v1/bank-accounts/{id}/imports
- POST /v1/bank-accounts/{id}/auto-match
- GET /v1/bank-lines
- POST /v1/bank-lines/{id}/categorize
- POST /v1/bank-lines/{id}/match
- POST /v1/bank-lines/{id}/unmatch
- POST /v1/bank-lines/{id}/exclude
- POST /v1/bank-lines/{id}/restore
- POST /v1/bank-rules
- GET /v1/bank-rules
- POST /v1/bank-rules/{id}/deactivate
- GET /v1/bank-feeds
- POST /v1/bank-feeds
- GET /v1/bank-feeds/{id}
- POST /v1/bank-feeds/link-token
- POST /v1/bank-feeds/{id}/accounts/link
- POST /v1/bank-feeds/{id}/accounts/unlink
- POST /v1/bank-feeds/{id}/sync
- POST /v1/bank-feeds/{id}/reconnected
- POST /v1/bank-feeds/{id}/settings
- POST /v1/bank-feeds/{id}/disconnect
POST/v1/bank-accounts
Register a bank or card account, linked to its ledger account
- Operation
createBankAccount - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Request body
namestring, requiredkind"checking" | "savings" | "credit_card" | "other", requiredledger_accountstring, requiredinstitutionstringmaskstringcsv_profileCsvProfile
- Responses
201Created (object)- Errors
400,401,403,409,422,429,500(Error:error.type,message)
GET/v1/bank-accounts
Bank accounts with ledger balance, line counts by state and reconciliation status
- Operation
listBankAccounts - Scope: read
- Read
- Responses
200Bank accounts (object)- Errors
400,401,403,429,500(Error:error.type,message)
POST/v1/bank-accounts/{id}/update
Correct a bank or card account's name, institution or last digits (null clears institution or mask). The ledger account and kind never change. Audited.
- Operation
updateBankAccount - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
namestringinstitutionstring | nullmaskstring | null
- Responses
200Updated (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
GET/v1/bank-accounts/{id}
One bank account with its import history
- Operation
getBankAccount - Scope: read
- Read
- Parameters
idpath, string, required
- Responses
200Bank account (object)- Errors
400,401,403,404,429,500(Error:error.type,message)
POST/v1/bank-accounts/{id}/imports
Import an OFX/QFX or CSV statement. Lines dedupe on FITID or a content hash, so re-importing is a no-op. dry_run previews.
- Operation
importBankStatement - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
format"ofx" | "qfx" | "csv", requiredcontentstring, required The file's text.filenamestringcsv_profileCsvProfiledry_runboolean
- Responses
200Dry run: parsed lines and which are duplicates; nothing written (object)201Imported (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-accounts/{id}/auto-match
Match unmatched lines to existing entries (same amount, date within the window) and pair transfers between own accounts. Ambiguous cases are left for a human.
- Operation
autoMatchBankLines - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
window_daysintegertransfersbooleandry_runboolean
- Responses
200Result (also for dry runs) (AutoMatchResult)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
GET/v1/bank-lines
Bank lines with their state; unmatched lines carry the first matching rule's suggestion
- Operation
listBankLines - Scope: read
- Read
- Parameters
bank_account_idquery, stringstatusquery, "unmatched" | "proposed" | "matched" | "categorized" | "excluded"fromquery, stringtoquery, stringlimitquery, integer
- Responses
200Bank lines (object)- Errors
400,401,403,429,500(Error:error.type,message)
POST/v1/bank-lines/{id}/categorize
Categorize an unmatched line into an account. Same governance as propose: agents auto-post within policy, otherwise it queues for approval; humans post. dry_run previews.
- Operation
categorizeBankLine - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
accountstring, requiredclassstring Class name (reporting dimension).memostringconfidencenumberrule_idstringdry_runbooleansoft_lock_override_reasonstring
- Responses
200Dry run (ProposeResult)201Posted and linked (ProposeResult)202Queued for approval; the line is 'proposed' until decided (ProposeResult)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-lines/{id}/match
Match an unmatched line to an existing posted entry that moves the bank's ledger account by exactly the line amount
- Operation
matchBankLine - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
entry_idstring, required
- Responses
200Matched (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-lines/{id}/unmatch
Undo a match (or release a line whose entry was reversed). Refused once the entry is cleared in a finished reconciliation.
- Operation
unmatchBankLine - Scope: approve
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
reasonstring, required
- Responses
200Unmatched (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-lines/{id}/exclude
Exclude an unmatched line (not a business transaction, e.g. a duplicate the bank sent)
- Operation
excludeBankLine - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
reasonstring, required
- Responses
200Excluded (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-lines/{id}/restore
Restore an excluded line to unmatched
- Operation
restoreBankLine - Scope: propose
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
Empty object
{}.- Responses
200Restored (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-rules
Create a categorization rule (payee contains / amount range → account, by priority). Rules never post: the rules-engine agent applies them through categorize.
- Operation
createBankRule - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Request body
namestring, requiredpriorityinteger, requiredbank_account_idstringpayee_containsstringdirection"in" | "out" | "any"amount_min_centsinteger Integer cents (100 = $1.00). Never a float.amount_max_centsinteger Integer cents (100 = $1.00). Never a float.accountstring, requiredclassstring Class name (reporting dimension).memostring
- Responses
201Created (object)- Errors
400,401,403,409,422,429,500(Error:error.type,message)
GET/v1/bank-rules
Rules in evaluation order (priority, then age)
- Operation
listBankRules - Scope: read
- Read
- Parameters
include_inactivequery, boolean
- Responses
200Rules (object)- Errors
400,401,403,429,500(Error:error.type,message)
POST/v1/bank-rules/{id}/deactivate
Deactivate a rule (rules are never edited or deleted)
- Operation
deactivateBankRule - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
reasonstring, required
- Responses
200Deactivated (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
GET/v1/bank-feeds
Bank feeds (Plaid connections) with their accounts, status and last sync, plus whether feeds are configured on this deployment and the plan's limit on feed-connected bank accounts
- Operation
listBankFeeds - Scope: read
- Read
- Responses
200Feeds (object)- Errors
400,401,403,429,500(Error:error.type,message)
POST/v1/bank-feeds
Finish connecting a bank: exchange Plaid Link's public_token, store the access token sealed, list the bank's accounts. Nothing is imported until an account is linked to a bank account. People only: agents are refused (insufficient_scope).
- Operation
connectBankFeed - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Request body
public_tokenstring, required
- Responses
201Connected (object)- Errors
400,401,403,409,422,429,500,502(Error:error.type,message)
GET/v1/bank-feeds/{id}
One bank feed with its accounts and health
- Operation
getBankFeed - Scope: read
- Read
- Parameters
idpath, string, required
- Responses
200Feed (object)- Errors
400,401,403,404,429,500(Error:error.type,message)
POST/v1/bank-feeds/link-token
A short-lived Plaid Link token to connect a bank in the browser, or (with bank_feed_id) to reconnect one in update mode. People only: agents are refused (insufficient_scope).
- Operation
createBankFeedLinkToken - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Request body
bank_feed_idstring Reconnect this feed (Link update mode)account_selectionboolean Update mode: let the person add or remove accounts
- Responses
201Link token (shown once; null on an idempotent replay) (object)- Errors
400,401,403,409,422,429,500,502(Error:error.type,message)
POST/v1/bank-feeds/{id}/accounts/link
Feed one account at the bank into an existing bank account, or into a new bank account on a ledger account. Counts against the plan (Solo 3, Business 15, Advanced unlimited feed-connected bank accounts). Lines dated before import_from are not imported (default: the day after the last line imported from a file, else 24 months back); overlap with file imports is deduped. The next sync replays the history for it. People only: agents are refused (insufficient_scope).
- Operation
linkBankFeedAccount - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
accountstring, required The bank-feed account (BankFeedAccount.id)bank_account_idstring An existing Evenbead bank accountnew_bank_accountobjectimport_fromstring Calendar date, YYYY-MM-DD.
- Responses
200Linked (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-feeds/{id}/accounts/unlink
Stop feeding a bank account from this connection (its lines stay; file import still works). People only: agents are refused (insufficient_scope).
- Operation
unlinkBankFeedAccount - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
accountstring, requiredreasonstring, required
- Responses
200Unlinked (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-feeds/{id}/sync
Pull new, changed and removed transactions now (Plaid /transactions/sync from the stored cursor) and import posted ones as bank lines. Agents may call it. A replay just syncs again (nothing new: nothing changes).
- Operation
syncBankFeed - Scope: propose
- Write: sets a value, no Idempotency-Key needed
- Parameters
idpath, string, required
- Request body
Empty object
{}.- Responses
200Sync result (login_required / error: reconnect or try later; the feed's status says which) (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-feeds/{id}/reconnected
After Link update mode succeeded: refresh the connection's health and accounts at Plaid and ask for a sync. People only: agents are refused (insufficient_scope).
- Operation
reconnectedBankFeed - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
Empty object
{}.- Responses
200Refreshed (object)- Errors
400,401,403,404,409,422,429,500,502(Error:error.type,message)
POST/v1/bank-feeds/{id}/settings
Feed settings: include_pending imports pending transactions too (default off: posted only; a posted transaction then replaces its pending line). Changing it replays the history. People only: agents are refused (insufficient_scope).
- Operation
updateBankFeedSettings - Scope: admin
- Write: sets a value, no Idempotency-Key needed
- Parameters
idpath, string, required
- Request body
include_pendingboolean, required
- Responses
200Updated (object)- Errors
400,401,403,404,409,422,429,500(Error:error.type,message)
POST/v1/bank-feeds/{id}/disconnect
Disconnect a bank: the connection is removed at Plaid (/item/remove) and its access token wiped here; linked bank accounts go back to file import; imported lines stay. Final. People only: agents are refused (insufficient_scope).
- Operation
disconnectBankFeed - Scope: admin
- Write: needs Idempotency-Key (or dry_run)
- Parameters
idpath, string, required
- Request body
reasonstring, required
- Responses
200Disconnected (object)- Errors
400,401,403,404,409,422,429,500,502(Error:error.type,message)