Results pushed to you, not polled.
Add an endpoint once and every job in the workspace reports back when it ends. The same endpoints warn you before your credits run out.
You'll need a workspace with Trawl enabled and an API key that can read and manage Trawl webhooks (trawl.webhook.read, trawl.webhook.manage); 01 · Foundations covers both. If you haven't run a job yet, do 02 · Your first extraction first.
1
The three events
Webhooks belong to the workspace: an endpoint receives the events it subscribes to from every job in it.
job.succeeded— a job finished and its result matches your JSON Schema. The result is indata.job.result.job.failed— a job stopped without a result: the page did not load, it ran out of steps or time, or the result did not match your schema. The reason is indata.job.error. A cancelled job sends nothing.credits.low— your balance dropped below 10% of your last top-up (at least 100 steps). Sent once, and again only after your next top-up. Section 4 has the details.
The webhook is a notification, not the record. The result also stays on the job (GET /v1/workspaces/:workspace_id/jobs/:id), so a missed delivery never loses data. The list of events, with a description and an example payload for each, is served by the API:
curl https://api.trawl.productcraft.co/v1/workspaces/<workspace_id>/webhooks/event-types \
-H 'authorization: Bearer pcft_live_...'2
Add an endpoint
From the console (Trawl → Webhooks) or the API. Endpoints, signatures, tests, retries and replay work the same in every ProductCraft product.
curl -X POST https://api.trawl.productcraft.co/v1/workspaces/<workspace_id>/webhooks/endpoints \
-H 'authorization: Bearer pcft_live_...' \
-H 'idempotency-key: add-results-endpoint-1' \
-H 'content-type: application/json' \
-d '{
"url": "https://hooks.acme.com/webhooks/trawl",
"event_types": ["job.succeeded", "job.failed"]
}'The answer carries the whsec_… signing secret exactly once. There is nothing to attach to a job: every job in the workspace reports to every endpoint subscribed to its event. An endpoint for results can leave out credits.low, and one for billing alerts can take only that.
Verifying the signature, Send test, automatic retries, auto-disable, the event log, replay and secret rotation are in the Webhooks guide, with Node code you can paste. Trawl expects a 2xx within 15 seconds; the result also stays on the job (GET /v1/workspaces/:workspace_id/jobs/:id), so a missed delivery never loses data.
3
What a job event looks like
Signed with Standard Webhooks like every ProductCraft event; the job is in data.job.
{
"id": "evt_83cfc794-78e9-4102-96de-3a9a6f5bc31e",
"type": "job.succeeded",
"created_at": "2026-10-17T10:00:00.000Z",
"workspace_id": "24fab978-7cd7-48ae-bce1-aba876b11957",
"data": {
"job": {
"id": "7c1e2a4b-5d3f-4e8a-9b6c-0d1e2f3a4b5c",
"status": "succeeded",
"result": { "title": "Example Domain", "price": null },
"error": null
}
}
}Set up before 17 October 2026? Endpoints that existed then, or that are created through the older POST .../webhooks route, keep working as they did: they receive job.succeeded and job.failed only for the jobs that name them in webhook_id. Until 15 January 2027 they also get the old x-trawl-signature header plus x-trawl-event and x-trawl-event-id, and the body still carries the old top-level event, occurred_at and job fields: read type and data.job before then. x-trawl-delivery-attempt is no longer sent; dedupe on webhook-id. To receive every job without naming it, add a new endpoint; you can then stop sending webhook_id on job create. The Webhooks guide covers the old header and moving your verifier.
4
Hear about a low balance before jobs stop
New jobs are refused (402) when the balance reaches zero. credits.low gives you time to top up first.
{
"id": "evt_1f0b9c2e-6a7d-4c3b-8e5f-2a1b0c9d8e7f",
"type": "credits.low",
"created_at": "2026-10-17T10:00:00.000Z",
"workspace_id": "24fab978-7cd7-48ae-bce1-aba876b11957",
"data": {
"balance_steps": 840,
"threshold_steps": 1000,
"last_top_up_steps": 10000
}
}The line is 10% of your last top-up, and never under 100 steps. The event is sent once, by the job whose usage takes the balance under the line; it comes again only after your next top-up. The same answer is on the credits endpoint, for a dashboard banner of your own:
curl https://api.trawl.productcraft.co/v1/workspaces/<workspace_id>/credits \
-H 'authorization: Bearer pcft_live_...'
{
"balance_steps": 840,
"low_balance": true,
"low_balance_threshold_steps": 1000,
"entries": [ ... ]
}