Skip to main content
A webhook is a URL you register so Natural can push Events to your server as they happen, instead of you polling for changes. When a payment completes, a deposit lands, or a customer connects, Natural sends the event to your URL. Each webhook subscribes to the event types you choose, every delivery is signed with the webhook’s secret so you can verify it came from Natural, and failed deliveries are retried. Natural signs every delivery with the Standard Webhooks spec; verify it before trusting the payload. See the Event catalog for every event type and its full payload.

1. Register an endpoint

POST /webhooks registers your URL and subscribes it to event types. The signing secret is returned once in the response; store it immediately.
enabledEvents accepts any event type from the Event catalog, or the wildcard "*" (which must be the only entry). description and tags are optional.
The signingSecret (whsec_...) appears only in this response. If you lose it, rotate it with POST /webhooks/{webhookId} /rotate-secret.

2. Verify the signature

Every delivery is a POST whose JSON body is the event object. Three signature headers ride on each delivery (lowercase, per the Standard Webhooks spec): Always verify before trusting a payload. Use the official standardwebhooks library (Python and Node); construct it with your whsec_ secret and pass the raw body plus headers. verify returns the parsed event, or raises on a bad signature:
Verify against the raw request body, the exact bytes Natural sent. Parsing and re-serializing the JSON first changes the bytes and breaks verification.
The library handles two details for you: it rejects deliveries whose webhook-timestamp is outside a tolerance window (replay defense), and it accepts a delivery if any of the space-separated signatures verifies, which is what lets a secret rotation overlap two valid secrets.
The signed content is the string {webhook-id}.{webhook-timestamp}.{body}. Strip the whsec_ prefix from the secret, base64-decode the remainder for the HMAC key, compute HMAC-SHA256, and base64-encode the result. Compare it against each space-separated v1,<sig> entry.

3. Delivery, retries & failures

Natural treats any 2xx response as success. The delivery request times out after 30 seconds. Failed deliveries (non-2xx, network error, or timeout) are retried up to 7 attempts total with jittered backoff (~20% jitter):
An endpoint that fails every attempt for 5 consecutive events is automatically disabled. Re-enable it with PATCH /webhooks/{webhookId} once your endpoint is healthy.

Best practices

  • Return 2xx fast. Acknowledge as soon as the signature verifies, then process the event asynchronously; slow handlers risk the 30-second timeout and trigger retries.
  • Deduplicate on webhook-id. Retries reuse the same webhook-id, and Natural may deliver an event more than once; record processed IDs and skip duplicates.
  • Store the whsec_ secret in a secrets manager, never in source control. Rotate it with POST /webhooks/{webhookId}/rotate-secret; the previous secret stays valid for the grace period you specify, so both signatures arrive during the overlap.
  • Don’t depend on event ordering. Retries and independent delivery mean events can arrive out of order; use the version field on the resource snapshot, or refetch the resource, when ordering matters.