Fintech apps rarely start from scratch anymore. When you connect a user's checking account, Plaid often sits in the middle—translating bank logins into usable JSON for your backend. The Plaid API powers account linking, balance checks, transaction history, and identity verification for thousands of apps like Venmo, Robinhood, and Chime.
This guide covers the Plaid API from a developer's perspective: obtaining keys, understanding the Link token flow, key product endpoints, error handling, and step-by-step API testing using Apidog. For reference, keep the official Plaid documentation open as you work.
If you’re still evaluating providers, check our best open banking APIs rundown. For this post, we’ll assume you’ve chosen Plaid and are ready to implement.
TL;DR
- Plaid connects your app to over 12,000 banks (US, Canada, Europe).
- Environments: Sandbox (fake data, free), Development (100 live Items, free), Production (pay per call).
-
Linking flow: 1) Create
link_token(server), 2) Open Plaid Link (client), 3) Exchangepublic_tokenforaccess_token(server), 4) Call product endpoints. - Core products: Auth, Balance, Transactions, Identity, Investments, Liabilities, Income (enabled per Item).
-
Common errors:
ITEM_LOGIN_REQUIRED,INVALID_CREDENTIALS. Webhooks notify you when an Item needs attention. - Rate limits: Per-Item and per-client. Batch reads and use webhooks instead of polling.
What is Plaid?
Plaid is a US-based fintech infrastructure provider that acts as an intermediary between your app and a user’s bank. When users enter their credentials into Plaid Link, Plaid connects to the bank (via open banking APIs or reverse-engineered flows), normalizes the data, and returns a consistent JSON response regardless of the bank.
-
Security: You never see or store bank credentials. Plaid maintains the connection (an Item) and gives you an
access_tokento query it. - Scope: One Item = one set of credentials at one institution (may include multiple accounts).
- Coverage: Checking/savings, credit cards, loans, investment, payroll data.
- ACH: Plaid does not move money; pair Plaid Auth with a payments processor for ACH. See our best ACH payments APIs guide.
Authentication and Setup
Step 1: Create a Plaid Developer Account
- Sign up at plaid.com and verify your email.
- Access the Plaid Dashboard with three environments:
-
Sandbox: Fake banks and users, free. Use
user_good/pass_goodto log in. - Development: Real banks, 100 live Items, free.
- Production: Real banks, unlimited Items, metered billing.
-
Sandbox: Fake banks and users, free. Use
Step 2: Get Your Keys
- Go to Team Settings > Keys in the Dashboard.
- Note:
-
client_id: Same for all environments. -
secret: Unique per environment.
-
- Store these in environment variables—do not commit to git.
Step 3: Install the SDK
Official Node.js SDK: github.com/plaid/plaid-node
npm install plaid
Step 4: Initialize the Client
import { Configuration, PlaidApi, PlaidEnvironments } from 'plaid';
const config = new Configuration({
basePath: PlaidEnvironments.sandbox,
baseOptions: {
headers: {
'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
'PLAID-SECRET': process.env.PLAID_SECRET,
},
},
});
const client = new PlaidApi(config);
Switch PlaidEnvironments.sandbox to .development or .production as needed.
Core Endpoints
The Link Token Flow
Every Plaid integration follows these steps:
Step 1: Create a link_token (Server-side)
const response = await client.linkTokenCreate({
user: { client_user_id: 'user_123' },
client_name: 'Your App',
products: ['auth', 'transactions'],
country_codes: ['US'],
language: 'en',
});
const linkToken = response.data.link_token;
Curl example:
curl -X POST https://sandbox.plaid.com/link/token/create \
-H 'Content-Type: application/json' \
-d '{
"client_id": "YOUR_CLIENT_ID",
"secret": "YOUR_SANDBOX_SECRET",
"user": { "client_user_id": "user_123" },
"client_name": "Your App",
"products": ["auth", "transactions"],
"country_codes": ["US"],
"language": "en"
}'
Step 2: Open Plaid Link (Client-side)
- Send
link_tokento your frontend. - Pass it to the Plaid Link SDK.
- User selects bank and authenticates. Plaid returns a
public_tokento your onSuccess callback.
Step 3: Exchange the public_token (Server-side)
const exchange = await client.itemPublicTokenExchange({
public_token: publicToken,
});
const accessToken = exchange.data.access_token;
const itemId = exchange.data.item_id;
Store accessToken securely for all future API calls.
Step 4: Call Product Endpoints
const accounts = await client.accountsGet({ access_token: accessToken });
const balance = await client.accountsBalanceGet({ access_token: accessToken });
Product Endpoints You Should Know
-
Auth: Account/routing numbers for ACH (
/auth/get) -
Balance: Real-time balances (
/accounts/balance/get) -
Transactions: Up to 24 months of cleaned transaction data (
/transactions/sync) -
Identity: Account holder info (
/identity/get). For pure KYC, see our best KYC API roundup. -
Investments: Holdings and investment transactions (
/investments/holdings/get) -
Liabilities: Student loan, credit card, mortgage details (
/liabilities/get) -
Income: Payroll data (
/credit/payroll_income/get)
Testing the Plaid API with Apidog
Testing Plaid end-to-end can be tricky due to browser-based Link. To reliably test server endpoints, payloads, and error handling, use Apidog:
- Import Plaid’s OpenAPI spec into Apidog for pre-configured endpoints, example bodies, and auth headers.
- Create environment variable sets (
client_id,secret,access_token) for sandbox/production and switch easily. - Use chained requests to test the full flow:
linkTokenCreate→sandboxPublicTokenCreate→itemPublicTokenExchange→accountsGet—all without a browser. - Apidog’s mock server helps frontend teams get
/accounts/getresponses before backend integration is complete. - Migrating from another tool? Our guide to API testing without Postman in 2026 covers the transition.
- Download Apidog and connect it to Plaid’s spec to get started.
Common Errors and Rate Limits
Plaid error responses include error_type, error_code, and a human-readable error_message. Key errors:
-
INVALID_CREDENTIALS: User typed the wrong password. Prompt for re-auth via Link update mode. -
ITEM_LOGIN_REQUIRED: Bank session invalidated (e.g., password change). Trigger Link in update mode; listen for webhook. -
RATE_LIMIT_EXCEEDED: Per-Item or per-endpoint limit hit. Back off, retry with jitter. -
PRODUCT_NOT_READY: Data not ready (e.g., transactions still syncing). Retry afterINITIAL_UPDATEwebhook.
Webhooks
- Pass a
webhookURL when creating thelink_token. - Plaid will POST updates to this URL.
- Critical events:
-
SYNC_UPDATES_AVAILABLE(new transactions), -
ITEM: LOGIN_REQUIRED(re-auth required), -
ITEM: ERROR(permanent failure).
-
- Always verify JWT signature on webhooks before acting.
Rate Limits
- Plaid enforces per-Item, per-endpoint rate limits (e.g.,
/accounts/balance/get≈ 5 calls/min/Item in production). - Aggregate client-level limits on heavy endpoints.
- Best practice: poll webhooks, cache balances for a few minutes, and never call Plaid directly from a user-facing request.
Plaid Pricing
- Sandbox: Free, unlimited.
- Development: Free, up to 100 Items.
-
Production:
- Auth: ~$1.50 per linked account (one-time)
- Balance: Per-call
- Transactions: Monthly per-Item fee (~$0.30)
- Identity: Per-call
- Investments/Liabilities/Income: Separate per-Item fees
For high volumes, custom pricing applies. See the Plaid products page for up-to-date details.
FAQ
How long does an access_token last?
Indefinitely, unless the user revokes access or the bank invalidates the session. Store encrypted; do not expire on your side.
Can I use Plaid for identity verification only?
Plaid Identity is available, but for strict KYC needs, dedicated products may be preferable. See our Stripe Identity API guide.
Does Plaid support non-US countries?
Yes—US, Canada, UK, much of the EU. Coverage varies by product. Use correct country_codes when creating the link_token.
What if a user changes their bank password?
The Item moves to ITEM_LOGIN_REQUIRED. You’ll get a webhook; trigger Link in update mode to re-authenticate (user keeps the same access_token).
Can I test the Link flow without a browser?
Yes. Use /sandbox/public_token/create to get a public_token for automated integration tests.
How do I handle Plaid in local development?
Keep your sandbox secret in .env, use PlaidEnvironments.sandbox, and tunnel (e.g., ngrok) to receive webhooks locally.
Top comments (0)