Webhooks
Get notified when an async task completes — preferred for Make / Zapier / n8n / Clay.
Async callbacks
task.completed
api_key in query (legacy)
Notes
- Webhooks are optional. If you don’t use them, poll GET /task/{process_id}/status.
- Enable by passing webhook_url in the original async POST request body.
- When your endpoint returns 2xx, the event is acknowledged. Non-2xx triggers retries.
How to enable
- Send any async request (Company / Contact / Apollo / etc.)
- Include webhook_url in the body
- We POST a JSON event when the task completes
- You fetch the result using result_url (or /task/{id}/data)
Example: enable webhook
{
"items": ["ibm", "microsoft"],
"max": 100,
"webhook_url": "https://yourapp.com/webhooks/scrupp"
}
The rest of the body depends on the endpoint. Only webhook_url is common.
Recommended response
HTTP 200 OK
Return 2xx fast. Process async on your side.
What not to do
Don’t do heavy work inside the webhook handler. Store the payload, respond 200, then fetch/process results in background.
Event payload
Sent to your webhook_url when a task completes.
Payload (example)
{
"event": "task.completed",
"process_id": 6666,
"status": "completed",
"result_url": "https://api.scrupp.com/task/6666/data",
"meta": {
"endpoint": "/company/linkedin",
"external_id": "row_9481",
"source": "zapier"
}
}
Always treat meta as optional. It can contain integration-specific values.
Fetch result
GET /task/6666/data?api_key=YOUR_API_KEY
Prefer result_url from the payload if provided. Otherwise build it from process_id.
If failed
{
"event": "task.completed",
"process_id": 6666,
"status": "failed",
"error": "Message (optional)"
}
Retries
If your endpoint is temporarily unavailable, we retry delivery.
Rules
- 2xx = acknowledged
- Non-2xx / timeout = retry with backoff
- Make sure your webhook handler responds within a few seconds
Best practice
Store the payload → respond 200 → fetch result_url and process in background.
Signature verification
Recommended to verify the webhook origin (HMAC).
Headers
X-Scrupp-Signature: sha256=<hex>
X-Scrupp-Timestamp: 1735471800
Signature is computed from timestamp + raw body using your shared secret.
Algorithm (pseudocode)
base = timestamp + "." + raw_body
expected = HMAC_SHA256(secret, base)
compare expected to signature (constant-time)
Where to find your webhook secret
Your webhook signature/secret is the first API key listed on your settings page.
Replay protection
Reject requests with timestamp older than e.g. 5 minutes.
Examples
Plug webhooks into common automation tools.
Make
- Custom webhook → copy URL
- Pass it as webhook_url in POST
- On webhook event → HTTP GET result_url
- Map items → Sheets/CRM
Zapier
- Trigger: Catch Hook
- Use Scrupp async POST with webhook_url
- On webhook → GET result_url
- Looping → create records
n8n / Clay
- Create webhook endpoint
- Pass webhook_url
- Fetch /task/{id}/data
- Store results / enrich further