Webhooks
Receive real-time notifications when jobs complete or fail, instead of polling.
Overview
Webhooks let your application receive push notifications from DocuHub as events happen. Instead of repeatedly polling the /v1/jobs endpoint to check whether a conversion has finished, you register a URL and DocuHub sends an HTTP POST request to it the moment the job completes or fails.
This is faster, more efficient, and reduces unnecessary API calls against your rate limit.
Supported Events
DocuHub currently delivers the following event types:
| Event | Description |
|---|---|
| job.completed | Fired when an async job finishes successfully. Includes the download URL and processing duration. |
| job.failed | Fired when an async job fails after all retry attempts are exhausted. Includes the error code and message. |
Payload Format
Every webhook delivery is an HTTP POST request with a JSON body. Here is an example for a job.completed event:
{
"id": "evt_abc123_x7k2m9",
"type": "job.completed",
"created_at": "2026-02-18T10:00:01Z",
"data": {
"job_id": "job_xyz789",
"type": "convert",
"status": "completed",
"download_url": "https://api.docuhub.live/v1/files/xyz789",
"expires_at": "2026-02-19T10:00:01Z",
"processing_ms": 1234
}
}The id field is unique per delivery attempt and can be used for idempotency. The data object varies by event type but always contains the job_id and status.
Setup Guide
Configure webhooks from the Developer Dashboard in three steps:
- 1Navigate to Developer Dashboard → Apps and select the app you want to configure.
- 2In the Webhooks section, enter your endpoint URL (must be HTTPS) and select the events you want to subscribe to.
- 3Copy the signing secret displayed after saving. You will use this to verify webhook signatures.
Signature Verification
Every webhook request includes an X-DocuHub-Signature header containing an HMAC-SHA256 signature of the raw request body. Always verify this signature before processing the payload to ensure the request originated from DocuHub and was not tampered with.
JavaScript / Node.js
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Python
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)timingSafeEqual or compare_digest) to prevent timing attacks.Retry Policy
If your endpoint does not return a 2xx status code, DocuHub retries the delivery up to 3 times with exponential backoff. After the final attempt, the event is marked as failed and can be reviewed in the Developer Dashboard.
| Attempt | Delay After Failure | Cumulative Time |
|---|---|---|
| 1 | 1 minute | 1 minute |
| 2 | 5 minutes | 6 minutes |
| 3 | 30 minutes | 36 minutes |
Best Practices
- Respond with 2xx quickly. Return an HTTP 200 status as soon as you receive the request. Process the event asynchronously in a background worker or queue.
- Process events asynchronously. Avoid doing heavy work (file downloads, database writes) inside your webhook handler. Push events onto a queue and process them separately.
- Verify signatures. Always validate the
X-DocuHub-Signatureheader to ensure the request is authentic. - Handle duplicate deliveries. Use the event
idfield to deduplicate. In rare cases (network timeouts), the same event may be delivered more than once.
Next steps
- Follow the Quick Start guide to make your first API call
- Review error codes your endpoint may encounter
- Learn about authentication & scopes