Skip to main content
MeetingKit sends a signed POST to your endpoint for every meeting, bot and calendar connection event in a workspace, however it was created. Each event carries the current resource.

Register an endpoint

Webhook endpoints belong to a workspace. With a key that is an owner or admin of it, register yours with POST /webhook_endpoints and choose the events it receives:
Store the secret from the response. It starts with whsec_ and is shown only once; send your own secret instead to use one you already hold. An endpoint covers every meeting, bot and calendar connection in its workspace, however it was created. If you run one workspace per customer, each workspace needs its own endpoint; the URL and the secret can be the same. Endpoints must be public HTTPS URLs. Redirects are not followed. An endpoint is pinned to the API version of the request that created it, or to api_version if you send one, so its events keep the shape your code was written against.

Event types

Each event has a reference page with the full payload schema, collocated with its resource’s endpoints in the sidebar.

Event payload

Event metadata sits at the top level; the current resource is under data.object:
For meeting.* events, data.object is the meeting as GET /meetings/{id} returns it; for calendar_connection.* events, the calendar connection. For bot.* events, data.object is the bot as GET /bots/{id} returns it, with the recording choices that apply to it — including bots sent from a connected calendar or manually from the product. The bot carries no results: on bot.transcript_ready and bot.summary_ready, read GET /meetings/{meeting_id}/results. Webhook payloads never include a MeetingKit editor or share URL.

Verify signatures

Each request carries three headers: Both digests are lowercase hex HMAC-SHA256, keyed with the endpoint’s full signing secret, whsec_ prefix included:

Verification code

Every request carries X-HappyScribe-Signature: t=<unix_timestamp>,v1=<hex_digest>. The digest is an HMAC-SHA256 of <timestamp>.<raw request body>, keyed with the full signing secret, whsec_ prefix included. Verify before parsing the JSON, on the raw bytes you received, and reject timestamps older than five minutes:
Keep your server’s clock in sync.

Retries and ordering

  • Acknowledge fast. Return any 2xx within 10 seconds. Anything else, or a timeout, is retried with backoff: up to 21 attempts over about 14 hours, with at most an hour between two.
  • Store, then acknowledge. Write the event somewhere durable before you return 2xx, and process it from there.
  • Deduplicate on the event id. Delivery is at least once. A retry has the same id and a fresh signature timestamp, so return 2xx for an id you already stored.
  • Don’t rely on order. Events for one resource usually arrive in order, but not always. Treat an event as a signal: read the resource again (GET /meetings/{id}, GET /bots/{id}) and save what the read returns.
  • Keep a fallback. Webhooks are the fast path, not the only one. If a bot or a meeting you expect to be finished has sent nothing, read it with GET /bots/{id} or GET /meetings/{id}.
  • Recover missed events. After an outage, list GET /webhook_events?delivery_status=failed from when it started and process the ones you have not stored, or redeliver one to your endpoint. GET /webhook_events/{id} shows every delivery attempt and what your server answered.

Test locally

MeetingKit can only deliver to public HTTPS URLs. During development, expose your local receiver with a tunnel such as ngrok http 8787 or cloudflared tunnel --url http://localhost:8787, and register the tunnel’s URL. Then call POST /webhook_endpoints/{id}/test to check that your receiver answers 2xx and verifies the signature: the response carries the status code it returned. A test event is a sample: its IDs do not exist, so do not fetch them. To see real events, run the Quickstart with the endpoint registered. A failed bot’s reason values are listed in Failure reasons.
Webhooks don’t change MeetingKit email behavior — meeting-summary emails continue to follow the existing product and user notification preferences.