Notifications V5 (beta)

Read, change and test the webhook address of a bot.

A finished collection is announced to the webhook address. It applies to every collection, manual or by plan, and works even for accounts where multiple plans are not open.

Endpoints

  • GET /v5/api/bots/{bot_id}/notifications Webhook settings and the last delivery result
  • PUT /v5/api/bots/{bot_id}/notifications Set or remove the webhook address
  • POST /v5/api/bots/{bot_id}/notifications/test Send a test delivery

Read

FieldDescription
webhook_url, webhook_enabledThe webhook address and whether it is on.
webhook_token_setWhether a signing token exists. The token value is never returned.
last_deliveryThe last delivery { kind, status, http_status, at } (kind is real, test and so on; the body and signature are not returned), or null.
Example request
curl 'https://www.hashscraper.com/v5/api/bots/8f3a7c1e9b5d24f6/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Example response 200
{
  "result": "success",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "elapsed_sec": 0.0123,
  "data": {
    "bot_id": "8f3a7c1e9b5d24f6",
    "webhook_url": "https://example.com/hooks/hashscraper",
    "webhook_enabled": true,
    "webhook_token_set": true,
    "last_delivery": {
      "kind": "real",
      "status": "success",
      "http_status": 200,
      "at": "2026-09-28T09:01:38+09:00"
    }
  }
}

Set or remove the address

Send an http:// or https:// address (no spaces, 255 characters at most) in webhook_url to set it, or null to remove it. If the account has no webhook token yet, one is created the same way as on screen. Internal and private addresses cannot be used.

Example request
curl -X PUT 'https://www.hashscraper.com/v5/api/bots/8f3a7c1e9b5d24f6/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{
  "webhook_url": "https://example.com/hooks/hashscraper"
}'
Example request
curl -X PUT 'https://www.hashscraper.com/v5/api/bots/8f3a7c1e9b5d24f6/notifications' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{
  "webhook_url": null
}'

Test delivery

The same as "Send to check" on screen. Without an address it is 422 WEBHOOK_NOT_SET. Even if the receiver fails the test itself has completed, so you get 200 and the outcome in data.success (with the reason in error when no response arrived). An idempotency key is not required.

Example request
curl -X POST 'https://www.hashscraper.com/v5/api/bots/8f3a7c1e9b5d24f6/notifications/test' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H "Idempotency-Key: $(uuidgen)"
Example response 200
{
  "result": "success",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "elapsed_sec": 0.0123,
  "data": {
    "bot_id": "8f3a7c1e9b5d24f6",
    "success": true,
    "http_status": 200,
    "timed_out": false,
    "elapsed_ms": 184,
    "error": null
  }
}

Fields added to the webhook body

The existing fields of the webhook body keep their names, values and order, and three fields were added after them. They are included by default in every webhook, manual or by plan.

  • trigger — manual, api, period, period_manual or excel.
  • plan — { id, name, label, scheduled_at } when a plan started it, or null when manual.
  • inputs — the conditions used for that collection { param1: { name, value } } (the same shape as the v5 inputs definition).

The X-HashScraper-Version header stays 1.0, and the signature (X-Webhook-Signature) is computed over the body actually sent, so your verification still passes. A bot with several plans sends a webhook per plan, so tell them apart with plan.

plan.id in the webhook is a number, while a plan id in v5 API responses is a string ("512"). Convert when you compare.

Webhook body (new fields)
{
  "schedule_id": 4821,
  "schedule_slug": "sample-shopping-bot",
  "schedule_name": "Sample shopping bot",
  "schedule_result_id": 239758028,
  "data_count": 1280,
  "completed_at": "2026-09-28T09:01:37.000+09:00",
  "job_start_time": "2026-09-28T09:00:03.000+09:00",
  "last_result_id": 90998721,
  "status": "completed",
  "trigger": "period",
  "plan": {
    "id": 512,
    "name": "주기 2",
    "label": "매주 월요일 09:00 (KST)",
    "scheduled_at": "2026-09-28T09:00:00+09:00"
  },
  "inputs": {
    "param1": {
      "name": "Keyword",
      "value": "sneakers"
    }
  },
  "empty_reason": null
}

Related guides