Apify Webhooks Guide 2026: Run Events, Payloads & Automation
Webhooks fire when Actor runs change state. Use them instead of polling: get an HTTP POST when a run succeeds, fails, or times out. Wire runs to Slack, Make.com, or your own API. Create webhooks in Apify Console under Actor → Integrations → Webhooks.
When to use webhooks
- Run Actors on schedule and trigger downstream work (notify Slack, update DB)
- Push results into CRM, warehouse, or custom APIs
- Build event-driven pipelines instead of polling run status every few seconds
Event types
From the Apify webhook events docs:
| Event | When it fires |
|---|---|
ACTOR.RUN.CREATED | New run started |
ACTOR.RUN.SUCCEEDED | Run finished successfully |
ACTOR.RUN.FAILED | Run finished with failure |
ACTOR.RUN.ABORTED | Run was aborted |
ACTOR.RUN.TIMED_OUT | Run exceeded time limit |
ACTOR.RUN.RESURRECTED | Run was resurrected |
Attach webhooks to an Actor (all runs) or to a specific task (only runs for that task).
Payload structure
Default payload for ACTOR.RUN.SUCCEEDED:
{
"userId": "abf6vtB2nvQZ4nJzo",
"createdAt": "2019-01-09T15:59:56.408Z",
"eventType": "ACTOR.RUN.SUCCEEDED",
"eventData": {
"actorId": "fW4MyDhgwtMLrB987",
"actorTaskId": "abc123",
"actorRunId": "uPBN9qaKd2iLs5naZ"
},
"resource": {
"id": "uPBN9qaKd2iLs5naZ",
"actId": "fW4MyDhgwtMLrB987",
"userId": "abf6vtB2nvQZ4nJzo",
"startedAt": "2019-01-09T15:59:40.750Z",
"finishedAt": "2019-01-09T15:59:56.408Z",
"status": "SUCCEEDED"
}
}
Use actorRunId (or resource.id) to fetch results:
GET https://api.apify.com/v2/actor-runs/%7BactorRunId%7D/dataset/items?token=%7Btoken%7D&fpr=use-apify
Authentication
Add a secret token to the webhook URL or in a header so only Apify can invoke it:
https://your-endpoint.com/webhook?token=your-secret
Or use the Headers template in the webhook config:
{
"X-Webhook-Token": "{{userId}}"
}
Validate the token in your handler before processing. If the URL points to an Apify endpoint, Apify adds the token automatically.
Retry logic
Apify retries on non-2xx responses with exponential backoff:
- 1 min, 2 min, 4 min, … up to ~11 retries (~32 hours)
- 30-second timeout per request
- After 11 failures, delivery stops
Return 2xx quickly. Queue heavy work (e.g. ETL, Slack API calls) and process asynchronously.
Creating a webhook
- Go to Apify Console → Actor → Integrations → Webhooks
- Add webhook → choose event(s): e.g.
ACTOR.RUN.SUCCEEDED,ACTOR.RUN.FAILED - Set URL (include token for auth)
- Optionally customize payload with
{{resource.id}},{{eventData.actorRunId}}, etc. - Save and test with the Test button
Use cases
Slack notification on success
// Webhook handler (Node.js example)
app.post('/apify-webhook', (req, res) => {
res.status(200).send(); // Reply fast
const { eventType, eventData, resource } = req.body;
if (eventType === 'ACTOR.RUN.SUCCEEDED') {
notifySlack(`Run ${eventData.actorRunId} finished. Fetch dataset via API.`);
}
});
Trigger Make.com scenario
Make.com has a built-in webhook module. Create a scenario with Webhooks → Custom Webhook. Use the provided URL as your Apify webhook target. Map eventData.actorRunId to downstream modules (e.g. Apify "Get run" to fetch dataset). See Make + Apify integration.
Idempotency
Use actorRunId + eventType as a unique key. Check if you have already processed this event (DB, Redis). If yes, return 200 and skip. Avoid duplicate Slack posts or DB writes.
Debugging
- Test button: Use it in the webhook config to send a sample payload
- Logs: Inspect your endpoint logs for status codes and body
- Firewall: Apify uses fixed IPs; allow them if your endpoint is behind a firewall. List of IPs
- Payload: Use a custom payload template to reduce payload size or reshape for your system
Create one webhook for ACTOR.RUN.SUCCEEDED on your busiest Actor. Point it to a test endpoint and verify the payload. Configure webhooks →
They trigger HTTP POST requests when Actor run events occur (e.g. SUCCEEDED, FAILED). Use them to notify Slack, trigger Make.com, or push results to your API without polling.
Yes. Create a webhook for ACTOR.RUN.SUCCEEDED. Your endpoint receives the payload with actorRunId. Use the Apify API to fetch the dataset, then process and store results.
Use actorRunId + eventType as an idempotency key. Check if the event was already handled before processing. Return 200 quickly and process async if needed.
Return 200 immediately. Queue the work (e.g. SQS, Redis) and process in a background worker. Apify times out after 30 seconds and retries on non-2xx.




