Overview
Webhooks let you receive real-time notifications when asset processing finishes. Instead of polling the submission status endpoint, your system is notified via HTTPS POST as soon as an event occurs.How webhooks work
1
Create a subscription
Register an HTTPS endpoint URL and the event types you want to receive. The API returns a signing
secret.2
Receive deliveries
When an asset finishes processing, the API sends a signed POST to your endpoint.
3
Verify and acknowledge
Verify the signature, respond quickly with a 2xx, and process asynchronously.
4
Fetch detail
The payload does not embed results. Fetch the asset detail, issues, or topics from the REST API.
Event types
Only two event types exist.Creating a webhook subscription
POST/api/webhooks/subscriptions
The request uses endpointUrl (HTTPS required), eventTypes, and an optional description.
201 Created. The secret is returned only on create:
422 is returned for a non-HTTPS URL or when the workspace reaches its subscription limit.
Webhook delivery payload
When an event occurs, the API sends a Standard Webhooks envelope to your endpoint. The outer fields areid, type, timestamp, and data. The data object is snake_case.
data.external_reference echoes verbatim the structured reference you supplied when creating the submission. It is present only when the submission was created with an externalReference (otherwise the key is omitted), and lets an integration correlate the completion back to the originating work item without keeping its own mapping. The same optional field appears on asset.processing.failed deliveries.
A failure delivery uses the same envelope with data.status set to "failed", an added data.error_message, and data.is_retryable (whether the asset can be retried):
The payload does not embed results. To get issues, topics, or full asset detail, fetch them from the REST API:
GET /api/submissions/{submission_id}/assets/{asset_id}, its /issues, or its /topics. See Assets.Verifying webhook signatures
Deliveries are signed using the Standard Webhooks format. Always verify the signature using your subscriptionsecret. After verification, read the event type from event["type"].
Handling webhooks
Your endpoint should:- Verify the signature (see above).
- Respond quickly — return a 2xx immediately, then process in the background.
- Process idempotently — handle the same event
idbeing delivered more than once. - Fetch detail — load issues or topics from the REST API as needed.
Delivery and retries
Webhook delivery is handled by a delivery provider. If your endpoint returns a non-2xx status, the delivery is retried automatically. Review attempt history through the deliveries endpoint or in the control plane rather than relying on a fixed retry schedule. GET/api/webhooks/subscriptions/{subscription_id}/deliveries
Query parameters: status (optional filter) and limit (1–200, default 50).
Testing webhooks
Using ngrok
For local testing, expose your local server publicly:https://abc123.ngrok.io. Create a subscription pointing to it.
Managing subscriptions
List subscriptions
GET/api/webhooks/subscriptions
Returns a paginated envelope. The secret is never included after create.
page (≥1), pageSize (1–100), sortBy (endpoint_url | created_at | updated_at), sortOrder (asc | desc), enabled (bool), and search.
Get a subscription
GET/api/webhooks/subscriptions/{subscription_id}
Returns a single subscription (without secret).
Update a subscription
PATCH/api/webhooks/subscriptions/{subscription_id}
Only enabling or disabling is supported:
Delete a subscription
DELETE/api/webhooks/subscriptions/{subscription_id}
Returns 204 No Content.
Webhook best practices
- Verify signatures — always validate the signature using your subscription
secret. - Respond quickly — return a 2xx promptly and process asynchronously.
- Process idempotently — handle duplicate event IDs gracefully.
- Fetch detail on demand — the payload does not embed results; load them from the REST API.
- Store the secret securely — keep it in environment variables or a secret manager.