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

FieldTypeWhat it is
data.meetingstringThe meeting code.
data.msg.idstringWho posted it — their id in the meeting.
data.msg.namestringTheir name.
data.msg.textstringWhat they typed.
data.msg.atnumberWhen, in ms since 1970.
data.msg.kindstring"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

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.