Webhook notifications
All async endpoints support optional webhook notifications. Instead of polling/job-status/{task_id} to check if your job is complete, you can provide a webhook_url and receive an HTTP POST request when the job finishes.
Supported endpoints
The following async endpoints support webhooks:| Endpoint | Description |
|---|---|
/find-email-async | Single email enrichment |
/find-phone-async | Single phone enrichment |
/find-email-bulk-async | Bulk email enrichment (up to 100 leads) |
/find-phone-bulk-async | Bulk phone enrichment (up to 100 leads) |
/enrich-lead-async | Lead enrichment |
/enrich-company-async | Company enrichment |
/research-agent-async | Research agent |
/qa-agent-async | QA agent evaluation |
Usage
Add the optionalwebhook_url parameter to your async request:
Webhook payload
When your job completes, we send a POST request to your webhook URL with the following JSON payload:Successful job
Failed job
Payload fields
| Field | Type | Description |
|---|---|---|
task_id | string | Unique identifier for the job. |
status | string | Either "completed" or "failed". |
task_type | string | Type of job (e.g., find_email, enrich_lead, find_phone_bulk). |
result | object | Job result data (only present when status is "completed"). |
error | string | Error message (only present when status is "failed"). |
Retry behavior
If your webhook endpoint is unavailable or returns a non-2xx status code, we retry delivery with exponential backoff:- Attempts: Up to 5 retries
- Backoff: 1s, 2s, 4s, 8s, 16s between attempts
- Timeout: 10 seconds per attempt
/job-status/{task_id}.
Best practices
- Return 2xx quickly: Your webhook endpoint should return a 2xx status code within 10 seconds. Process the payload asynchronously if needed.
- Idempotency: Design your webhook handler to be idempotent. While rare, you may receive duplicate deliveries.
- Use HTTPS: We recommend using HTTPS URLs for webhook endpoints to ensure payload security.
-
Validate task_id: Store the
task_idfrom your initial request and validate it matches the webhook payload.
Example: Receiving webhooks
Node.js (Express)
Python (Flask)
Fallback: Polling
Webhooks are optional. You can always fall back to polling/job-status/{task_id} if:
- Your infrastructure doesn’t support incoming webhooks
- Webhook delivery fails
- You need to retrieve results at a later time