Webhooks
Receive every finished meeting as signed JSON at your own HTTPS endpoint.
Availability: To be confirmed
A webhook sends each finished meeting to a URL you control, as JSON, signed so you can verify it came from meaty.
Add a webhook
In the web or desktop app: Settings → Developers → Webhooks.
- Enter your endpoint URL. It must be HTTPS and publicly reachable.
- Choose what's included: Summary, Actions, Transcript (transcript off by default).
- Optional: Auto-send when a meeting finishes (off by default). Otherwise send meetings by hand from Share.
- Copy the signing secret (
whsec_…). It's shown once.
Up to 8 webhooks per account. Send test delivers a sample payload any time.
The request
POST to your URL with a JSON body and these headers:
| Header | Value |
|---|---|
X-Meaty-Event |
meeting.ready or meeting.updated |
X-Meaty-Delivery |
A delivery ID, the same across retries — use it to ignore duplicates |
X-Meaty-Signature |
sha256= + hex HMAC-SHA256 of the raw body |
meeting.ready fires when the notes are first ready. meeting.updated
fires after edits (batched over a few seconds) — including the template
being applied, which usually lands moments after meeting.ready.
The body
{
"event": "meeting.ready",
"meeting": {
"id": "6f0c…",
"title": "Quarterly planning with Acme",
"created_at": "2026-10-20T09:30:00+00:00",
"duration_ms": 1800000,
"meeting_type": "client_consultation",
"tags": ["acme"],
"url": "https://meaty.me/public/…",
"summary": "…",
"description": "…",
"actionables": [
{"task": "Send the revised quote", "owner": "Maria", "due_date": "2026-10-24", "status": "open"}
],
"transcript": "[…] Maria: …\n[…] Tom: …"
}
}
- A part you switched off is absent, not empty.
urlis present only when the meeting has an active share link.transcriptis cut at 200,000 characters.- A test delivery adds
"test": true.
Verify the signature
The key is the whole signing secret, whsec_ included. Compute over the
raw request bytes, before any JSON parsing:
import hashlib, hmac
def verify(secret: str, raw_body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)
Delivery and retries
- meaty waits 5 seconds for a
2xx. Redirects aren't followed. - A failed delivery is retried twice: after 1 minute, then after 10.
- The last deliveries and their results are listed on the webhook.