Skip to main content

Apify Webhooks Guide 2026: Run Events, Payloads & Automation

· 4 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

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:

EventWhen it fires
ACTOR.RUN.CREATEDNew run started
ACTOR.RUN.SUCCEEDEDRun finished successfully
ACTOR.RUN.FAILEDRun finished with failure
ACTOR.RUN.ABORTEDRun was aborted
ACTOR.RUN.TIMED_OUTRun exceeded time limit
ACTOR.RUN.RESURRECTEDRun 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

  1. Go to Apify Console → Actor → Integrations → Webhooks
  2. Add webhook → choose event(s): e.g. ACTOR.RUN.SUCCEEDED, ACTOR.RUN.FAILED
  3. Set URL (include token for auth)
  4. Optionally customize payload with {{resource.id}}, {{eventData.actorRunId}}, etc.
  5. 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

  1. Test button: Use it in the webhook config to send a sample payload
  2. Logs: Inspect your endpoint logs for status codes and body
  3. Firewall: Apify uses fixed IPs; allow them if your endpoint is behind a firewall. List of IPs
  4. Payload: Use a custom payload template to reduce payload size or reshape for your system
Apify Affiliate Banner 728x90Apify Affiliate Banner 728x90Apify Affiliate Banner 300x50Apify Affiliate Banner 300x50
Next step

Create one webhook for ACTOR.RUN.SUCCEEDED on your busiest Actor. Point it to a test endpoint and verify the payload. Configure webhooks →

Frequently Asked Questions

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.

Common mistakes and fixes

Webhook not firing

Check event type (ACTOR.RUN.SUCCEEDED vs ACTOR.RUN.CREATED). Ensure URL returns 2xx. Verify webhook is attached to the correct Actor or task.

Duplicate webhook deliveries

Design handler for idempotency. Use runId + eventType as unique key. Skip if already processed.