# Get ledger balances and transactions

In this tutorial, you'll use two ledger API operations to monitor your account balance and retrieve a detailed record of activity in your prefunded account:

1. **Get available balances** — retrieve the current available and reserved balances for your account.
2. **Get ledger transactions** — retrieve a paginated list of ledger transactions within a date-time range for reconciliation.


You'll also learn how to:

- Paginate through large result sets using offset-based pagination.
- Filter by payment ID to find all ledger entries associated with a specific payment.
- Export results as CSV for use in reconciliation workflows.


For background on how ledger operations (RESERVE, DEBIT, CREDIT, RELEASE) affect your balance, see [Ledger transactions](/products/payments-direct-2/v2026.03/api-docs/concepts/ledger-transactions).

## Before you begin

To follow this tutorial, you need:

- Access to the Ripple Payments Direct 2.0 API UAT environment.
- A valid OAuth2 access token. See [Request an access token](/products/payments-direct-2/v2026.03/api-docs/tutorials/request-an-access-token).
- At least one completed or in-flight payment (to observe meaningful ledger entries).


## Step 1: Get available balances

Use the **Get available balances** operation to see how much is currently available in your prefunded account, and how much is reserved for in-flight payments.

### Endpoint

`GET /v2/balances`

### Optional query parameter

| Parameter | Type | Description |
|  --- | --- | --- |
| `currency` | string | Filter results to a single currency (for example, `USD`). If omitted, all currencies are returned. |


### Example request — all currencies


```bash
curl -X GET "https://api.test.ripple.com/v2/balances" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

### Example request — USD only


```bash
curl -X GET "https://api.test.ripple.com/v2/balances?currency=USD" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

### Example response


```json
{
  "timestamp": "2025-03-15T10:30:00.000000Z",
  "balances": [
    {
      "fundingType": "FUNDED",
      "currency": "USD",
      "availableBalance": 50000.00,
      "reservedBalance": 2500.00
    }
  ]
}
```

### Understanding the balance fields

| Field | Description |
|  --- | --- |
| `availableBalance` | Funds that are currently spendable. This is the balance you can use to initiate new payments. |
| `reservedBalance` | Funds currently held aside for in-flight payments. You cannot use this balance to initiate new payments until the reservation is released or consumed. |
| `timestamp` | The time at which the balance snapshot was taken. |


Balance and payment creation
If a payment creation request fails with error `USR_067` (Insufficient balance), compare `availableBalance` against the payment amount. The reserved balance is not available for new payments.

## Step 2: Get ledger transactions

Use the **Get ledger transactions** operation to retrieve a paginated list of ledger entries within a date-time range. Each entry shows the operation performed, its effect on your available balance, and the source that created it.

### Endpoint

`GET /v2/ledger-transactions`

### Required query parameters

| Parameter | Description | Example |
|  --- | --- | --- |
| `currency` | ISO 4217 currency code. | `USD` |
| `start-dttm` | Start of the date-time range (inclusive, UTC). | `2025-03-15T00:00:00Z` |
| `end-dttm` | End of the date-time range (exclusive, UTC). | `2025-03-16T00:00:00Z` |
| `page-size` | Number of records per page. Minimum: 1, maximum: 50. | `25` |


### Example request


```bash
curl -X GET "https://api.test.ripple.com/v2/ledger-transactions?\
currency=USD\
&start-dttm=2025-03-15T00:00:00Z\
&end-dttm=2025-03-16T00:00:00Z\
&page-size=25" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Accept: application/json"
```

### Example response


```json
{
  "offset": "0",
  "pageSize": "25",
  "pageElements": "10",
  "total": "10",
  "statementTransactions": [
    {
      "tenant": "acme-corp",
      "amount": "14.00",
      "currency": "USD",
      "operation": "DEBIT",
      "txnSource": "PAYMENTS",
      "status": "SUCCESS",
      "createdDttm": "2025-03-15T10:25:12.000000Z",
      "updatedDttm": "2025-03-15T10:25:12.000000Z",
      "availableBalanceBefore": "50014.00",
      "availableBalanceAfter": "50014.00"
    },
    {
      "tenant": "acme-corp",
      "amount": "10000.00",
      "currency": "USD",
      "operation": "DEBIT",
      "txnSource": "PAYMENTS",
      "status": "SUCCESS",
      "createdDttm": "2025-03-15T10:25:10.000000Z",
      "updatedDttm": "2025-03-15T10:25:10.000000Z",
      "availableBalanceBefore": "50014.00",
      "availableBalanceAfter": "50014.00"
    },
    {
      "tenant": "acme-corp",
      "amount": "10014.00",
      "currency": "USD",
      "operation": "RESERVE",
      "txnSource": "PAYMENTS",
      "status": "SUCCESS",
      "createdDttm": "2025-03-15T10:23:45.000000Z",
      "updatedDttm": "2025-03-15T10:23:45.000000Z",
      "availableBalanceBefore": "60014.00",
      "availableBalanceAfter": "50000.00"
    }
  ]
}
```

### Understanding ledger operations

The `operation` field tells you what action was applied to your account. The sequence of RESERVE → DEBIT is the typical pattern for a completed payment.

| Operation | Effect on `availableBalance` | When it occurs |
|  --- | --- | --- |
| `CREDIT` | Increases | Funds are added to your account (for example, a top-up). |
| `RESERVE` | Decreases | Funds are set aside when a payment enters the validation or transferring state. |
| `DEBIT` | No change (typically) | Reserved funds are consumed when a payment completes. The available balance already decreased at RESERVE time. |
| `RELEASE` | Increases | Reserved funds are returned when a payment fails or is cancelled. |
| `VOID_BALANCE` | Implementation-specific | Administrative correction. Contact Ripple technical support for details. |
| `OVERRIDE_BALANCE` | Implementation-specific | Administrative correction. Contact Ripple technical support for details. |


Why DEBIT doesn't change the available balance
When a payment starts, the `RESERVE` operation moves funds out of available balance and into a reserved state. When the payment completes, `DEBIT` finalizes the outflow from the reserved amount. But since available balance already decreased at `RESERVE` time, `availableBalanceBefore` and `availableBalanceAfter` are typically equal for a `DEBIT` entry. If a payment fails, a `RELEASE` entry returns the reserved funds to available balance.

## Step 3: Paginate through results

If the `total` value in the response is greater than `pageElements`, there are more records to retrieve. Use the `offset` parameter to fetch subsequent pages.

**Pattern:** Set `offset` to a multiple of `page-size` to advance through pages.

### Example: Fetch the second page


```bash
curl -X GET "https://api.test.ripple.com/v2/ledger-transactions?\
currency=USD\
&start-dttm=2025-03-15T00:00:00Z\
&end-dttm=2025-03-16T00:00:00Z\
&page-size=25\
&offset=25" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

Continue incrementing `offset` by `page-size` until `pageElements` in the response is less than `page-size`, which indicates you have reached the last page.

Fix your time range before paginating
Do not change `start-dttm` or `end-dttm` between pages of the same query. Changing the time range mid-pagination can cause you to miss or duplicate records.

## Step 4: Filter by payment ID

To find all ledger entries associated with a specific payment, use the `txnReference` parameter. For payments, the `txnReference` value is the `paymentId` returned when the payment was created.

This is useful for auditing a specific payment's balance impact (the RESERVE, DEBIT, and any RELEASE entries for that payment).

### Example: Look up ledger entries for a specific payment


```bash
curl -X GET "https://api.test.ripple.com/v2/ledger-transactions?\
currency=USD\
&start-dttm=2025-03-15T00:00:00Z\
&end-dttm=2025-03-16T00:00:00Z\
&page-size=25\
&txnReference=aa74f2f4-5996-4f0c-9d8a-7a5e1d51c502" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

### Example response


```json
{
  "offset": "0",
  "pageSize": "25",
  "pageElements": "2",
  "total": "2",
  "statementTransactions": [
    {
      "tenant": "acme-corp",
      "amount": "10014.00",
      "currency": "USD",
      "operation": "DEBIT",
      "txnSource": "PAYMENTS",
      "status": "SUCCESS",
      "createdDttm": "2025-03-15T10:25:10.000000Z",
      "updatedDttm": "2025-03-15T10:25:10.000000Z",
      "availableBalanceBefore": "50014.00",
      "availableBalanceAfter": "50014.00"
    },
    {
      "tenant": "acme-corp",
      "amount": "10014.00",
      "currency": "USD",
      "operation": "RESERVE",
      "txnSource": "PAYMENTS",
      "status": "SUCCESS",
      "createdDttm": "2025-03-15T10:23:45.000000Z",
      "updatedDttm": "2025-03-15T10:23:45.000000Z",
      "availableBalanceBefore": "60014.00",
      "availableBalanceAfter": "50000.00"
    }
  ]
}
```

This shows the complete ledger impact of the payment: funds were reserved when the payment was created, and debited when it completed.

## Step 5: Export as CSV

For reconciliation workflows, you can request the response as a CSV file by setting the `Accept: text/csv` header. If this header is omitted, the API returns JSON by default.

### Example: Download a CSV statement


```bash
curl -X GET "https://api.test.ripple.com/v2/ledger-transactions?\
currency=USD\
&start-dttm=2025-03-01T00:00:00Z\
&end-dttm=2025-04-01T00:00:00Z\
&page-size=50" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Accept: text/csv" \
  -o ledger-march-2025.csv
```

### CSV format

The CSV response includes the same fields as the JSON response, as column headers:


```csv
tenant,amount,currency,txnReference,operation,txnSource,status,createdDttm,updatedDttm,availableBalanceBefore,availableBalanceAfter
acme-corp,10014.00,USD,aa74f2f4-5996-4f0c-9d8a-7a5e1d51c502,DEBIT,PAYMENTS,SUCCESS,2025-03-15T10:25:10Z,2025-03-15T10:25:10Z,50014.00,50014.00
acme-corp,10014.00,USD,aa74f2f4-5996-4f0c-9d8a-7a5e1d51c502,RESERVE,PAYMENTS,SUCCESS,2025-03-15T10:23:45Z,2025-03-15T10:23:45Z,60014.00,50000.00
```

Pagination applies to CSV too
CSV responses are also paginated. For large date ranges, use the `offset` parameter to retrieve subsequent pages and concatenate the results, omitting the header row from all pages after the first.

## Sorting results

Use `sort-key` and `sort-direction` to control the order of results. The default sort order is determined by the API if these parameters are omitted.


```bash
curl -X GET "https://api.test.ripple.com/v2/ledger-transactions?\
currency=USD\
&start-dttm=2025-03-15T00:00:00Z\
&end-dttm=2025-03-16T00:00:00Z\
&page-size=25\
&sort-key=CREATED_AT\
&sort-direction=DESC" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

Supported `sort-key` values:

| Value | Sorts by |
|  --- | --- |
| `CREATED_AT` | Transaction creation timestamp |
| `STATEMENT_OPERATION` | Operation type (CREDIT, DEBIT, etc.) |
| `STATEMENT_SOURCE` | Transaction source (PAYMENTS, BANK, etc.) |
| `STATEMENT_STATUS` | Ledger transaction status |
| `STATEMENT_TXN_REFERENCE` | Transaction reference |
| `STATEMENT_UPDATED_AT` | Last update timestamp |


## Error handling

| Error code | Status | Description | Action |
|  --- | --- | --- | --- |
| `USR_251` | 400 | Request parameter missing. | A required parameter (`currency`, `start-dttm`, `end-dttm`, or `page-size`) is missing. Add the missing parameter and retry. |
| `SYS_301` | 500 | Internal server error. | Retry with exponential backoff. Contact Ripple technical support if the issue persists. |
| `CFG_201` | 500 | Invalid configuration. | Unable to retrieve balances due to a configuration issue. Contact Ripple technical support. |
| `AUTH_001` | 401 | Unauthorized. | Your token is invalid or expired. Generate a new access token and retry. |


## Summary and next steps

In this tutorial, you:

1. Retrieved your current available and reserved balances using `GET /v2/balances`.
2. Fetched a paginated list of ledger transactions for a date range using `GET /v2/ledger-transactions`.
3. Filtered transactions by payment ID using the `txnReference` parameter.
4. Exported results as CSV for reconciliation.


**Next steps:**

- To understand how ledger operations map to payment lifecycle events, see [Ledger transactions](/products/payments-direct-2/v2026.03/api-docs/concepts/ledger-transactions).
- To create payments that will appear as ledger entries, see [Create a payment](/products/payments-direct-2/v2026.03/api-docs/tutorials/create-a-payment).
- For balance-related error codes, see [API error codes](/products/payments-direct-2/v2026.03/api-docs/error-codes/api-errors).
- For monitoring payment state changes that drive ledger activity, see [Polling](/products/payments-direct-2/v2026.03/api-docs/best-practices/polling) or [Notification webhooks](/products/payments-direct-2/v2026.03/api-docs/best-practices/notification-webhooks).