1. Webhooks
CrossFX Payment APIs
  • Guides
    • CrossFX API Documentation
    • Support & Contact
    • API Basics
    • Authentication Guide
    • FX Rates
      • FX Rates Guide
    • Corridors
      • Supported Corridors Guide
    • Banks
      • Fetching Banks List Guide
      • Fetching Bank Branches Guide
    • Sanctions
      • Sanctions Screening Guide
    • Beneficiaries
      • Create Beneficiary Guide
      • Get Beneficiary Guide
    • Transfers
      • Generate Quote Guide
      • Confirm Transfer Guide
      • Get Transfer Status Guide
    • Crypto Deposit Address
      • Crypto Deposit Address Guide
    • Payments
      • Initiate Deposit Guide
      • Initiate Payout Guide
    • Webhooks
      • Webhooks Guide
      • Webhook Subscriptions Guide
      • Webhook Events Guide
      • Webhook Delivery Attempts Guide
    • Sandbox
      • Sandbox Data & Testing Guide
  1. Webhooks

Webhook Subscriptions Guide


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#

A valid bearer token. See the Authentication Guide.
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-types
The event codes you can subscribe to. Read it rather than hard-coding the list.
Create Webhook Subscription
POST /api/v1/webhooks/subscriptions
Send 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-secret
Issues a new signing_secret and returns it.
Search Webhook Subscriptions
POST /api/v1/webhooks/subscriptions/search
Paginated 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.
NOTE
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.
WARNING
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.
HTTPcodeTriggerWhat you do
422VALIDATION_FAILEDendpoint_url or event_type_codes is missing, or a code is not a published event typeRead error.json for the field. Take the codes from the event types endpoint.
422VALIDATION_FAILEDstatus is set to a value you do not ownSend active or paused
404NOT_FOUNDNo subscription matches the idCheck the id, or search for your subscriptions
400BAD_REQUESTThe organisation already holds 10 subscriptions that have not been deletedDelete one you no longer need, then retry. Pausing does not free a slot.
409CONFLICTThe organisation already has a subscription on this endpoint_urlUpdate the existing subscription instead. This body names no field.
401The Authorization header is missing, malformed, or the token has expiredRequest a new token and retry. The body is { "message": "Unauthorized" }.

Related#

Webhook Delivery Attempts Guide
Why one delivery to one endpoint failed.
Support & Contact
What to send us when deliveries stop arriving.
Modified at 2026-09-08 10:31:44
Previous
Webhooks Guide
Next
Webhook Events Guide
Built with