Webhooks push signed JSON events to your endpoints as things happen — no polling.
Manage endpoints via the API (/v1/webhook-endpoints, scope webhooks:manage)
or in the Customer Portal under
Account Settings → Webhooks, where you can also inspect recent deliveries,
retry failures, and send test events.
Events
Subscriptions accept exact names, * (everything), or prefix wildcards like
order.*.
Payload
Every delivery is a POST with a Stripe-style envelope. data.object matches the
shape the API returns for the same resource:
Headers on every delivery:
Verifying signatures
Each endpoint has a whsec_... signing secret (returned once on creation,
viewable in the portal). The v1 signature is an HMAC-SHA256 of
{timestamp}.{raw request body} using that secret:
Compute the HMAC over the raw request body exactly as received — parsing and
re-serializing the JSON will change the bytes and break verification.
Delivery, retries, and failures
- Respond with any
2xx within 10 seconds. Do heavy processing async.
- Failed deliveries are retried up to 6 times with increasing backoff
(1 minute → 8 hours).
- After 20 consecutive failed deliveries, the endpoint is automatically
disabled. Re-enable it in the portal or via
PUT /v1/webhook-endpoints/{id} with { "disabled": false }.
- Delivery order is not guaranteed. Use the envelope’s
created timestamp,
and fetch the resource from the API when you need its latest state.
- Deliveries may occasionally repeat — deduplicate on the
X-Fortis-Delivery
header.
Endpoint requirements
- HTTPS URLs pointing at publicly reachable hosts.
- Endpoints are managed per app: an API key can only manage its own app’s
endpoints.