Skip to main content

Overview

Webhooks allow you to receive real-time HTTP notifications when your inference jobs change status, eliminating the need to poll the /api/v2/jobs/{id} endpoint.
Webhooks are sent as POST requests to your specified URL with a JSON payload and security headers for verification.

Configuration

Global Webhook URL

Configure a global webhook URL in your account settings. All jobs will send notifications to this URL unless overridden.

Per-Request Override

You can override the global webhook URL on any job request by including the webhook_url parameter. Optionally, you can also pass a webhook_secret to sign the callback for that specific job with a job-scoped secret instead of your account’s default:
Only HTTPS URLs are accepted. HTTP URLs will be rejected for security. webhook_secret must always be sent together with webhook_url — it cannot be used to override the secret for the globally configured URL.
When webhook_secret is provided, every callback for that job (including retries) is signed with it instead of your account’s default secret. Use this when you want to scope a secret to a specific job — for example per-tenant secrets, short-lived tokens, or delivering to a different receiver than your global endpoint. Make sure the receiver verifying the signature uses the same per-job secret.

Events

Webhooks are sent on the following status transitions:

Request Format

Headers

All webhook requests include these headers:

Payload Structure

Sent when a worker starts processing your job.

Security

Signature Verification

Every webhook includes an HMAC-SHA256 signature in the X-DeAPI-Signature header. Always verify this signature to ensure the request came from deAPI.
If you supplied a webhook_secret in the original job request, every callback for that job (including all retries) is signed with that secret. Otherwise, the signature uses the global webhook secret from your account settings. Your verification code must use whichever secret you sent for that job — typically by looking it up from data.job_request_id in your own store.
Signature format: sha256=<hex-encoded-hmac> How to verify:
  1. Get the timestamp from X-DeAPI-Timestamp header
  2. Get the raw JSON body (don’t parse it first)
  3. Concatenate: timestamp + "." + raw_body
  4. Calculate HMAC-SHA256 using your webhook secret
  5. Compare with the signature (use timing-safe comparison)

Best Practices

Always verify signatures

Never process webhooks without verifying the HMAC signature first.

Check timestamps

Reject webhooks with timestamps older than 5 minutes to prevent replay attacks.

Use HTTPS

Only configure HTTPS endpoints. HTTP is rejected automatically.

Handle idempotency

Use delivery_id to detect and handle duplicate deliveries.

Retry Policy

If your endpoint fails to respond with a 2xx status code, we’ll retry delivery with exponential backoff: After 10 failed attempts (~24 hours), the webhook is marked as failed.
Circuit Breaker: After 10 consecutive failed deliveries across any webhooks for your account, webhooks are automatically disabled. Re-enable them in your account settings after fixing your endpoint.

Response Requirements

Your endpoint should:
  • Return a 2xx status code (200-299) within 10 seconds
  • Not follow redirects (3xx responses are treated as failures)
  • Process the webhook asynchronously if needed (respond quickly, process later)

Testing

Use webhook.site to test webhooks during development:
  1. Get a unique URL from webhook.site
  2. Configure it as your webhook URL (per-request or global)
  3. Submit a job and watch the webhooks arrive
  4. Verify headers and payloads match the expected format
You can also use tools like ngrok to expose your local development server to receive webhooks.