Funding and Ledger Accounts

Find the ledger account your payouts are paid from, check its balance, and reconcile its transactions.

A ledger account holds the money you pay out from. Every payment is paid from exactly one ledger account, in that account's currency. This page shows how to find your accounts, read their balance and history, and what happens when an account runs short.

Before you start

  • Payment Labs opens your ledger accounts when your account is set up, one per currency you pay out in. You cannot create one through the API.
  • You fund an account by sending money to the bank details Payment Labs gives you for it. Funding happens outside the API; contact Payment Labs for the funding instructions of each account.
  • The operations on this page need any payout role.

Step 1: List your ledger accounts

Call List Ledger Accounts. Archived accounts are left out unless you send showArchived=true.

curl https://api-sandbox.paymentlabs.io/payors/me/ledgers \
  -H "Authorization: Bearer $TOKEN"
[
  {
    "id": "A-01JD8ZK3V6M2Q4R7T9W1X3Y5Z7",
    "alias": "usd-main",
    "currency": "USD",
    "accountNumber": "100200300",
    "balance": { "value": 25000, "currency": "USD", "formattedValue": "$25,000.00", "digits": 2, "wholeValue": 2500000 },
    "lastRowId": "L-01JDB2C3D4E5F6G7H8J9K0M1N2",
    "archived": false
  }
]

lastRowId is the ID of the account's most recent transaction row; it changes whenever the balance moves, so you can compare it with a saved value to see whether there is new activity before you read the history.

Keep the id (or the alias) of each account. You pass it as ledgerAccount when you create a payment. Both forms are accepted. If you have exactly one active account you can leave ledgerAccount out and that account is used.

Get Payor also returns your accounts and balances in ledgerAccounts.

Step 2: Read the transaction history

Call Get Ledger Account Transactions with a date range to get the movements on one account.

curl "https://api-sandbox.paymentlabs.io/payors/me/ledgers/A-01JD8ZK3V6M2Q4R7T9W1X3Y5Z7?startDate=2026-10-01&endDate=2026-10-31&enrich=true" \
  -H "Authorization: Bearer $TOKEN"
  • startDate and endDate go together, and the range can cover at most 90 days. Without them you get the account and its balance only.
  • The response adds startingBalance, endingBalance and rows. Each row has an id, a timestamp, a memo, a signed amount and a status: DRAFT, PENDING, COMPLETED, REFUNDED or CANCELLED.
  • enrich=true adds details about the payment or deposit behind each row. Its comments lists changes made to the payment after it was created: a new category, a new tax jurisdiction, or the original amount (in minor units) when the amount changed.
  • Rows come newest first, up to 1,000 per response. When the response includes nextStartDate, there are older rows left in the range: call again with the same startDate and with endDate set to nextStartDate. Repeat until nextStartDate is absent. Paging repeats rows from the day of nextStartDate, so de-duplicate by each row's id. A single day with more than 1,000 rows cannot be paged past this way.
  • For a full history, or for busy days, use Export Ledger Transactions instead (see Step 3).

Step 3: Export statements

You wantCall
A PDF statement for a periodExport Ledger Statement with startDate and endDate (both required, at most 90 days apart). The response is the PDF file.
The transaction history as a spreadsheetExport Ledger Transactions with startDate, endDate, format (csv or xlsx, default csv) and an optional timezoneOffset in minutes (from -840 to 720). The response is { "fileUrl": "..." }, a short-lived download link. Download the file straight away.

Know when funds arrive

Subscribe to the ledger-account-credited webhook. It fires when money lands on one of your ledger accounts and carries the amount credited, the new balance and the ledgerAccountId.

How payments use the balance

  • When you submit a single payment, Payment Labs checks that the account balance covers the payment's sourceAmount. If it does not, the call fails with 423 and code: INSUFFICIENT_BALANCE and nothing is queued.
  • That check does not include fees. A payment that passes it can still be short once fees are added. It then waits for funds: its status stays SUBMITTED, and it is sent automatically after your next deposit arrives. A payment that stays SUBMITTED longer than you expect usually means the account needs funding.
  • Submitting a whole batch does not check the balance up front. Every payment that cannot be covered waits for funds in the same way.
  • When a payment is returned, the returned amount goes back to the ledger account it was paid from. See Payment Statuses.

Errors and edge cases

ErrorMeaningWhat to do
400 START_DATE_AND_END_DATE_REQUIRED_TOGETHERYou sent one date without the other on Get Ledger Account Transactions.Send both or neither.
400 START_DATE_AND_END_DATE_REQUIREDAn export was called without both dates.Send both.
400 START_DATE_INVALID_DATE_FORMAT, 400 END_DATE_INVALID_DATE_FORMATA date could not be read.Use YYYY-MM-DD or a full ISO 8601 timestamp.
400 START_DATE_LATER_THAN_END_DATEThe range is reversed.Swap the dates.
400 DATE_RANGE_TOO_LONGThe range is longer than 90 days.Split it into several calls.
400 INVALID_FORMAT, 400 INVALID_TIMEZONE_OFFSETBad format or timezoneOffset on the spreadsheet export.Use csv or xlsx, and an offset from -840 to 720.
404 NOT_FOUNDThe account is not one of yours.Check the id against List Ledger Accounts.
400 VALIDATION_ERROR on Create Payment, with details.ledgerAccount[0].code = MORE_THAN_ONE_LEDGER_ACCOUNTYou left ledgerAccount out and you have more than one active account.Send ledgerAccount.
Same, with code INVALID_LEDGER_ACCOUNTThe ledgerAccount you sent is not one of your active accounts. constraints.validAccounts lists the aliases you can use.Send one of those.

Next steps


What’s Next

Did this page help you?