Developers · Webhook event

transcript.line — new transcript lines, batched every few seconds

A Meetful webhook event, sent to the https URL registered on your key. While people talk.

When it arrives

While people talk. Lines are collected for four seconds, or until there are 25, and sent together — a busy meeting would otherwise be a request every second.

What is in it

FieldTypeWhat it is
data.meetingstringThe meeting code.
data.linesarrayThe new lines since the last delivery: at, speakerId, speaker, text, meeting, lineId.

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": "transcript.line",
  "at": 1794314425759,
  "agent": "ag_ZYpgxJIwAz",
  "data": {
    "meeting": "edn-wopf-rnf",
    "lines": [
      {
        "at": 1794314421758,
        "speakerId": "dana",
        "speaker": "Dana",
        "text": "Let us move the launch to the third of March.",
        "meeting": "edn-wopf-rnf",
        "lineId": "ln_1_tgcmcu"
      },
      {
        "at": 1794314422159,
        "speakerId": "sam",
        "speaker": "Sam",
        "text": "Fine by me, as long as the docs are ready by then.",
        "meeting": "edn-wopf-rnf",
        "lineId": "ln_2_000tqb"
      }
    ]
  }
}

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

Append the lines to whatever you keep. lineId is unique within the meeting, so a delivery retried after a timeout can be told apart from a new one by checking whether you already have its first lineId.

A batch holds at most 25 lines; a longer burst arrives as several deliveries.

The agent's own spoken lines are not in these batches; they are in meeting.ended's transcript.

An agent on the socket gets each of these lines the moment it is said, as a transcript message. The webhook trades that immediacy for one request every few seconds instead of one per sentence.

Answer within eight seconds. A delivery that gets no answer by then counts as failed and is tried again, so a slow endpoint can see the same batch twice — another reason to check lineId.

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: transcript.line, 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: meeting.started · chat.message · 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.