Skip to main content
Bank consent has to happen on a hosted page (CDR). The API mints a link session and you send the user to its url; they sign in to Redbark with the same account the key belongs to, finish the bank’s consent, and land on your return_url with ?link_session=completed (or failed&reason=…).
provider is fiskil (Australia), akahu (New Zealand), plaid (United States) or snaptrade (brokerages). institution is optional. When set, it must be an id from GET /v2/institutions for the same provider. An institution that is not accepting new connections is left out of that list, and creating a session for it fails with 400 parameter_invalid. Plaid does not take an institution: the user picks the bank in Plaid Link. Poll GET /v2/link_sessions/{id} until status is completed (then connection is set) or subscribe to connection.created. Sessions expire after 30 minutes. Creating one fails with 403 subscription_required when the account has no active trial or subscription (for every caller, reauthorization included), 403 connection_limit when the plan has no free connection slot (a reauthorization is exempt), and 403 professional_required for snaptrade on a plan without brokerage. Scope connections:write.

Connection lifecycle

GET /v2/institutions lists the banks and brokerages you can connect (scope connections:read). It covers Fiskil (Australia), Akahu (New Zealand), Plaid (United States) and SnapTrade (brokerages). Without popular=true, results are sorted by name. Results are paginated like other lists.
country is AU for Fiskil, NZ for Akahu, US for Plaid and null for SnapTrade. popular_rank is the position in that provider’s popular list, with 1 first, and null when the institution is not popular. available and status answer different questions and can disagree. available is whether we offer the bank for linking at all; status is what the provider reports about it right now (ONLINE, OUTAGE, or null when unknown). available: true with status: "OUTAGE" is the normal way a supported bank looks during an outage: the link session will be created, but the consent may not complete until the bank is back. Akahu, Plaid and SnapTrade report no status, so their institutions are always available: true with status: null. Plaid has no downloadable directory, so its institutions are search only. provider=plaid or country=US without a q of at least 2 characters returns an empty list. A Plaid reauthorization reopens Plaid Link in update mode on the same Item. If a provider’s directory cannot be loaded, that provider contributes no rows and the request still succeeds. OAuth destinations go through a destination link: POST /v2/destination_links { type, return_url } → send the user to url. On completion a draft destination exists (status: incomplete, destination set on the link). Then:
  1. GET /v2/destinations/{id}/resources?type=spreadsheet (or sheet&parent=<spreadsheet id>, database, base, table&parent=app…, budget, account&parent=…, category&parent=…) to see what the grant can reach. A child type with no parent falls back to the destination’s current target, so type=sheet alone lists the tabs of the spreadsheet the destination already points at.
  2. POST /v2/destinations/{id} { "target": { "spreadsheet_id": "1AbC…", "sheet_id": 0 } } to aim it. The destination becomes active.
Targets by type: Sheets spreadsheet_id (+ sheet_id, names), Notion database_id, Airtable base_id + table_id, YNAB budget_id, Webhook url.

Webhook destinations

Created directly: POST /v2/destinations { "type": "webhook", "name": "My endpoint", "target": { "url": "https://example.com/redbark" } }. The signing secret (config.signing_secret) is returned on create and POST /v2/destinations/{id}/rotate_secret only; store it then. Payloads and headers are documented under Webhooks.

The destination object

status: active, incomplete (no target yet), reauth_required (the grant failed on a sync; use a new destination link or the dashboard), disabled (auto-disabled webhook; POST …/enable). Deleting a destination also deletes syncs that only wrote to it; 409 destination_in_use while a run is writing.