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
| Field | Type | What it is |
|---|---|---|
data.meeting | string | The meeting code, three letters, four, three. |
data.url | string | The 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
meeting.endedThe whole transcript, recap and notes when a meeting ends.chat.messageSomebody typed in the meeting chat.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.