WebhookToolkit
REST API v1

Webhook Toolkit API

Everything the inspector does, over HTTP: create capture URLs, wait for webhooks, read them, replay them. JSON in, JSON out, CORS enabled. The CLI and the MCP server are built on it.

Base URL
https://webhook-toolkit.com/api/v1

Authentication

Optional. Without a key, you can create anonymous URLs (7-day lifetime, 30 per IP per day) and read any URL whose token you know. Send Authorization: Bearer whk_… (create keys in your dashboard) to create permanent URLs and use your plan's quotas.

Quick start

Terminal
# 1. create a URL
curl -s -X POST https://webhook-toolkit.com/api/v1/endpoints -H 'content-type: application/json' -d '{"name":"demo"}'
# → { "endpoint": { "token": "Qx7pL2mN9aZk", "url": "https://webhook-toolkit.com/r/Qx7pL2mN9aZk", ... } }

# 2. wait for the next request (in another terminal: curl -d hello https://webhook-toolkit.com/r/Qx7pL2mN9aZk)
curl -s "https://webhook-toolkit.com/api/v1/endpoints/Qx7pL2mN9aZk/wait?timeout=50"
# → { "request": { "method": "POST", "body": "hello", "provider": null, ... } }

Routes

POST/endpointsCreate a capture URL. Body: { name? }. Anonymous URLs expire after 7 days.
GET/endpointsList your URLs (API key required).
GET/endpoints/:tokenOne URL, with its configured response.
PATCH/endpoints/:tokenRename it or change what it answers: { name?, response: { status?, body?, contentType? } }.
DELETE/endpoints/:tokenDelete the URL and its requests.
POST/endpoints/:token/claimMake an anonymous URL permanent on your account (API key).
GET/endpoints/:token/requests?limit=&after=Captured requests, newest first. after = ISO timestamp.
DELETE/endpoints/:token/requestsClear the history.
GET/endpoints/:token/requests/:idOne request in full.
GET/endpoints/:token/wait?timeout=&after=Long-poll: returns the next request (max 50 s), or { request: null, timedOut: true }.
GET/endpoints/:token/streamServer-Sent Events: one `request` event per captured request.
POST/endpoints/:token/requests/:id/replayRe-send the request to a public URL: { url }.
POST/endpoints/:token/requests/:id/explainAI: { mode: "explain" | "handler", language?, locale? }.
GET/meYour plan and limits (API key required).
GET · POST/relaysList or create Relay tunnels (paid plans).

Objects

Endpoint
{
  "id": "clx…", "token": "Qx7pL2mN9aZk", "name": "demo",
  "url": "https://webhook-toolkit.com/r/Qx7pL2mN9aZk",
  "inspectUrl": "https://webhook-toolkit.com/e/Qx7pL2mN9aZk",
  "expiresAt": "2026-09-25T10:00:00.000Z",   // null = permanent
  "owned": false, "locked": false, "requestCount": 0,
  "createdAt": "2026-09-18T10:00:00.000Z",
  "response": { "status": 200, "body": "{\"ok\":true}", "contentType": "application/json" }
}
CapturedRequest
{
  "id": "clx…", "method": "POST", "path": "/stripe", "query": "",
  "headers": { "stripe-signature": "t=…,v1=…", "content-type": "application/json" },
  "body": "{\"id\":\"evt_…\",\"type\":\"invoice.paid\"…}",
  "contentType": "application/json", "size": 2143,
  "ip": "54.187.174.169", "country": "US",
  "createdAt": "2026-09-18T10:01:02.000Z",
  "provider": "stripe", "event": "invoice.paid"
}

Errors

Errors are JSON: { "error": "plan_limit", "message": "…", "upgradeUrl": "…" }. Codes: bad_request (400), unauthorized (401), upgrade_required and plan_limit (402), forbidden (403), not_found (404), expired (410), rate_limited (429). A capture URL whose owner's plan lapsed answers 402; an expired anonymous URL answers 410.

Streaming

Terminal
curl -N https://webhook-toolkit.com/api/v1/endpoints/Qx7pL2mN9aZk/stream
event: hello
data: {"endpointId":"clx…","token":"Qx7pL2mN9aZk"}

event: request
data: {"id":"clx…","method":"POST","path":"/","body":"hello",…}

Prefer the official client in Node.js: npm i webhook-toolkitcreateEndpoint(), waitForRequest(), stream(), typed errors. See the CLI page.

REST API — create webhook URLs, read and wait for requests · Webhook Toolkit