Catch, inspect, replay and forward webhooks. https://<id>.hooks.<d> (or a named endpoint) records every
request. Host: hooks.<d>. Binary: hooksd. Stage 6.
-
An endpoint is a team's: https://<id>.hooks.<d> (10 characters) or <name>.hooks.<d> (one wildcard
certificate). It keeps every request (method, path, query, headers, the body's first 1 MB, its size and
sha256, the sender's address) for its retention (1–90 days, 7 by default; pruned hourly).
-
Answer: while xvii hooks listen ENDPOINT --forward PORT|URL is connected (kit/relay, as tunnel), the
request goes to the developer's machine and its answer goes back (10 s, then the endpoint's own
answer). Otherwise the endpoint answers with what is set: status, headers, body, delay. listen without
--forward only watches: the endpoint answers and the CLI prints each request.
-
Forwards: up to 5 URLs; every request goes to each in the background, tried again after 1 s, 5 s,
30 s, 2 min and 10 min until a 2xx–3xx. Each attempt (and each listener answer) is a delivery on the
request. Forwards and replays reach the internet only: loopback, private and link-local addresses are
refused at dial time.
-
Signatures: Telegram's secret token, GitLab's token, GitHub's and Stripe's HMAC-SHA256 (Stripe's
timestamp within 5 minutes). The secret is sealed with DATA_DIR/seal.key and never shown; each request
is marked signed or bad signature, and nothing is refused.
-
Replay: a request kept whole goes again to the listener, the forwards or any URL; the result is a
delivery.
-
Limits hooks.endpoints and hooks.storage (bytes of kept bodies); over the storage limit requests are
still answered and recorded, without their bodies.
-
CLI: xvii hooks [ls], create [--name] [--team] [--verify --secret], rm, listen, requests,
replay REQUEST [--to listener|forwards|URL].
-
Journal: endpoint.create, endpoint.update, endpoint.delete, endpoint.listen, request.replay.
-
Pending forward retries live in memory: a restart drops them (the request and its earlier attempts
stay).
-
Not yet: endpoints scoped to a project, search and diff of requests, editing a request before a replay.
-
An endpoint's own host name: Own domain in xvii domains in its sheet attaches a name (target
"webhook endpoints"); requests to it are caught like those to <id>.hooks.<d>, and the endpoint's
address becomes it. Journal endpoint.domain.