Developers · Webhook event

meeting.started — a meeting your key created has begun

A Meetful webhook event, sent to the https URL registered on your key. As soon as your key creates a meeting — with POST /api/meeting, or the start_meeting tool.

When it arrives

As soon as your key creates a meeting — with POST /api/meeting, or the start_meeting tool.

What is in it

FieldTypeWhat it is
data.meetingstringThe meeting code, three letters, four, three.
data.urlstringThe link anyone opens to join.

Every delivery is { event, at, agent, data }: the event name, when it was sent, your key's agent id, and the fields above.

A real one

{
  "event": "meeting.started",
  "at": 1794314420825,
  "agent": "ag_ZYpgxJIwAz",
  "data": {
    "meeting": "edn-wopf-rnf",
    "url": "https://meetful.com/edn-wopf-rnf"
  }
}

Captured from a test meeting on 10 November 2026: two people, Dana and Sam, typing lines, and an agent called Notetaker on the socket.

What to do with it

Use it to post the link where people will see it, or to put a row in your own records that later events can be matched to by data.meeting.

In the capture the url carried the test server's address; on meetful.com it is https://meetful.com/<code>.

It means the meeting exists and its link works, not that anybody is in it yet — it arrives the moment the meeting is created, usually before the first person opens the link.

Only the key that created a meeting is sent this. A meeting somebody starts from the Meetful website, with no key involved, sends no meeting.started to anyone.

Receiving it

Register a URL on your key once — it must be https. You are shown a signing secret, once; keep it. A delivery that fails is tried twice more, after 1.5 and 6 seconds, then dropped; an answer of 4xx other than 429 is not retried.

curl -X PATCH https://meetful.com/api/keys/me \
  -H "authorization: Bearer $MEETFUL_KEY" \
  -H 'content-type: application/json' \
  -d '{"webhook":{"url":"https://your-server.example.com/meetful"}}'

Each delivery carries x-teammeet-event: meeting.started, a timestamp and an HMAC-SHA256 signature over timestamp.body — the scheme Stripe and GitHub use. Check it before you trust the body:

import crypto from 'node:crypto';

// rawBody: the request body exactly as it arrived; secret: the whsec_… you were given once
function verify(headers, rawBody, secret) {
  const ts = headers['x-teammeet-timestamp'];
  const sig = headers['x-teammeet-signature'];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;   // older than five minutes
  const mine = 'sha256=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
  return sig.length === mine.length && crypto.timingSafeEqual(Buffer.from(mine), Buffer.from(sig));
}

Goes with

Also: transcript.line · recording.ready · Every event and message · The webhook overview

Try Meetful

Meetings that take their own notes

Free video meetings in the browser: every line of the transcript under the name of who said it, and the summary and action items when you hang up. Nothing to install — guests just open the link.