meaty.me Docs

Webhooks

Receive every finished meeting as signed JSON at your own HTTPS endpoint.

Updated 2026-10-20 View as markdown

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.

  1. Enter your endpoint URL. It must be HTTPS and publicly reachable.
  2. Choose what's included: Summary, Actions, Transcript (transcript off by default).
  3. Optional: Auto-send when a meeting finishes (off by default). Otherwise send meetings by hand from Share.
  4. 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.
  • url is present only when the meeting has an active share link.
  • transcript is 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.

See Integration delivery failures.