Webhooks
Register an endpoint, understand the delivery guarantees, and debug what was sent.
A webhook is an event we send to your HTTPS endpoint when something changes: a deposit lands, an endorsement is decided, a wallet send confirms. This page covers registration, delivery, and recovery. The payload and its authentication have their own pages:
Event structure
The envelope, the full event-kind catalog, and what rides in
data.object.
Verifying signatures
How to authenticate a delivery before you trust a byte of it.
Prerequisites
- An HTTPS endpoint that returns 2xx before it does any work.
- Somewhere to store processed event ids, for deduplication.
- A place to keep the endpoint's signing secret, per environment.
Registering an endpoint
curl -s $BASE/api/webhooks \
-H "Api-Key: $KEY" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"url": "https://yourapp.example/rasto/webhook"}'
{
"id": "whk_033y9PqRsTuVwXyZaBcDe",
"object": "webhook",
"url": "https://yourapp.example/rasto/webhook",
"event_kinds": null,
"secret": "whsec_..."
}
secretis shown once, in this response. It is the endpoint's signing secret: store it now, per environment.GET /api/webhooksnever returns it. To get a new secret, delete the endpoint and register it again.- Endpoints must be HTTPS, with a
urlof at most 512 characters. - Omitting
event_kindssubscribes to every kind, which reads back asnull. To receive only some, see Subscribing to a subset. - Endpoints are per environment. Register in sandbox and live separately, and store the two secrets separately.
GET /api/webhookslists them.DELETE /api/webhooks/{webhook_id}removes one.- The
whk_id is stable, so you can store it against your own records.
Sandbox webhooks are real: delivered and signed exactly like live ones, so the consumer you build against sandbox runs unchanged in live.
Delivery guarantees
| Guarantee | What it means for your code |
|---|---|
| At least once | Deduplicate by event id. A retry reuses the same id |
| Retried with backoff | A non-2xx or a timeout is retried. Slow handlers cause duplicates |
Ordered by sequence, not arrival | Apply events in sequence order to make your projection deterministic |
| Emitted transactionally | You never receive an event for something that rolled back, and never miss one for something that did not |
| Signed | Verify before parsing. See Verifying signatures |
Processing
Verify the signature
Against the raw request body, before parsing it. Reject anything that does not verify, and anything whose timestamp is outside your tolerance window.
Acknowledge fast
Return 2xx as soon as the payload is stored, and process asynchronously. A handler that works before it answers risks a timeout, and a timeout is retried.
Deduplicate by event id
Retries and replays reuse the envelope's id. Keep a processed-ids
table and skip anything you have seen.
Order by sequence
Retries and parallel delivery reorder arrivals, so order by
sequence. It only ever increases, but it is not contiguous: gaps are
normal, so never wait for a missing number.
Treat events as signals, state as truth
An event tells you something changed. For decisions that matter, re-read the resource with a GET rather than acting on a payload that may have been sitting in a retry queue.
Debugging, replay, and downtime
GET /api/webhook_eventsis the event history: everything we emitted, whether delivered or not, newest first. It is the first place to look when a webhook "never arrived": apublished_atofnullmeans it has not gone out yet. See Reading the history for the object.POST /api/webhook_events/{webhook_event_id}/replayre-delivers one event, as many times as you call it. The envelope carries the sameidplus"replayed": true, so your dedupe skips it if you already processed the original.- The dashboard shows the same history and replay under Webhooks.
An endpoint that is down delays events; it does not lose them. Deliveries
retry with backoff, and every event stays in the history. To catch up
after an outage, page through GET /api/webhook_events until you reach
your last processed sequence, or replay the events you missed. For the
full procedure, see Reconciliation.