Search documentation
Fuzzy search across every docs page and section
Getting startedQuickstart
Fuzzy search across every docs page and section
Getting startedQuickstart
Getting started
From API keys to synced transactions: create a link token, embed Link, exchange the public token, and sync data.
This guide takes you from nothing to a connected account with synced transactions, entirely in the sandbox. Total time: about ten minutes.
Create an account, then copy the test secret key from Dashboard → API keys. Test keys start with fc_sk_test_ and route every call to the sandbox network.
The server SDK talks to /v1; the Link SDK renders the connection modal in the browser. Plain HTTPS works too — every endpoint is POST JSON.
npm install @feelconnect/node @feelconnect/link
On your server, create a short-lived link_token for the user who wants to connect an account. It expires after 30 minutes and is safe to hand to the browser.
/v1/link/token/createcurl https://api.feelconnect.dev/v1/link/token/create \-H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \-H "Content-Type: application/json" \-d '{"client_name":"My App","user":{"client_user_id":"user-123"},"products":["transactions","balances","recurring"]}'
{"link_token": "lnk_tok_eyJhbGciOiJIUzI1NiJ9.eyJzaWQiOiJsbmtfMmY4...","expiration": "2026-07-28T12:30:00.000Z"}
In the browser, open the Link modal with the token. The user searches for their institution, authenticates, picks accounts, and grants consent. On success you receive a public_token.
"use client";import { useFeelConnectLink } from "@feelconnect/link";export function ConnectButton({ linkToken }: { linkToken: string }) {const { open, ready } = useFeelConnectLink({linkToken,onSuccess: (publicToken, metadata) => {// POST publicToken to your server for exchangefetch("/api/connections/exchange", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({ public_token: publicToken }),});console.log("connected:", metadata.institution?.name);},onExit: (error) => {if (error) console.warn(error.code, error.message);},});return (<button onClick={open} disabled={!ready}>Connect a bank account</button>);}
Send the public_token to your server and exchange it once for a persistent access_token plus an item_id. Store the access token encrypted — it is the credential for everything that follows and is shown only once.
/v1/link/token/exchangecurl https://api.feelconnect.dev/v1/link/token/exchange \-H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \-H "Content-Type: application/json" \-d '{"public_token":"public-sandbox-4f1c…"}'
{"access_token": "fc_at_hK8mQ2xP7cW1nR4tYb8sJd3fV6zL0aGe","item_id": "item_7dJ3nWqZ5xC9vK1mTf4g"}
Pull transactions with cursor pagination: call /transactions/sync in a loop, persisting next_cursor after each page, until has_more is false. Later, re-sync from your stored cursor whenever you receive a transactions.sync_updates_available webhook.
/v1/transactions/synccurl https://api.feelconnect.dev/v1/transactions/sync \-H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \-H "Content-Type: application/json" \-d '{"access_token":"fc_at_…","count":500}'
{"added": [{"transaction_id": "txn_3fW8kQxT1mB6nY2cRj9z","account_id": "acct_9hK2mQxP7cW1nR4tYb8s","date": "2026-07-24","authorized_datetime": "2026-07-24T18:12:09.000Z","name": "GREENMART #204 SEATTLE WA","merchant_name": "GreenMart","amount": 84.31,"iso_currency_code": "USD","pending": false,"category": "Groceries","category_detailed": "Supermarket","payment_channel": "in_store"}],"modified": [],"removed": [],"next_cursor": "eyJ2IjoxLCJvIjo1MDB9","has_more": false}