Endpoints and events
Recurso pushes events (invoice.paid, subscription.updated, usage.alert.triggered, …)
to HTTP endpoints you register. This guide covers managing those endpoints
through the SDK: creating them, listing them, pausing/resuming, inspecting
delivery attempts, and redelivering an event.
The webhooks surface manages endpoints. Delivery inspection and
redelivery of an event live on the events surface (events /
Events in Node/Go, the redeliver_event and list_event_deliveries
operations in Python), because an event fans out to every subscribed
endpoint.
The signing secret is returned only in the create response. Store it
when you register the endpoint — you cannot fetch it again later. Listing
endpoints omits the secret.
Register an endpoint
Pass the destination URL and the event types to deliver. Fetch the full list of valid event types fromGET /v1/events/types (events.types() in Node,
client.Events.Types(ctx) in Go, list_event_types.sync(...) in Python).
List endpoints
Listing returns every endpoint for the tenant, without the signing secret.Pause and resume
Pausing sets the endpoint toinactive: it stops receiving deliveries but keeps
its secret and configuration, so you can resume without re-registering.
1
Pause
Node and Go expose named helpers; Python sends the status body directly.
2
Resume
recurso.webhooks.delete(id) /
client.Webhooks.Delete(ctx, id) / delete_webhook_endpoint.sync(id, client=client).
Inspect deliveries
Every attempt to reach an endpoint is a delivery record with an attempt count, the last HTTP status code, and the next retry time. List them per endpoint, newest first, filtered by derived status (pending, succeeded,
failed) and paginated with limit/offset.
Redeliver an event
If your handler was down or returned an error, re-enqueue the event to every active subscribed endpoint. Redelivery is keyed on the event ID, not the endpoint, and is idempotent — repeated calls reset the existing delivery records for a fresh attempt rather than creating duplicates. It returns202 with the
count of deliveries queued.
In Python, the redeliver and event-delivery operations live in the
recurso.api.webhooks package (redeliver_event, list_event_deliveries)
even though they act on an event. IDs passed to Python operations are typed as
uuid.UUID — pass a UUID (or a value that stringifies to one).Verifying inbound deliveries
Receiving a webhook is code you write — an HTTP route in your own app that RecursoPOSTs to. None of the three SDKs ship an inbound-signature helper or a
server; the webhooks/events surfaces only manage endpoints. Verify
signatures yourself:
1
Read the raw request body
Compute the signature over the exact bytes Recurso sent. Do not
re-serialize a parsed JSON object — key order or whitespace changes break the
HMAC. Capture the raw body before any JSON middleware touches it.
2
Recompute the HMAC with the endpoint's signing secret
Recurso signs each delivery with an HMAC keyed by the signing secret
returned when you created the endpoint (the
whsec_… value). Recompute the
HMAC-SHA256 of the raw body with that secret.3
Compare in constant time
Compare your computed digest against the signature header on the request
using a constant-time comparison (
crypto.timingSafeEqual in Node,
hmac.Equal in Go, hmac.compare_digest in Python) to avoid timing leaks.
Reject the request on any mismatch.Related
- Errors & retries — handling failures, idempotency, and pagination
- Usage-based billing — the events that fire
usage.alert.triggered - SDK overview — install and configure each client
- Node guide · Go guide · Python guide