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

# The HTTP API

> Publish events over plain HTTPS: one endpoint, an idempotency key, and clear status codes.

Every [SDK](/docs/send/sdks) publishes through one HTTPS endpoint. Most applications use a generated client and never call it directly, but it is all you need from a language without an SDK, a script, or `curl`.

## Publish an event

```bash theme={"languages":{"custom":["/languages/repost.json"]}}
curl -X POST https://api.repost.sh/v1/messages \
  -H "Authorization: Bearer $REPOST_SEND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1001" \
  -d '{
    "type": "order.created",
    "customerId": "acme",
    "data": { "id": "order-1001", "currency": "EUR" }
  }'
```

| Field        | Required | Meaning                                                         |
| ------------ | -------- | --------------------------------------------------------------- |
| `type`       | Yes      | The event type, as deployed from your schema (`order.created`). |
| `customerId` | Yes      | The customer's `externalId`.                                    |
| `data`       | Yes      | The payload, shaped by the event's model.                       |
| `timestamp`  | No       | RFC 3339 (`2026-07-02T12:00:00Z`). Defaults to now.             |

Authentication is a Bearer token with the `publish` scope. The `Idempotency-Key` header (up to 255 characters) is optional but recommended; it is what makes retries safe.

A successful publish returns `202 Accepted` with the message:

```json theme={"languages":{"custom":["/languages/repost.json"]}}
{
  "id": "msg_01JZX3NV7Q9WD9F2M6K4T8RSAB",
  "type": "order.created",
  "customerId": "acme",
  "timestamp": "2026-07-17T12:00:00.000Z"
}
```

`202` means Repost has stored the event durably and will deliver it. Fan-out, signing, and retries happen after this point and are covered under [delivery](/docs/send/delivery).

## Idempotency

To make sure an event is sent exactly once even when your side crashes and retries, set an idempotency key that names the business fact, such as `order-1001-created`, rather than a random value per attempt. Repost remembers each key for 24 hours together with the body it arrived with:

* The same key with the same body returns the original message: `202`, with an `Idempotent-Replay: true` header.
* The same key with a different body is rejected with `422`. A key refers to one event; hitting this response means a bug in your key logic.
* The same key while the first attempt is still in flight gets `409` with `Retry-After: 1`. Retry a moment later to receive the replay.

With stable keys, queue redeliveries, crashed workers, and timeout-retry loops all collapse into a single delivered event.

## Status codes

| Status        | Meaning                                                                  | What to do                        |
| ------------- | ------------------------------------------------------------------------ | --------------------------------- |
| `202`         | Accepted, or an idempotent replay.                                       | Done.                             |
| `400`         | Missing or invalid field, bad timestamp, oversized key, or invalid JSON. | Fix the request.                  |
| `401` / `403` | Bad token, or missing the `publish` scope for this environment.          | Fix credentials.                  |
| `409`         | Same idempotency key currently in flight (`Retry-After: 1`).             | Retry shortly.                    |
| `413`         | Payload over 1 MiB.                                                      | Send references instead of blobs. |
| `422`         | Idempotency key reused with a different payload.                         | Fix the key logic.                |
| `429`         | Environment rate limit (`Retry-After: 1`).                               | Back off and retry.               |
| `503`         | Temporarily unable to accept messages (`Retry-After: 2`).                | Retry with backoff, same key.     |

Retry `409`, `429`, `503`, and network failures, always with the same idempotency key. The other errors indicate a problem in the request itself.

## Continue

<Columns cols={3} className="gap-y-4">
  <Card title="SDKs" icon="package" href="/docs/send/sdks" cta="Typed clients" arrow="true">
    Generated clients that handle these details for you.
  </Card>

  <Card title="Delivery & retries" icon="shield-check" href="/docs/send/delivery" cta="After the 202" arrow="true">
    How the accepted message reaches your customers.
  </Card>

  <Card title="Customers & endpoints" icon="users" href="/docs/send/endpoints" cta="Recipients" arrow="true">
    The management API for customers, endpoints, secrets, and replay.
  </Card>
</Columns>
