Skip to main content
This walkthrough registers a webhook endpoint for your organization, lists and deletes endpoints, and shows how to verify a signed delivery on your server. Every call here runs from your server with your org_ API key. A partner admin session token also works (see Admin session tokens).
4D does not send webhook deliveries yet. You can register, list and delete endpoints today, and they are kept, but no event is posted to them. Until delivery is switched on, use Read recent events to pull events. The delivery format below is the one 4D signs with, so you can build and test your receiver against it now.

1. Register an endpoint

The event names are stored as you send them. They are not checked against a catalog, so a misspelled name is accepted and never matches anything. To see the event types your organization produces, and their exact spelling, call the refetch call without a filter. 201 Created:
The secret is in this response only. Store it in your secret manager now: no later call returns it, and 4D keeps only an encrypted copy that it uses to sign deliveries. A body that fails validation, including a url that is not https, answers 422 with code VALIDATION_ERROR and the field problems under details.

2. List and delete endpoints

GET /v1/webhooks lists your organization’s endpoints, oldest first. The list never includes the secret.
DELETE /v1/webhooks/{id} removes one:
An id that is not one of your organization’s endpoints answers 404 with code NOT_FOUND. There is no call to change an endpoint, read its secret again or rotate the secret. To change the URL, the events or the secret, register a new endpoint, move your receiver to the new secret, then delete the old endpoint.

3. Verify a delivery

A delivery is a POST to your url with a JSON body and these headers: The signature is HMAC-SHA256, keyed with your endpoint’s secret, over the timestamp, a period and the exact raw request body: `${t}.${rawBody}`, hex-encoded. Each attempt is signed at the moment it is sent, so t is always recent. To verify, on every request:
  1. Read the raw body as bytes, before any JSON parsing. A re-serialised body does not match.
  2. Parse t and every v1 (and v0, if present) out of X-4D-Signature. A v0 entry carries a signature made with a previous secret; accept the request if either matches.
  3. Reject a t more than 300 seconds away from your clock.
  4. Compute the HMAC and compare it in constant time.
Deduplicate on X-4D-Event-Id, not on X-4D-Delivery-Id. A retried delivery carries the same event id and a new delivery id, so an event can reach you more than once.

Retries and what counts as success

Any 2xx response is a success. Anything else, including a network error, is a failure, and 4D tries again. An event gets seven attempts in all: the first, then retries after 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours and 24 hours, about 40 hours end to end. After the seventh failure the event is not sent to that endpoint again. There is no call to redeliver a failed event. Use the refetch call below to recover anything your endpoint missed. Answer quickly and do the work afterwards: return 2xx once the signature checks out and the event is safely queued on your side.

4. Refetch recent events

To pull events instead of waiting for them, or to catch up after downtime, use Read recent events. It returns your organization’s events from the last 30 days.