Webhooks
Get a signed HTTP call when items finish instead of polling for results.
Register an HTTPS endpoint and Pathwize POSTs a JSON event to it whenever something you care about happens. Each delivery is signed with your endpoint’s secret, retried with backoff for up to 24 hours if your server does not answer with a 2xx, and carries a stable event id so you can ignore duplicates.
Events
| Event | When | data |
|---|---|---|
item.labeled | An item reached its final answer (all raters done, or a reviewer decided). | task_id, item (same shape as a results row) |
item.flagged | The experts could not label an item: unreadable, wrong data or unresolved disagreement. | task_id, item with flags |
task.completed | The last open item of a task was finished. Fires again after every new batch that completes. | task_id, items_done |
ping | Sent when you press Send test in the dashboard or call the test endpoint. | message |
Payload
{
"id": "evt_6f1c2d9a3b4e5f6a7b8c9d0e",
"type": "item.labeled",
"created": 1790400000,
"data": {
"task_id": "9ecd8b0a-342a-4b9c-a3dc-4cd69e5c5caf",
"item": {
"id": "werk-nord-2026-09-25-000871",
"status": "labeled",
"result": { "label": "Cardboard", "labels_all": ["Cardboard", "Cardboard"], "agreement": 1, "raters": 2, "flags": [] },
"group": "werk-nord",
"captured_at": "2026-09-25T07:12:04+02:00",
"meta": { "site": "Werk Nord" }
}
}
}Verifying the signature
Every request carries Pathwize-Signature: t=<unix seconds>,v1=<hex> where v1 is HMAC-SHA256 of <t>.<raw body> with your secret. Recompute it over the raw bytes, compare in constant time, and reject timestamps older than five minutes. Pathwize-Event repeats the event type and Pathwize-Delivery identifies the attempt.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(signatureHeader.split(",").map((p) => p.split("=")));
const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Managing endpoints
Add endpoints under Developers in the dashboard or through the API. The signing secret is returned once, on creation. Up to 10 endpoints per workspace.
urlstringrequired- HTTPS endpoint that accepts POST.
eventsstring[]required- One or more of
item.labeled,item.flagged,task.completed. descriptionstring- Free text shown in the dashboard.
curl https://www.gopathwize.com/api/v1/webhooks \
-H "Authorization: Bearer pw_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://api.example.com/pathwize/webhook","events":["item.labeled","task.completed"]}'Lists your endpoints with their last delivery status (never the secret).
Sends a signed ping event to the endpoint and returns whether it answered 2xx.
id to deduplicate. Results stay available through the results endpoint whether or not a webhook was delivered.