Webhooks
A webhook tells another tool each time something happens in Caute.
Set one up
Signed in, go to Settings, then Webhooks. Or, with a token or OAuth grant that holds items:read or search:
curl -X POST https://api.getcaute.com/v1/webhooks \
-H "Authorization: Bearer $CAUTE_TOKEN" -H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/caute", "types": ["item.searchable"]}'
The answer's secret (whsec_…) is shown once. Leave types out to get every type, including ones added later.
Webhooks need the Pro+ or Team plan.
What arrives
Each delivery is a POST of one event in JSON, the same envelope as GET /v1/events:
{"id": "0199…", "type": "item.searchable", "created_at": "2026-10-12T14:03:11.402Z",
"workspace_id": "0198…", "space_id": "0198…", "subject": {"type": "item", "id": "0199…"},
"payload": {"kind": "web"}}
An event holds ids and metadata, never what was saved. An item event's payload.kind is the card's kind (web,
document, note, …), so you can skip what you don't handle without fetching it. To get the item, fetch
GET /v1/items/{subject.id} with your own credential. Types sent today:
| Type | Meaning |
|---|---|
item.captured |
Something was caught. |
item.searchable |
Its text is ready. |
item.failed |
It couldn't be read. |
item.deleted |
It was deleted. |
note.updated |
A note was written or changed. |
highlight.created |
A passage was highlighted. |
email.quarantined |
Mail from an unverified sender is waiting. |
brief.ready |
A brief you asked for was written, as a note in your inbox. The subject is the note. |
You are sent only what the credential that made the webhook can read. Treat any type you don't know as something to ignore.
Check it came from Caute
Every delivery carries three headers:
webhook-id: the event's id.webhook-timestamp: Unix seconds.webhook-signature:v1,followed by the base64 HMAC-SHA256 of{id}.{timestamp}.{body}, keyed with the base64-decoded part of the secret afterwhsec_.
This is the Standard Webhooks scheme, so any of its libraries works. verify.py
does the same with the Python standard library alone. Reject a delivery whose timestamp is more than five minutes off.
Retries and order
- Answer with a 2xx status within 10 seconds.
- Anything else is retried, from 30 seconds apart up to an hour apart. Nothing behind it is sent until it succeeds, so events arrive in order.
- A repeat carries the same
webhook-id, so keep the ids you've handled to drop repeats. - Redirects are not followed.
- Answering
410 Goneturns the webhook off. - A webhook that keeps failing for three days is turned off, with the reason shown in Settings. Turned back on, it carries on from the first event it hadn't delivered.