Skip to content

teller

Use when working with Teller.io banking API — enrollments, accounts, transactions, balances, webhooks, mTLS authentication, or bank data integration. Also use when building fintech features that connect to real bank accounts.

ModelSource
sonnetpack: banking
Full Reference

┏━ 🔧 teller ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Teller.io banking API — accounts, transactions ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Real-time bank data via Teller.io — mTLS + HTTP Basic auth, no SDK, all raw fetch.

ItemValue
API basehttps://api.teller.io
AuthmTLS (cert + key) + HTTP Basic (token as username, empty password)
API version2020-10-12Teller-Version header; 72h rollback window
Environmentssandbox (no mTLS), development (mTLS required), production (mTLS required)
Sandbox credsusername=username / password=password
Dev enrollment limit100 total, non-restorable when deleted
mTLS libraryundici-tls-dispatcher — Node.js native fetch uses undici, not http
DocWhat’s inside
reference/accounts.mdList accounts, get account details, balances, account types, delete enrollment
reference/transactions.mdList transactions, pagination, date ranges, 28 categories, sync algorithm
reference/identity.mdIdentity API — owner info, GET /accounts/:id/identity
reference/payments.mdZelle payments (BETA), payee management
reference/connect.mdTeller Connect widget, teller-connect-react, Ed25519 signature verification, reconnect
reference/webhooks.md4 event types, HMAC-SHA256 verification, retry behavior

Build auth header:

const authHeader = `Basic ${Buffer.from(accessToken + ":").toString("base64")}`;

mTLS setup (dev/production only):

import UndiciTLSDispatcher from "undici-tls-dispatcher";
const cert = Buffer.from(process.env.TELLER_CERTIFICATE!, "base64").toString("utf8");
const key = Buffer.from(process.env.TELLER_PRIVATE_KEY!, "base64").toString("utf8");
const dispatcher = new UndiciTLSDispatcher({
tlsConfig: [{ url: "https://api.teller.io", tls: { cert, key } }],
});
// Pass as fetch option: { dispatcher }

Encrypt token before DB storage (AES-256-GCM):

// Format: Base64(Salt[16] || IV[12] || AuthTag[16] || Ciphertext)
// Key derivation: PBKDF2-SHA256, 100,000 iterations from ENCRYPTION_KEY env var

Strip token from responses — never return to client:

const { accessToken: _, ...safeEnrollment } = enrollment;
return safeEnrollment;
// WRONG — NaN or string concat
const total = txn.amount + otherAmount;
// CORRECT — always parseFloat first
const amount = parseFloat(txn.amount); // negative=debit, positive=credit
const abs = Math.abs(parseFloat(txn.amount));
MistakeFix
Using txn.amount directly in mathAlways parseFloat(txn.amount) first
Using https.Agent for mTLSNode.js fetch uses undici — use undici-tls-dispatcher
Storing raw access token in DBEncrypt with AES-256-GCM before storing
Returning access token to clientStrip it from all API responses
Deleting dev enrollment during testingBurns from 100-slot hard limit permanently
No replay protection on webhooksReject events with timestamp > 3 minutes old
Forgetting mTLS in dev/prodSandbox skips mTLS; dev and production require cert + key
Syncing without date overlapMiss pending→posted transitions — overlap 7+ days