You can configure a webhook to receive real-time updates when a scraper job runs.

To enable it, pass a webhook object in your job request.

Webhook delivery is async and retries automatically on failure (3 attempts)

Example

{
  "webhook": {
    "url": "https://yourdomain.com/webhook",
    "events": ["scraper.job.finished", "scraper.data.rows_added"],
    "headers": {
      "x-custom-header": "custom header value"
    }
  }
}

Supported Events

  • scraper.job.started — Sent when the job starts processing
  • scraper.data.rows_added — Sent as data is collected (may trigger multiple times)
  • scraper.job.finished — Sent when the job is complete

Custom Headers

You can pass custom HTTP headers in the headers field. These headers will be included in every webhook request. Use it to include auth tokens or signatures.

Payload

Each webhook event will include:

  • event — Event name
  • jobId — ID of the related job
  • timestamp — ISO timestamp of the event
  • data — Depends on event type (e.g. status, rows, result URL)

Example payload:

{
  "event": "scraper.job.finished",
  "jobId": "abc123",
  "jobStatus": "finished",
  "timestamp": "2025-04-14T12:00:00Z",

  "dataRowsCount": 50,
  "creditsSpent": 500
}
{
  "event": "scraper.data.rows_added",
  "timestamp": "2025-04-11T14:30:00Z",
  "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82",
  "jobStatus": "in_progress",
  "dataRows": [
    {
      "text": "Extracted text here...",
      "statusCode": 200,
      "statusText": "OK",
      "url": "https://hasdata.com/blog",
      "depth": 1,
      "title": "Blog | HasData"
    },
    /*...*/
    {
      "text": "Extracted text here...",
      "statusCode": 200,
      "statusText": "OK",
      "url": "https://hasdata.com/datasets/",
      "depth": 1,
      "title": "Ready-to-use datasets | HasData"
    }
  ],
  "dataRowsCount": 10,
  "creditsSpent": 100
}