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

# Introduction

> Payouts, collections, and FX across African rails — bank, mobile money, and stablecoins — through one API.

Chipper Platform is a payments API for Africa. One integration sends money to bank accounts, mobile money wallets, and crypto addresses across Ghana, Nigeria, Kenya, Uganda, and Rwanda — and collects money over the same rails.

## Base URLs

The API runs as two fully separate stacks. Your key decides where a request lands — `sk_test_…` keys only work against sandbox, `sk_live_…` keys only against production.

| Stack          | Base URL                                  | Money                                                                |
| -------------- | ----------------------------------------- | -------------------------------------------------------------------- |
| **Production** | `https://api.platform.chipper.ai`         | Real money.                                                          |
| **Sandbox**    | `https://sandbox-api.platform.chipper.ai` | Simulated fiat rails, testnet blockchains. Nothing moves real funds. |

Sandbox behaves like production — same endpoints, same shapes, same webhooks — so an integration built against it ports to live keys without code changes.

## The fastest way to integrate

Hand these docs to your AI agent and let it build the integration. Every page is served as plain Markdown (append `.md` to any URL, or fetch [`/llms.txt`](/llms.txt)), and the docs run an **MCP server** your agent can connect to and search directly — so Claude Code, Cursor, or any coding agent can read the reference, write the calls, and test them against the sandbox without you copy-pasting a thing. Give the agent a sandbox key and point it here; see [Building with AI agents](/guides/ai-agents) for scoped keys and spend caps when it graduates to real money.

## Making your first request

<Steps>
  <Step title="Create an API key">
    In the [dashboard](https://chipper-platform-web-dashboard.onrender.com), go to **Developers → API keys** and create a sandbox key. Keys are shown once — store them like passwords.
  </Step>

  <Step title="Validate a destination">
    ```bash theme={null}
    curl https://sandbox-api.platform.chipper.ai/v1/validate \
      -H "Authorization: Bearer sk_test_..." \
      -H "Content-Type: application/json" \
      -d '{"code": "gh_mtn", "accountNumber": "233559630374"}'
    ```

    The response resolves the account holder's name — catch typos while the money is still yours.
  </Step>

  <Step title="Send a payout">
    ```bash theme={null}
    curl https://sandbox-api.platform.chipper.ai/v1/payouts \
      -H "Authorization: Bearer sk_test_..." \
      -H "Content-Type: application/json" \
      -d '{
        "to": {
          "code": "gh_mtn",
          "accountNumber": "233559630374",
          "amount": 150,
          "currency": "GHS",
          "recipient": { "name": "Ama Serwaa" }
        },
        "externalReference": "inv-1042"
      }'
    ```
  </Step>
</Steps>

## Conventions

**Response envelopes.** Single resources come wrapped in a key named after the resource — `{ "payout": { … } }`, `{ "recipient": { … } }`. Lists always return `{ "data": [...], "hasMore": bool, "nextCursor": string | null }`.

**Pagination.** Every list takes `limit` (1–100, default 20) and `cursor`. Pass the previous page's `nextCursor` as `cursor` to walk forward; `nextCursor` is `null` on the last page. Results are newest first.

**Money is a string.** Amounts in responses are decimal strings (`"150.00"`), never floats. Parse with a decimal library, not `parseFloat`, when doing arithmetic.

**Idempotency.** Money-moving endpoints take an `externalReference` — your unique reference for the operation. Retrying with the same value never creates a duplicate: you get the original resource back with status `200` instead of `201`.

**Errors.** Every error is the same shape:

```json theme={null}
{
  "error": "not_found",
  "message": "Recipient not found",
  "requestId": "req_q7vei435zifs51ia0lqr"
}
```

`error` is a stable machine-readable code; `message` is for humans. `requestId` is also echoed in the `x-request-id` response header on every request — include it when contacting support and we can find the exact request.

**IDs carry their type.** `pay_…` payouts, `rcp_…` recipients, `ord_…` orders, `pl_…` payment links. On sandbox, customer-facing ids carry the stack too: `pl_test_…`.

## What's documented so far

The reference covers the full API-key surface — payouts, recipients, validation, collections, virtual accounts, crypto addresses, orders, conversions, payment links and pages, transactions, webhooks, disputes, files, and the sandbox simulations.
