Developers · Webhook event
chat.message — somebody typed in the meeting chat
A Meetful webhook event, sent to the https URL registered on your key. Each time a person posts in the chat of a meeting your key is in.
When it arrives
Each time a person posts in the chat of a meeting your key is in.
What is in it
| Field | Type | What it is |
|---|---|---|
data.meeting | string | The meeting code. |
data.msg.id | string | Who posted it — their id in the meeting. |
data.msg.name | string | Their name. |
data.msg.text | string | What they typed. |
data.msg.at | number | When, in ms since 1970. |
data.msg.kind | string | "msg" for a person's message. |
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": "chat.message",
"at": 1794314422560,
"agent": "ag_ZYpgxJIwAz",
"data": {
"meeting": "edn-wopf-rnf",
"msg": {
"id": "dana",
"name": "Dana",
"text": "Docs owner is Sam.",
"at": 1794314422559,
"kind": "msg"
}
}
}
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
Typed messages are often the decisions people did not want to say out loud — a name, a date, a link. Keep them next to the transcript.
Messages that agents post are not sent as chat.message — only what people type.
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: chat.message, 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
chatRead and post messages in the meeting chat.meeting.endedThe whole transcript, recap and notes when a meeting ends.Also: transcript.line · meeting.started · 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.