core data
Bank data, in the shape you were going to normalize it into anyway.
Accounts, balances, and transactions on one access token, with a cursor that survives restarts and a transaction object stable enough to store directly. Identity, liabilities, and a net-worth report sit on the same connection.
endpoints
Eight calls cover the data plane.
All POST + JSON, all bearer-authenticated, all metered the same way.
- POST
/v1/transactions/syncIncremental feed: added, modified, removed, next_cursor, has_more. The endpoint you build on. - POST
/v1/transactions/getDate-range read with count/offset paging and optional account filtering, for one-off queries. - POST
/v1/accounts/getAccounts with cached balances, plus the item they belong to. - POST
/v1/accounts/balance/getBalances, refreshed through the connector when the last sync is older than 15 minutes. - POST
/v1/identity/getAccount-holder names, emails, phones, and addresses on file at the institution. - POST
/v1/liabilities/getCard and loan terms: APR, minimum payment, next due date, original principal. - POST
/v1/assets/getA point-in-time report: total assets, total liabilities, net worth, and the breakdown behind them. - POST
/v1/items/getConnection state: connector, status, error, consented products, last successful sync.
transactions/sync
The loop you write once.
Page size is 1–500 and defaults to 100. Loop while has_more is true, then keep the final cursor.
# First call: omit the cursor to receive the item's full history as "added".curl https://connect.feels.money/v1/transactions/sync \-H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \-H "Content-Type: application/json" \-d '{"access_token": "fc_at_your_item_token","count": 500}'
added— rows you have not seen. On a first sync, that is the entire history.modified— rows you already hold that changed. The common case is a pending authorization posting, where the amount, date, and name can all move. Upsert ontransaction_id, which survives the pending → posted transition.removed— ids to delete, typically an authorization that never posted. A removal is never announced for a row you were never sent.next_cursorandhas_more— the position to persist, and whether another page is waiting right now.
the transaction object
Twelve fields, stable across every connector.
Whichever upstream served the data, the shape you store is this one.
| Field | What it is |
|---|---|
| transaction_id | Stable id, txn_…. Survives the pending → posted transition, so it is a safe primary key. |
| account_id | The owning account on the same item. |
| date | YYYY-MM-DD posted date — the authorization date while the row is still pending. |
| authorized_datetime | ISO-8601 authorization time when the institution reports one, else null. |
| name | The raw statement descriptor, unmodified. |
| merchant_name | Cleaned merchant when resolvable — the deterministic descriptor table runs on ingest, not as a separate paid call. |
| amount | Major units. Positive is money out, negative is money in. |
| iso_currency_code | ISO-4217 code for the amount. |
| pending | True until the transaction posts. |
| category / category_detailed | Primary and detailed labels from the platform taxonomy — the same strings /v1/categories/get returns. See transaction enrichment. |
| payment_channel | online, in_store, transfer, or other. |
on the same token
What else the connection carries.
No second integration, no second credential — the same access token, gated by the consent the user gave.
- Identity — names, emails, phones, and addresses on file. Items whose identity sync degraded return the empty identity shape rather than an error. Reference.
- Liabilities — APR, minimum payment, next payment due, and original principal per credit or loan account. Reference.
- Assets — total assets, total liabilities, and net worth, computed from balances with holdings standing in only where a balance cannot be trusted, so invested value is never counted twice. Reference.
- Recurring streams — subscriptions, bills, and payroll detected from the transactions the connector returned, which means they work on any connector that returns transactions at all. How detection works.
- Investments and crypto — holdings, securities, and trade history where the connector supports them. The full product surface.
What live coverage actually depends on
FeelConnect does not hold bank connections of its own. Every institution in the catalog carries an ordered chain of connectors, and live traffic goes to the first one whose credentials are present in the deployment you are calling.
Some connectors an operator can switch on alone in minutes — GoCardless Bank Account Data (UK and EU banks, free self-signup under their PSD2 licence), Coinbase, Kraken, PayPal, public-address crypto wallets, and CSV / OFX / QFX import. Others need a signed business relationship before they will serve production data, including Plaid, MX, Finicity, Akoya, and Stripe Financial Connections. Where an institution has no enabled connector, a live call returns provider_error rather than pretending.
The sandbox is the exception and it is always on: test keys resolve to the simulated network regardless of credentials, so the full integration is buildable on day one. See going live for the provider-by-provider breakdown.
in production
The parts you have to handle.
Stated plainly so they are not a surprise on launch day.
Rate limits. A token bucket per key, bursting to 3×, with X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset on every response. Exhaustion returns 429 rate_limit_error. Per-second limits and monthly quotas are per plan — see pricing.
Errors. Every non-2xx response is { error: { type, code, message, request_id } }. The request id is also on the successful path, in the dashboard’s request log, so support conversations start from the same row. Error reference.
Broken logins. Items enter login_required or error, fire an item.error webhook, and are repaired by reopening Link in update mode. Build that path before you need it.
faq
Questions developers actually ask.
keep reading
Where to go next.
- Transactions referenceCursor semantics, date-range reads, and every field.
- Open banking APIHow the connection is made in the first place.
- Financial data APIInvestments, liabilities, income, and the GraphQL gateway.
- WebhooksSignatures, the event list, and the retry schedule.
- PricingWhat counts as a request, and every plan limit.
- Institution directoryWhich institutions route where, one page each.