Overview#
A webhook subscription is the record that ties one of your HTTPS endpoints to the events you want delivered to it. Creating a subscription is also how you receive the signing secret that proves a delivery came from CrossFX. This page covers creating, reading, updating, pausing, rotating, and deleting.Key features#
Event selection per subscription: a subscription receives only the event types it names
Its own signing secret: each subscription is issued its own whsec_ secret, so endpoints are independently verifiable
Pause without deleting: set a subscription to paused while you work on your endpoint, then set it back to active
Rotation on demand: replace a secret you believe is exposed, without recreating the subscription
Per-subscription retry budget: max_retries is set on the subscription, not globally
Use cases#
Register an endpoint during onboarding and capture its signing secret
Run separate endpoints for separate event types, each with its own secret
Pause deliveries during a deploy, then resume them
Rotate a secret after a suspected exposure or on a scheduled cycle
Prerequisites#
An HTTPS endpoint that answers 2xx and processes events idempotently.
The event type codes you want, from the event types endpoint below.
API#
List Webhook Event Types
GET /api/v1/webhooks/event-typesThe event codes you can subscribe to. Read it rather than hard-coding the list.Create Webhook Subscription
POST /api/v1/webhooks/subscriptionsSend endpoint_url and event_type_codes. Returns the subscription and its signing_secret.Get Webhook Subscription
GET /api/v1/webhooks/subscriptions/{subscription_id}Returns the subscription, including status, consecutive_failures, and last_delivery_at. Never the secret.Update Webhook Subscription
PATCH /api/v1/webhooks/subscriptions/{subscription_id}Change endpoint_url, event_type_codes, max_retries, or set status to active or paused.Rotate Webhook Signing Secret
POST /api/v1/webhooks/subscriptions/{subscription_id}/rotate-secretIssues a new signing_secret and returns it.Search Webhook Subscriptions
POST /api/v1/webhooks/subscriptions/searchPaginated search across your subscriptions, filterable by status.Delete Webhook Subscription
DELETE /api/v1/webhooks/subscriptions/{subscription_id}Stops deliveries and frees the slot. Returns the deleted record.Send an endpoint_url and the event_type_codes you want. Returns the subscription, and on create the signing_secret you verify deliveries with.
Business rules#
A new subscription starts in pending_verification and receives nothing. Send PATCH with status set to active before you expect a delivery.
The signing_secret is returned exactly twice: on create, and on rotate. It is never returned by a read, a search, or an update. Store it securely the moment you receive it. If it is lost, rotate to get a new one.
CrossFX generates the secret. You do not supply one. It is whsec_ followed by 64 hexadecimal characters.
Rotation takes effect immediately. Deliveries are signed with the new secret as soon as rotation completes. Only the current secret is accepted on delivery.
event_type_codes must be codes the platform publishes. Read them from the event types endpoint. An unrecognised code is rejected.
An empty event_type_codes list does not mean "everything". On create it is accepted and gives you a subscription that matches no event at all. On update it is ignored rather than treated as a clear, so to stop an event type send the list you do want to keep.
Patching status supports statuses active and paused. The platform manages the other statuses: pending_verification, auto_disabled, and deleted.
A subscription that fails 50 deliveries in a row is auto-disabled. Watch consecutive_failures and last_delivery_at, and set the subscription back to active once your endpoint is healthy.
max_retries defaults to 8 and governs how many attempts follow the first for that subscription.
An organisation may hold up to 10 subscriptions that have not been deleted. A paused or auto_disabled subscription still occupies a slot. Only deleting one frees it.
Deleting is a soft delete, and it is repeatable. The subscription stops receiving deliveries, drops out of search, and comes back with status set to deleted. It stays readable by id, and deleting it again returns another 200 rather than an error.
A subscription you just created is not live yet. It is created in pending_verification, and nothing is delivered to it until you PATCH its status to active.
Errors#
Every error below returns the platform envelope, with error first and error_id last. Quote error_id when you contact support.| HTTP | code | Trigger | What you do |
|---|
| 422 | VALIDATION_FAILED | endpoint_url or event_type_codes is missing, or a code is not a published event type | Read error.json for the field. Take the codes from the event types endpoint. |
| 422 | VALIDATION_FAILED | status is set to a value you do not own | Send active or paused |
| 404 | NOT_FOUND | No subscription matches the id | Check the id, or search for your subscriptions |
| 400 | BAD_REQUEST | The organisation already holds 10 subscriptions that have not been deleted | Delete one you no longer need, then retry. Pausing does not free a slot. |
| 409 | CONFLICT | The organisation already has a subscription on this endpoint_url | Update the existing subscription instead. This body names no field. |
| 401 | | The Authorization header is missing, malformed, or the token has expired | Request a new token and retry. The body is { "message": "Unauthorized" }. |
Webhook Delivery Attempts Guide
Why one delivery to one endpoint failed.Support & Contact
What to send us when deliveries stop arriving.