Refresh a connection
Force a re-pull of accounts and recent transactions for this Connection. Banks usually post new transactions once a day so we already refresh active connections automatically — call this only when you have a specific reason to need fresher data (user just clicked a “refresh” button, you’re reconciling something time-sensitive).
Source-specific behavior
On-demand refresh is not uniformly available across sources.
The HTTP outcome depends on the connection’s source:
- Finicity (
con_FINICITY_*) — returns202 Acceptedwith anoperation_id. The backend queues the refresh asynchronously; on success theaccount.refresh.completedwebhook fires when the bank call finishes, and on terminal failure theaccount.refresh.failedwebhook fires instead. Refreshes only the accounts already linked on this connection: it updates balances and transactions on rows we already hold and never adds an account. An account the end-user opened, or chose not to share, after the original link is not picked up here no matter how often you call it. UsePOST /connections/{connection_id}/reauthorizefor that. - MX (
con_MX_*) — returns202 Acceptedwith anoperation_id. MX has no synchronous refresh API, so the backend triggers a member aggregation and returns immediately; MX pulls fresh balances and transactions asynchronously, and theaccount.refresh.completedwebhook fires when it finishes (account.refresh.failedon terminal failure). The aggregation re-reads the member’s whole account list, so an account added at the bank since link time is created here without any end-user step. The same happens on the scheduled passes, so on MX you can simply wait. - FDE (
con_FDE_*) — returns202 Acceptedwith anoperation_id. FDE re-runs its document extraction pipeline; on success theaccount.refresh.completedwebhook fires on completion, and on terminal failure theaccount.refresh.failedwebhook fires instead. The run re-reads the portal’s sub-accounts, so a sub-account that has appeared since link time is created here too.
Accounts opened after linking
Only Finicity is closed: refresh there is update-only. MX and FDE
discover new accounts on a refresh, and on MX the scheduled
passes do the same without you calling anything. Either way
nothing pushes you a notification, because there is no
account.added webhook. After a refresh completes,
re-list GET /v3/accounts?client_id=…&connection_id=… and diff
on account id. Account.created_at carries when LedgerSync first
saw the account, which is the field to sort by.
Refresh support by source
All three connectable sources — Finicity, MX, and FDE —
support on-demand refresh and answer 202 Accepted with an
operation_id; the outcome always arrives asynchronously on
the account.refresh.completed / account.refresh.failed
webhook, never in the 202 body. Uploaded-statement (PDF)
data is read-only, has no connection, and is never refreshed.
Empty-body POST
This endpoint takes no request body. Send an explicit
Content-Length: 0 header — Google’s HTTPS load balancer
in front of the API rejects body-less POSTs without one
with 411 Length Required. Most HTTP clients add this
automatically; some (raw fetch, certain SDKs in
keep-alive mode) do not.
Authorizations
Pass your secret key in the Authorization header as a Bearer
token: Authorization: Bearer sk_test_... (sandbox) or
Bearer sk_live_... (production).
Keys are created in the developer portal and the plaintext secret is shown exactly once at creation. Treat them like passwords — never embed them in mobile apps or front-end code.
Headers
Safe-retry key for POSTs. Send any unique string per logical
request (a UUIDv4 is great). If the network drops and you retry
with the same Idempotency-Key within 24 hours, you get the
exact same response back instead of creating a duplicate.
Cached responses include failures (4xx and 5xx) too. If a call failed because of a bad input and you want to try again with the corrected input, use a fresh key — otherwise you'll keep getting the cached failure.
255"6f1a8c50-3e9c-4d4a-b1f5-2c5b9a2f7d11"
Path Parameters
Canonical Connection id (con_<SOURCE>_<bankAccountId>). The
placeholder UUID returned during initiate is rejected here with
400 — only active connections can be refreshed.
"con_FINICITY_41294"
Body
No body. Send Content-Length: 0 so the upstream load
balancer doesn't reject the request with 411.
The body is of type object | null.
Response
The request was accepted but the underlying work runs
asynchronously. Use the returned operation_id to poll
GET /operations/{operation_id} or just wait for the matching
webhook event.
Returned with 202 Accepted for async operations.
"op_01HXYZ8A6N7K2W9PQ4T5Z3V6E0"
queued "https://api-sandbox.ledgersyncappv2.com/v3/operations/op_01HXYZ8A6N7K2W9PQ4T5Z3V6E0"
Rough ETA for completion. Best-effort.
