Handle webhooks
Webhooks notify your server about events on the Apify platform, such as an Actor run that finished successfully. The notification carries the run object, including the ID of its default dataset, so your server can process the results as soon as they're ready.
Create a webhook
To create a webhook, call create() on the webhook collection client. The condition selects the Actor whose runs trigger the webhook, and eventTypes the events it reacts to:
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'MY-APIFY-TOKEN' });
await client.webhooks().create({
description: 'Instagram hashtag Actor succeeded',
// The Actor ID of apify/instagram-hashtag-scraper.
condition: { actorId: 'reGe1ST3OBgYZSsZJ' },
// Generate a request URL at https://webhook.site, or point it at any REST server.
requestUrl: 'https://webhook.site/CUSTOM_WEBHOOK_ID',
eventTypes: ['ACTOR.RUN.SUCCEEDED'],
});
Receive the notifications
The server that receives the notifications can be any HTTP server. This example uses Express, so install it alongside the client:
npm i apify-client express
The server reads the dataset ID from the payload and saves the run's items to a local file:
import { writeFile } from 'node:fs/promises';
import { ApifyClient, DownloadItemsFormat } from 'apify-client';
import express from 'express';
const client = new ApifyClient({ token: 'MY-APIFY-TOKEN' });
const app = express();
const PORT = 3000;
// Parse the JSON payload the webhook sends.
app.use(express.json());
app.post('/apify-webhook', async (req, res) => {
// The default payload carries the run object in `resource`.
const { defaultDatasetId } = req.body.resource;
// Save the run's dataset locally as JSON.
const items = await client.dataset(defaultDatasetId).downloadItems(DownloadItemsFormat.JSON);
await writeFile(`${defaultDatasetId}.json`, items);
// Respond to the webhook.
res.send('Webhook received');
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));