POST, verifies the signature, and returns a 2xx. The verification has a few sharp edges (raw body, constant-time compare, a timestamped signature), so the fastest reliable way to build it is to let your coding agent do it from the prompt below.
Before you start
- An HTTPS URL that can accept a
POST. Plain HTTP is rejected. In development, expose localhost with a tunnel (ngrok http 3000,cloudflared tunnel) so Tallwatch can reach it. - A signing secret of at least 16 characters, shared between Tallwatch and your app:
Store it as
TALLWATCH_WEBHOOK_SECRETin your app, and paste the same value into the channel form when you add the webhook.
Generate it with your coding agent
1
Open your agent in the project
Claude Code, Cursor, or whatever you use, with your repo as context.
2
Paste the prompt
Copy the prompt below and replace the stack line with yours.
3
Let it scaffold and test
The prompt asks for a verified endpoint plus a unit test, so you can run the test to confirm both the accept and reject paths before going live.
Prompt for your coding agent
What you receive
Headers on every delivery:
The body is the canonical JSON payload, or your Handlebars output if the channel uses a template. Field-by-field reference: Payload.
How delivery behaves
- Return any
2xx. A bare204with no body is ideal. Anything else counts as failed. - Answer within 10 seconds. That’s the per-request cap. If your work takes longer, return
202immediately and process asynchronously. - Transient failures retry. A
5xx,429, or timeout is retried inline up to 3 times with a short backoff, then markedfailedon the incident. A4xxis treated as a permanent rejection and not retried.
Test it locally
You don’t need Tallwatch to test verification. This produces a correctly signed request withopenssl and curl:
204. Change one character of SECRET and rerun. You should get 401. That confirms both paths before you point a real channel at it.
When the endpoint is live over HTTPS, add the channel in Settings → Alerts → Channels → Add channel → Webhook, paste the URL and the same secret, and click Send test alert.
Make it production-ready
- Be idempotent. Tallwatch retries transient failures, so the same event can arrive more than once. Derive a stable key (for example
event+incident.id) and skip work you’ve already done. - Keep the replay window tight. 300 seconds is a reasonable tolerance. Reject anything older.
- Rotate without downtime. Accept the old and new secret during a rollover, then drop the old one. See Signing.
- Reshape the body if you want. Set a Handlebars template on the channel and the body becomes whatever you render. The signature still covers the rendered bytes, so verification is unchanged. See Templates.