> ## Documentation Index
> Fetch the complete documentation index at: https://docs.integrateledger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API reference

> The Ledger REST API, its conventions, authentication, errors, idempotency and pagination.

The Ledger API is a JSON API over HTTPS. It's organised around a few resources: usage (check and track), customers, billing, and the catalog of plans, features and credit packs. The [OpenAPI spec](https://docs.integrateledger.com/openapi.json) describes every endpoint, for code generation and agent tools.

```text Base URL theme={"system"}
https://api.integrateledger.com
```

There's one base URL for both environments. The API key decides whether a request reads and writes Sandbox or Live.

## Authentication

Send a secret key as a bearer token on every request. Keys start with `ledger_test_` (Sandbox) or `ledger_live_` (Live), and each can be limited to groups of endpoints. See [API keys and permissions](https://docs.integrateledger.com/api-keys.md).

```bash theme={"system"}
curl https://api.integrateledger.com/v1/plans \
  -H "Authorization: Bearer $LEDGER_API_KEY"
```

Keep keys on your server. The API has no endpoints meant for browsers or mobile apps.

## Conventions

* **Methods.** `GET` reads, `POST` creates and updates, `DELETE` archives catalog items or deletes a customer. Updates take the item's complete body.
* **Bodies.** Send JSON with `Content-Type: application/json`, up to 1 MiB. Requests without the header get `415`; larger bodies get `413`.
* **Customers.** Identify a customer by your own ID, `customerId`, in the body or, on `GET` and some `POST` and `DELETE` requests, as a URL-encoded query parameter: `?customerId=user_123`.
* **Money** is in US cents, in fields ending in `Cents`.
* **Timestamps** are ISO 8601 strings in UTC.
* **Request IDs.** Every response has an `x-request-id` header. Quote it when you ask about a request.

## Errors

Errors return a non-2xx status and a body with an `error` code, sometimes with fields that help you act:

```json theme={"system"}
{
  "error": "insufficient_credits",
  "availableCredits": 0,
  "creditCost": 1
}
```

[Errors](https://docs.integrateledger.com/errors.md) lists every code with what to do about it.

## Idempotency

Retries are safe where they matter:

| Endpoint | How |
| - | - |
| `POST /v1/track` | The `request_id` you send. A repeat returns the first result with `"idempotent": true`. |
| `POST /v1/billing/upgrade` | The `Idempotency-Key` header. A repeat returns the upgrade's current state. |
| `POST /v1/billing/attach` | While a Checkout is open, attaching the same plan or pack returns it again. |
| `POST /v1/customers` | Returns the existing customer with `"created": false`. |

## Rate limits

Each key can send `check` and `track` at 200 requests a second, billing and catalog writes at 5 a second, and everything else at 50 a second, with short bursts above that. Every response carries `RateLimit-*` headers; over the limit, Ledger returns `429` with a `Retry-After` header. See [Rate limits](https://docs.integrateledger.com/rate-limits.md).

## Pagination

[List customer subscriptions](https://docs.integrateledger.com/api-reference/customers/subscriptions.md) and [List customer purchases](https://docs.integrateledger.com/api-reference/customers/purchases.md) return pages, newest first:

```json theme={"system"}
{
  "items": [],
  "hasMore": true,
  "nextCursor": 42
}
```

Pass `limit` (1–100, default 25), and when `hasMore` is `true`, pass `nextCursor` as `cursor` to get the next page. Catalog lists return every active item at once.

## SDKs

The [TypeScript and Python SDKs](https://docs.integrateledger.com/sdks.md), both `integrateledger`, wrap every endpoint except deleting a customer. Each endpoint page shows cURL, TypeScript and Python.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.