Everything here was observed against the live API (2026-09-03/04) on a Pro account, not taken from the docs. Where the official docs say something else, that is noted. The code comments and CHANGELOG.md reference these facts; when the platform changes, scripts/live_tool_check.py is what notices.
PUT /token/{id}replaces the whole record. A body with onlyaliasresets status, content, timeout and CORS. The server reads the token first and merges every update (same for actions, schedules, templates, variables, databases, users).POST /tokenignoreslisten; onlyPUTsets it.configure_webhooksends a follow-upPUTwhen a new token asks forlisten.- With an API key, tokens are permanent (
premium: true).expiry(max 604800 s) is optional;WEBHOOK_SITE_DEFAULT_EXPIRYsets a default. descriptionis accepted and returned although the API reference does not list it.request_limitabove 10000 is accepted where the plan allows it (20000 worked on Pro; Enterprise goes to 100000). The client no longer caps it at 10000.alias: nullonPUTremoves an alias (configure_webhook(alias="")). Aliases are 3-32 letters, digits,-or_.GET /token/{alias}returns the token although the docs say aliases are not accepted in API URLs. Sub-resource paths such as/token/{alias}/requestsdo 404, so every tool resolves an alias to the UUID once and uses the UUID from then on.- Alias lookups are cached by webhook.site for about 120 s. After a settings change, the alias URL keeps answering with the previous settings until that cache expires; the UUID URL reflects the change immediately.
configure_webhookreports this asalias_cache_note. - Capture forms that all work:
https://webhook.site/{id}[/any/path],https://{id}.webhook.site, andhttps://webhook.site/{id}/{status}, which forces that response status (force_status_urlinget_webhook_info). POST /tokenis rate limited (the docs say 10/min free, 60/min paid). A 429 withRetry-Afterup toWEBHOOK_MCP_RATE_LIMIT_MAX_WAITseconds is waited out once.
- The list endpoint pages at most 100 items and reports
is_last_page;export_webhook_datapages through it. The account-level CSV export is limited to 3 calls per minute and answers 429 withRetry-After. /request/latestcan 404 for one or two seconds after a capture;get_requestretries once.- Notes go to the singular path
PUT /token/{id}/request/{rid}; the plural path in the docs answers 404. Notes are capped at 10000 characters. - Set Response (
PUT /token/{id}/request/{rid}/response, base64 body) returns{"status": 3}when it reached a waiting caller and2when nothing was waiting. A request is only held whilelisten > 0and a socket listener is subscribed, which is whatrespond_to_next_requestdoes end to end. - The search language accepts exclusion (
-method:GET),_exists_:field,note:, geo fields (country_code:DE), date ranges (created_at:[now-1h TO now]) and thesortingfield:sorting:>Nreturns exactly the requests created after the one withsortingN.date_from/date_totake date expressions such asnow-7d. request.sorting(microsecond timestamp) is also a Custom Action variable.- Requests dropped by Don't Save, Rate Limit or a failed Basic Auth never appear in the API.
- DNSHook lookups arrive with
type: dnsand the record type inmethod; every subdomain of{id}.dnshook.siteis captured.
- The mail domain is
{id}@emailhook.site(verified delivering);{id}@email.webhook.sitestill works. - Email objects carry
sender,checks(spam, virus, spf, dkim, dmarc),destinations,email_truncated,filesand atext_contentderived from the HTML.
- 63 action types; each was run through
test-actionfor real (utils/action_types.json,manage_custom_actions(action="types")).test-actionneedsorder; withaction_idit tests against a saved action without changing it, contrary to the docs. - Actions have a
name. APUTwithout it clears the name, so updates merge it in. - Actions also run on incoming emails. A
send_emailaction to the token's own inbox loops unless aconditionon$request.type$guards it (37 emails in a minute, seen). - Outbound actions (
http,send_request,slack_send_message, schedules) pointed at a webhook.site URL are detected as recursion, disabled, and the account owner gets an email. executere-runs all saved actions on a request and overwrites the stored output;error_notificationsdefaults to off.conditions(plural) accepts the operatorsregex(with/delimiters/),nex,null,nnullon top of the documented twenty; the singularconditionanswers "Unknown operator" for those. The operator maps come from the frontend bundle (actionConditionOperators).set_variablehas modestext,random,random_number(random_number.from/to),dateandmath(round(1 + 2.5, 0)set 4).text_mapuses the condition operator codes (ew,ct, ...), not their spelled-out names.databaseacceptstype: whdbwithdb_id(a Webhook.site Database) and always wantsparams([]when unused).send_requestis legacy (the editor no longer offers it). The editor refusesqueueonmodify_response,dont_saveandrate_limit; the API accepts it.- Queue Profiles live at
/queues(not in the API docs):name,amount,duration,expiry,delay;GET /queues/{id}404s, the list is the source. Actions reference one throughqueue_id. - Schedules accept
require_cert_expiry(days) in addition to the documented fields;run-nowanswers 302. GET /variables(undocumented) lists the base variable names the platform defines.
manage_custom_actions(action="script_reference")lists 138 functions generated from the docs, each called on the live engine byscripts/verify_webhookscript.py. The documentedbase64_urlencodeandnumber_lengthdo not exist;base64url_encode,get,get_variableandlengthexist although undocumented.- Custom Action variables are not substituted inside a script: use
var('request.content'). Arithmetic is strictly typed (5 + "4"errors).
- webhook.site drops idle keep-alive connections after a few seconds; reusing one fails with "Server disconnected without sending a response". The client expires idle connections after 4 s and retries idempotent calls (GET, HEAD, PUT, DELETE) once. POST is never replayed.
- The real-time socket at
ws.webhook.siteaccepts Engine.IO 3 and 4; channelprivate-token.{id}, eventrequest.created(emails and DNS included). The waiting tools fall back to polling when it drops. - Requests to a capture URL are stored with their headers, so the server never sends the
Api-Keyheader there.
Error log, providers (OAuth and credentials for actions), custom domains, API key management, notification settings, roles, share links and the form builder. manage_users cannot create API keys.