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 thewebhook_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:
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_url | string (HTTPS) | No | Overrides the global webhook URL for this job only. |
webhook_secret | string (32–255) | No | Overrides the global webhook secret for this job only. Used to compute the X-DeAPI-Signature HMAC-SHA256. Must be sent together with webhook_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:| Event | Trigger | Description |
|---|---|---|
job.processing | pending → processing | Job assigned to a worker, processing started |
job.completed | processing → done | Job completed successfully, results available |
job.failed | processing → error | Job failed during processing |
Request Format
Headers
All webhook requests include these headers:| Header | Description | Example |
|---|---|---|
X-DeAPI-Signature | HMAC-SHA256 signature for verification | sha256=5d41402abc4b2a76b9719d911017c592... |
X-DeAPI-Timestamp | Unix timestamp when webhook was sent | 1705315800 |
X-DeAPI-Event | Event type that triggered the webhook | job.completed |
X-DeAPI-Delivery-Id | Unique identifier for this delivery | 550e8400-e29b-41d4-a716-446655440001 |
Content-Type | Always application/json | application/json |
User-Agent | Identifies the sender | DeAPI-Webhook/1.0 |
Payload Structure
- job.processing
- job.completed
- job.failed
Sent when a worker starts processing your job.
| Field | Type | Description |
|---|---|---|
data.job_request_id | string (UUID) | Your job’s unique identifier |
data.status | string | Current status: processing |
data.previous_status | string | Previous status: pending |
data.job_type | string | Type of job (e.g., image_generation, video_upscale, transcription) |
data.started_at | string (ISO 8601) | When processing began |
Security
Signature Verification
Every webhook includes an HMAC-SHA256 signature in theX-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.sha256=<hex-encoded-hmac>
How to verify:
- Get the timestamp from
X-DeAPI-Timestampheader - Get the raw JSON body (don’t parse it first)
- Concatenate:
timestamp + "." + raw_body - Calculate HMAC-SHA256 using your webhook secret
- 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 a2xx status code, we’ll retry delivery with exponential backoff:
| Attempt | Delay | Cumulative Time |
|---|---|---|
| 1 | Immediate | 0 |
| 2 | 1 minute | 1 min |
| 3 | 2 minutes | 3 min |
| 4 | 5 minutes | 8 min |
| 5 | 10 minutes | 18 min |
| 6 | 30 minutes | 48 min |
| 7 | 1 hour | 1h 48min |
| 8 | 3 hours | 4h 48min |
| 9 | 6 hours | 10h 48min |
| 10 | 12 hours | 22h 48min |
Response Requirements
Your endpoint should:- Return a
2xxstatus 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:- Get a unique URL from webhook.site
- Configure it as your webhook URL (per-request or global)
- Submit a job and watch the webhooks arrive
- Verify headers and payloads match the expected format