curl --request GET \
--url https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "acc_FINICITY_45",
"source": "FINICITY",
"type": "credit_card",
"iso_currency_code": "USD",
"connection_id": "con_FINICITY_41294",
"client_id": "<string>",
"name": "<string>",
"subtype": "money_market",
"mask": "1234",
"current_balance": -1234.56,
"available_balance": 123,
"last_refreshed_at": "2023-11-07T05:31:56Z",
"oldest_transaction_date": "2023-04-11",
"liabilities": {
"credit_limit": 65000,
"available_credit": 50596.54,
"statement_balance": -14381.66,
"minimum_payment": 143,
"payment_due_date": "2026-09-24"
},
"realized_capabilities": {
"transactions": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"balance": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"available_balance": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"statements": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"check_images": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}{
"error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}Get an account
Look up a single Account by id. Returns name, type, current balance, mask (last 4 of the account number), and the Connection it came from.
curl --request GET \
--url https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.ledgersyncappv2.com/v3/accounts/{account_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "acc_FINICITY_45",
"source": "FINICITY",
"type": "credit_card",
"iso_currency_code": "USD",
"connection_id": "con_FINICITY_41294",
"client_id": "<string>",
"name": "<string>",
"subtype": "money_market",
"mask": "1234",
"current_balance": -1234.56,
"available_balance": 123,
"last_refreshed_at": "2023-11-07T05:31:56Z",
"oldest_transaction_date": "2023-04-11",
"liabilities": {
"credit_limit": 65000,
"available_credit": 50596.54,
"statement_balance": -14381.66,
"minimum_payment": 143,
"payment_due_date": "2026-09-24"
},
"realized_capabilities": {
"transactions": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"balance": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"available_balance": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"statements": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
},
"check_images": {
"status": "succeeded",
"last_success_at": "2023-11-07T05:31:56Z",
"next_refresh_after": "2023-11-07T05:31:56Z",
"last_error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}{
"error": {
"code": "unknown_api_key",
"message": "The API key you presented doesn't match any active key.",
"type": "auth_error",
"doc_url": "https://portal.ledgersyncappv2.com/errors/unknown_api_key",
"category": "AUTH_ERROR",
"is_user_actionable": true,
"source_diagnostic_code": "FIN-103",
"param": "client.email",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"errors": [
{
"param": "client.email",
"message": "must be a valid email address",
"code": "invalid_email"
}
]
}
}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.
Path Parameters
Query Parameters
The Client (cli_…) to scope the read to. Required on account,
transaction, and statement reads — LedgerSync's backend data APIs
are scoped per end-user, so these resources are resolved within a
single Client.
Response
The Account.
"acc_FINICITY_45"
Financial-data source backing an account. Aggregator sources
(FINICITY, MX) and FDE back a Connection; PDF does not.
Values:
FINICITY— Finicity aggregationMX— MX aggregationFDE— Financial Document Extraction (LedgerSync proprietary)PDF— Uploaded bank statements. Read-only: exposed on/accountsand/transactions(statements are not served for PDF), and never as a Connection (PDF accounts haveconnection_id: null).
FINICITY, MX, FDE, PDF Coarse account classification, normalized by LedgerSync so the same six values mean the same thing on every source. Always present. other means the source did not classify the account, or classified it as something with no home in this enum (a rewards balance, an MX "other liability") - read subtype to tell those apart. This list is closed and stable; new upstream products appear in subtype, never here.
checking, savings, credit_card, loan, investment, other "credit_card"
ISO-4217 currency code. Defaults to USD when the source omits it.
"USD"
Owning connection — canonical id (con_<SOURCE>_<bankAccountId>). Null on a sandbox single-fetch (a sandbox account id doesn't encode its connection). Always present when listing accounts by connection.
"con_FINICITY_41294"
The finer label the source reported, before it was collapsed into type. Always present. This is an OPEN vocabulary that grows as sources report new products, which is why it is a plain string and not an enum: a new value here is never a breaking change. Branch on type; use subtype for display, or for finer routing you control and can update. unknown when the source reported no type at all, which today is every FDE account and roughly half of the accounts created from uploaded statements. Examples of the collapse: money_market and certificate_of_deposit report type: savings; mortgage and line_of_credit report type: loan; ira, roth and plan_401k report type: investment; bank reports type: checking.
^[a-z0-9_]+$"money_market"
Last 4 digits of the account number (Plaid-style mask).
"1234"
Most recent balance in the account's currency, as a decimal, signed from the account holder's point of view and normalized by LedgerSync so it means the same thing on every source. Positive is value you hold, negative is value you owe, so summing this across a client's accounts gives net worth. A credit card or loan carrying a balance is therefore negative, and a checking account in overdraft is negative too. The sign is meaningful in both directions: an overpaid card with a real credit balance is positive. Null when the source hasn't reported one yet. The account.refresh.completed webhook reports the same account with the same sign, wrapped as {amount, iso_currency_code} rather than a bare decimal.
-1234.56
Available balance, when the source distinguishes it from the current balance. On a credit card this is available credit, an amount you can spend, so it is NOT sign-flipped the way current_balance is and is normally positive. MX is the only source that reports it, and only for some accounts (common on checking, rare on cards), so it is null far more often than not. Check realized_capabilities.available_balance rather than assuming it is present.
How far back our transaction history for this account actually goes: the date of the oldest transaction we hold. It is the minimum date you will see if you page this account's entire history through GET /accounts/{account_id}/transactions. Measured from the transactions we hold, not a claim by the aggregator about what it could supply. Null means we hold no transactions for this account at all, which is normal for one that was linked but has not completed a first refresh. It moves backwards, never forwards, when a backfill lands, and it is not a promise about what a future refresh will retrieve.
"2023-04-11"
Credit-card terms for this account: what the client can borrow, what they owed at the last statement close, and what the bank wants next. Null for every account that is not a credit card or line of credit, and also for cards at institutions that do not report these values, so its presence is itself the signal that anything is known. Individual fields inside it are independently nullable for the same reason.
Show child attributes
Show child attributes
Per-account observed outcome of the most recent attempt at each capability. Today the backend tracks status at the bank level — accounts within the same connection share this snapshot. Per-account divergence (one account in a connection failed but others succeeded) requires a backend extension and is deferred.
Show child attributes
Show child attributes
When LedgerSync first stored this account, which is when we
first saw it at the source. For accounts present at link time
this tracks the connection; for one shared later it is when it
arrived. There is no account.added webhook, so this is the
field to sort or diff on when you re-list accounts to find what
is new. It never moves afterwards.
