Skip to content

Webhooks

Async tasks can notify you (or push the full result) on completion instead of being polled. Configure webhooks with the webhook block at enqueue.

{
"keyword": "electric cars",
"location": { "code": 2840 },
"language": { "code": "en" },
"format": "advanced",
"webhook": {
"ready_url": "https://example.com/hooks/ready?id=$id&tag=$tag",
"result_url": "https://example.com/hooks/result?id=$id",
"result_format": "advanced"
}
}
FieldMethodPayload
ready_urlGETNo body — a ping telling you the task is ready to fetch.
result_urlPOSTThe full native envelope for the completed task.
result_formatstandard | advanced | html for the result_url payload (defaults to the task’s format).

Both URLs support literal placeholders that Serplify substitutes:

  • $id — the task id.
  • $tag — the request tag (empty if none).

The POST body is the same native envelope you’d get from GET /v1/serp/tasks/{id}:

{
"request_id": "req_…",
"status": "ok",
"meta": { "api_version": "0.1.0", "time": 0, "cost": 0, "currency": "USD" },
"data": { "keyword": "electric cars", "search_engine": "google", "items": [ /* … */ ] }
}
  • Webhooks are best-effort with retries — a delivery that returns non-2xx or times out is retried with backoff.
  • Respond quickly with a 2xx; do heavy processing asynchronously on your side.
  • Webhooks never affect task billing or state — a failed webhook does not fail the task, and the result remains fetchable via GET /v1/serp/tasks/{id}.
  • Treat ready_url/result_url as best-effort signals and reconcile with a periodic GET /v1/serp/tasks sweep if you need exactly-once guarantees.