Skip to main content
LedgerSync gives you one API for your users’ bank data. You link an account once, and we return accounts, balances, transactions, and statements as clean JSON — no matter which bank or which underlying data source is behind it. Under the hood we pull from three connectable sources and route between them for you:

Finicity

Broadest US coverage, with bank OAuth where the institution supports it.

MX

An alternate aggregator that catches banks Finicity misses.

FDE

LedgerSync’s proprietary credential-based extraction, for banks neither aggregator covers.
You never pick a source. When you initiate a connection, v3 chooses the right one server-side from our institution catalog. There is no source parameter — the id you get back (like con_FINICITY_41294 or con_MX_1224) tells you which one answered.
A fourth, read-only source: PDF. When a user’s account was set up from uploaded bank statements, its accounts and transactions come back with source: "PDF" (ids like acc_PDF_42, txn_PDF_8837). You don’t connect PDF through the widget, and it never appears under GET /v3/connections — a PDF account’s connection_id is null. Statements aren’t served for PDF accounts. Everything else (accounts, transactions, pagination) reads exactly like an aggregator source.

The data model

Everything hangs off four nested objects. Learn these once and the rest of the API reads naturally.
Reads are Client-scoped — pass client_id on every read call. For example: GET /v3/accounts?client_id=cli_...&connection_id=con_FINICITY_41294.

How linking works, in one breath

1

Create a Client

Your end-user, keyed by your own external_id.
2

Initiate a Connection

POST /v3/clients/{id}/connections with an institution_id. You get a 202 and an operation_id to poll.
3

Hand off the widget

Open the returned widget_url in the user’s browser. They pick their bank, sign in, and choose accounts. You never see their credentials.
4

Read the data

Once the connection goes active, store the canonical con_... id and read accounts, transactions, and statements.
The full walkthrough lives in Connect a bank.

Start here

Quickstart

From a sandbox key to live transaction data in a few requests.

Connect a bank

Initiate, hand off the widget, and read back accounts.

Webhooks

Get told the moment a connection goes active, fails, or refreshes.

Errors

One error envelope, one field to branch on: code.

API Reference

Every endpoint, field, and response, in full.

Authentication

Bearer keys, sandbox vs. live, and the trace header.

Everything is JSON over HTTPS

No SDK required. Send and receive JSON, authenticate with a Bearer key, and read the X-LS-Trace-Id header on every response for support. Sandbox is one key away — grab an sk_test_... key, point at https://api-sandbox.ledgersyncappv2.com/v3, and link the built-in FinBank test bank with no MFA.
Sandbox smoke test
When you’re ready to try a full link end to end, head to the Quickstart.