Skip to content

Events ​

Scopes: events:read to read, events:write to ask for one again. Live only.

GET /v1/events ​

Every event for your key's mode, newest first, whether or not it was delivered. This is how you catch up after an outage or before you had an endpoint.

Query: limit, starting_after, type (e.g. charge.succeeded).

json
{
  "id": "ev_…",
  "object": "event",
  "type": "charge.succeeded",
  "created": 1758013442,
  "livemode": true,
  "data": { "…": "…" },
  "delivery": {
    "state": "retrying",
    "attempts": 3,
    "attempts_remaining": 4,
    "last_status": 502,
    "last_response": "<html>Bad Gateway…",
    "last_attempt_at": 1758015242,
    "next_attempt_at": 1758022442
  }
}

delivery.state is one of pending · retrying · delivered · exhausted · unrouted (no endpoint was registered when it happened). It is the state of our conversation with your server, never the state of the payment — an exhausted charge.succeeded is still a payment you were paid. last_status: 0 means we could not reach you at all.

GET /v1/events/{id} ​

One event, with its delivery history.

POST /v1/events/{id}/retry ​

Ask for an event to be sent again. Allowed when it is delivered, exhausted or unrouted; the attempt count resets to zero. Returns the event. If it is already pending or retrying, ALREADY_QUEUED (409) — your intent is already true.

Nothing is sent by this call. It makes the event due, and the delivery job — the only thing that ever opens a socket to your server — picks it up within a minute. A replay behaves exactly like a first attempt because it is one.

A catch-up job ​

After any outage, page through GET /v1/events?type=charge.succeeded back to the last event you processed, and process anything you have not seen. Because delivery is at-least-once and your handler already deduplicates on id, the catch-up can be as generous as you like.

Every code, scope and route on this site is rendered from the API's own source.