Back
Product

we post to your url

new card? status change? pro can now POST a signed json payload to your endpoint. hmac. retries. no slack-or-nothing.

Jessé Cruz 3 min read

slack is a chat. your product is a stack.

a new card used to die in a channel. a status change used to die in a channel. if you wanted it in linear, or a queue, or your own laravel app, you copy-pasted.

so i shipped a signed POST to your url.

what we send

pro. one url per project. you pick the events:

  • post.created — someone submitted a card (board, widget, mcp, same hook)
  • post.status_changed — it moved. from and to are in the body

plus webhook.ping when you hit send test. ping is not a subscription. it just proves the wire.

the body looks like this:

{
  "id": "delivery-uuid",
  "event": "post.created",
  "created_at": "2026-08-13T12:00:00+00:00",
  "project": { "id": 1, "slug": "acme", "name": "acme" },
  "data": {
    "id": 42,
    "title": "dark mode",
    "status": "pending",
    "url": "https://usehoot.app/projects/acme/board?post=42"
  }
}

headers: X-Hoot-Event, X-Hoot-Delivery, X-Hoot-Signature. user-agent Hoot-Webhook/1.0.

queued. 3 tries. backoff 1s, 5s, 10s. we give your endpoint five seconds. then we stop.

how you know it's us

the secret starts with hoot_whsec_. we show it once. encrypted after that.

sign this string:

{unix timestamp}.{raw json body}

hmac-sha256. hex.

the header is:

X-Hoot-Signature: t=1710000000,v1=…

check it with hash_equals. reject a stale t. do not parse the json first — sign the raw body.

[$t, $v1] = /* parse t= and v1= */;
$expected = hash_hmac('sha256', $t.'.'.$raw, $secret);
hash_equals($v1, $expected);

that's the whole contract.

why not just slack

slack is fine. telegram is fine.

they are not your backend.

votes still measure demand. you still decide what ships. the webhook just means hoot can talk to the thing you already run, without us pretending a chat app is an api.

where it lives

project → notifications → outgoing webhook.

paste the url. pick the events. copy the secret. send a ping.

if you're on starter: that's a pro wall. upgrade, or stay on email.

if you're already on pro: turn it on. then go write the six lines above.

if you're not on hoot: usehoot.app

ask. ship. tell your backend. 🦉

Related