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

# API reference

> Base URL, versioning, JSON conventions, pagination, idempotency, and status codes for the Drin REST API.

The Drin REST API. Every endpoint is versioned under /v1, speaks JSON, and authenticates with a bearer key. The same surface is mirrored by the SDK, the CLI, and the MCP server.

The base URL is `https://api.drin.run`. Authenticate every request with your API key in the `Authorization` header. You can run your first `POST /v1/emails` the moment you have a key — no DNS required in test mode.

```bash Base URL theme={null}
curl https://api.drin.run/v1/emails \
  -H "Authorization: Bearer $DRIN_API_KEY"
```

## Conventions

Requests and responses are JSON. Send `Content-Type: application/json` on any request with a body. Field names are `camelCase`; timestamps are ISO 8601 (`2026-06-02T17:04:00Z`); identifiers are opaque strings — treat them as such and never parse them.

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    `Authorization: Bearer <key>`, plus `X-Drin-Product` to name a project for account-wide keys.
  </Card>

  <Card title="Errors" icon="shield" href="/api-reference/errors">
    A consistent `{ "error": { "type", "message" } }` envelope on every non-2xx response.
  </Card>

  <Card title="Pagination" icon="chart-line" href="/api-reference/pagination">
    Cursor pages: `?limit`, `?cursor`, `nextCursor`.
  </Card>

  <Card title="Rate limits" icon="bolt" href="/api-reference/rate-limits">
    `429` with a `Retry-After` header when you go too fast.
  </Card>
</CardGroup>

## Versioning

Every path is prefixed with `/v1`. We add fields and endpoints without bumping the version — new optional response fields and new query parameters are not breaking changes, so write your client to ignore unknown fields. A breaking change would ship under a new version prefix.

## Pagination

List endpoints return a cursor page. Pass `?limit` (1–100) and `?cursor` (the previous response's `nextCursor`). When `nextCursor` is `null`, you've reached the end.

```json Page shape theme={null}
{
  "data": [ /* … */ ],
  "nextCursor": "eyJpZCI6Im1zZ18wMUgifQ"
}
```

The SDK and CLI auto-paginate. See [Pagination](/api-reference/pagination) for the full walk.

## Idempotency

Send an `Idempotency-Key` header on a `POST` to make it safe to retry — the same key replays the original result for 24 hours, per project, so a retried send never duplicates. See [Idempotency & retries](/idempotency).

## Status codes

Drin uses conventional HTTP status codes.

| Code          | Meaning                                                                |
| ------------- | ---------------------------------------------------------------------- |
| `200` / `201` | Success. The body holds the resource you asked for.                    |
| `202`         | Accepted — the send was queued. Returns a message `id` and a `status`. |
| `204`         | Success, no body (for example, a delete).                              |
| `207`         | Multi-status — a batch where items can each succeed or fail.           |
| `4xx`         | Your request. See [Errors](/api-reference/errors).                     |
| `5xx`         | Our side. Safe to retry idempotently.                                  |

<Note>
  **Request IDs.** Every response echoes an `X-Request-Id` header. Include it when you contact support — it lets us find the exact request in our logs.
</Note>

<Card title="Send your first request" icon="rocket" href="/quickstart">
  The quickstart walks through a real `POST /v1/emails` end to end.
</Card>
