Every SDK 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#
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:
{
"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.
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 anIdempotent-Replay: trueheader. - 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
409withRetry-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.