# API overview

The base URL, the auth header, the request/response conventions, and an index of every paylod endpoint.

## Base URL

```text title="Base URL"
https://paylod.dev/functions/v1
```

## Authentication

Every endpoint takes a bearer API key. The key determines the application and the environment, so no request ever carries a shortcode or a Daraja credential.

```http title="Header"
Authorization: Bearer mp_live_YOUR_API_KEY
```

See [Authentication](/docs/authentication) for keys, environments, idempotency and rate limits.

## Endpoints

| Method | Path | What it does |
| --- | --- | --- |
| `POST` | [`/collect`](/docs/api/payments) | Send an STK Push to a customer's handset |
| `GET` | [`/status/:id`](/docs/api/payments) | Read a payment's current state |
| `POST` | [`/payout`](/docs/api/payouts) | Send money out to a customer (B2C) |
| `POST` | [`/reversal`](/docs/api/payouts) | Reverse or refund a completed transaction |
| `POST` | [`/qr-generate`](/docs/api/other) | Generate a dynamic Lipa na M-Pesa QR code |
| `POST` | [`/c2b-register`](/docs/api/other) | Register offline C2B confirmation + validation URLs |
| `POST` | [`/transaction-status`](/docs/api/other) | Query a historical transaction by receipt |
| `POST` | [`/account-balance`](/docs/api/other) | Query your shortcode's M-Pesa float |

## Synchronous vs asynchronous

M-Pesa is an asynchronous network, and paylod does not pretend otherwise.

- **`200 OK`** — the answer is in the response body. Only `GET /status/:id` and `POST /qr-generate` and `POST /c2b-register` work this way.
- **`202 Accepted`** — the request was accepted and handed to M-Pesa. The real outcome arrives later, on your [webhook](/docs/api/webhooks) (or, for `/collect`, by polling `GET /status/:id`). The body carries an id you can correlate on.

Asynchronous endpoints that move money or read the ledger (`/payout`, `/reversal`, `/transaction-status`, `/account-balance`) also require the application's **Initiator Name** and **Initiator Password** to be configured. See [Go live](/docs/guides/go-live).

## Errors

| Status | Meaning |
| --- | --- |
| `400` | Malformed JSON, or Daraja credentials not configured for this app and environment |
| `401` | Missing or invalid API key |
| `404` | Not found, or belongs to another application |
| `409` | Idempotency key reused with a different body |
| `422` | Body failed validation |
| `429` | Rate limited |
| `502` | Daraja rejected the request — the upstream error is passed through |

M-Pesa's own result codes (`1032`, `1037`, `2001`, …) are decoded in the [error reference](/docs/errors).
