Skip to content
Docs
Open Escouade
Documentation contents

Docs › Meet

Meet for developers

View as .md

Meet has a read-only REST API, signed webhooks and an MCP server. Keys, webhooks and connected assistants are managed in Meet’s space, account menu "Développeurs" (/developpeurs).

The REST API, the keys and the webhooks are read-only: nothing there creates, changes or deletes a meeting, minutes or an action. A key only reads the meetings its owner owns, outside the bin; never those other members share with their teams.

API keys

A key is created in Développeurs › Clés, with a name and at least one permission. Its value is shown once only, right after creation. It has the form rmk_ followed by an eight-character public identifier, a _ and a secret; only its fingerprint is kept. It can be revoked at any time, for good. An account has at most 20 active keys.

PermissionOpens
meetings:readThe list and details of meetings: title, date, status, origin, calendar context.
reports:readMinutes: summary, key points, decisions, open questions, chapters.
actions:readThe actions in the minutes: owner, deadline, "done" status.
transcripts:readTranscriptions, with a permission of their own.
usage:readThe month’s time, through the MCP server (get_usage tool).

The REST API

Base address: https://meet.escouade.io/v1. Authentication: Authorization: Bearer rmk_…. Responses in JSON, dates in RFC 3339 (UTC). Any method other than GET receives 405. The API sends no CORS headers: it is called from a server, never from a web page, where a key must not live.

ResourcePermissionReturns
GET /v1/meetingsmeetings:read{"data": [meeting…], "next_cursor": "…" or null}
GET /v1/meetings/{id}meetings:read{"data": meeting}
GET /v1/meetings/{id}/reportreports:read{"data": minutes}, without the actions
GET /v1/meetings/{id}/actionsactions:read{"data": [action…]}
GET /v1/meetings/{id}/transcripttranscripts:read{"data": {"meeting_id", "segments": […]}}
Terminal
curl -s https://meet.escouade.io/v1/meetings?limit=5 \
  -H 'Authorization: Bearer rmk_…'

List and pagination

GET /v1/meetings returns the most recent meetings first. Parameters: limit (1 to 100, 20 by default), cursor (the next_cursor value of the previous page, as is), status (a status below). next_cursor is null on the last page.

A meeting

FieldContent
idThe meeting’s identifier.
titleTitle.
statusPublic status (below).
starts_atStart; for a phone recording, when it was sent.
scheduled_end_atScheduled end, for a calendar meeting; otherwise null.
origincalendar (connected calendar), link (pasted link), phone (recorder), desktop, manual (meeting noted in Meet).
platformmeet, teams, zoom, webex, goto, in_person, desktop, other.
organizer_emailOrganiser known from the calendar, otherwise null.
contextCalendar description as plain text (1,200 characters at most), otherwise null.
has_transcript, has_reportA transcription, minutes exist.
updated_atLast change.
participants{"email", "name", "response", "organizer"}, organiser first; response among accepted, tentative, declined, pending, unknown.

Never: the video call link, a file path, an internal technical identifier.

Statuses

statusMeaning
plannedScheduled.
joiningThe bot is joining the meeting or waiting in the waiting room.
recordingRecording in progress.
processingTranscription and minutes being prepared.
transcript_readyFinished with a transcription, without minutes.
report_readyFinished with minutes.
completedFinished without transcription or minutes.
failedProcessing did not succeed.
missedMissed.
unsupportedPlatform not supported.

Minutes, actions, transcription

  • Minutes: meeting_id, template, summary, key_points, decisions, open_questions (each {"text", "source_seconds"}), chapters ({"title", "summary", "source_seconds"}). No minutes yet: 404 not_ready.
  • Action: id (stable key), title, assignee, due (free text as spoken, may be null), completed, source_seconds.
  • Transcription: segments of {"start", "end", "speaker", "text"}, in seconds; speaker is null when the speaker is not known.

Errors and limits

Error body: {"error": {"code": "…", "message": "…"}}; for a 403, required_scope as well.

HTTPcodeWhen
400invalid_parameterlimit or status outside the allowed values.
400invalid_cursorUnreadable cursor.
401unauthorizedKey missing, unknown or revoked.
403insufficient_scopeMissing permission.
404not_foundMeeting that does not exist, belongs to another account or is in the bin.
404not_readyNo minutes or transcription yet.
405Method other than GET.
429rate_limitedMore than 120 calls per minute for the key, or from the same IP address for the API and MCP combined. Retry-After header.
500internal_errorService error.

Webhooks

Destinations are managed in Développeurs › Webhooks: an HTTPS address reachable on the Internet, the chosen events, at most 10 destinations per account.

EventSent when
meeting.transcript_readyA transcription is saved (it may be empty if nobody spoke).
meeting.report_readyThe minutes are saved.
meeting.processing_failedThe recording or the transcription did not succeed.

The body carries only the essentials; the title and content are then read through the API, with a key:

JSON
{"id": "evt_…", "type": "meeting.report_ready", "created_at": "2026-10-20T09:41:07Z",
 "data": {"meeting_id": "…", "status": "report_ready"}}

Verifying the signature

The headers follow the Standard Webhooks convention:

  • webhook-id: the event’s identifier, the same on every retry;
  • webhook-timestamp: the moment, in Unix seconds;
  • webhook-signature: v1, followed by the HMAC-SHA256, in base64, of {webhook-id}.{webhook-timestamp}.{body}, keyed with the whsec_… secret without its prefix, decoded from base64.

Verify in constant time, refuse a timestamp more than 5 minutes off, ignore a webhook-id already processed. The secret is shown once, when the destination is created.

Python
import base64, hashlib, hmac, time

def verify(secret, headers, body):
    key = base64.b64decode(secret.removeprefix("whsec_"))
    message = "%s.%s.%s" % (headers["webhook-id"], headers["webhook-timestamp"], body)
    expected = base64.b64encode(hmac.new(key, message.encode(), hashlib.sha256).digest()).decode()
    if abs(time.time() - int(headers["webhook-timestamp"])) > 300:
        return False
    return any(hmac.compare_digest("v1," + expected, s) for s in headers["webhook-signature"].split())

Delivery

Your endpoint replies 2xx within 10 seconds. Otherwise, a retry goes out after 30 s, 2 min, 10 min, 30 min, 1 h, 3 h then 6 h: 8 attempts at most, then the event is marked abandoned. A delivered or abandoned event can be resent from the page, with the same identifier. No redirect is followed. A paused destination accumulates its events, which go out when it resumes.

The MCP server

Address: https://meet.escouade.io/mcp, over Streamable HTTP, without sessions. An assistant connects through OAuth, with the address alone; a program, with an rmk_… key in Authorization: Bearer.

Twenty-one tools: eleven read, five prepare an action and five are reserved for the assistant’s views.

Read toolPermissionWhat it returns
search_meetingsmeetings:readThe meetings matching a search.
get_meetingmeetings:readA meeting.
get_reportreports:readIts minutes.
get_action_itemsactions:readIts actions.
get_transcripttranscripts:readIts transcription.
get_todaymeetings:readA day’s meetings, and the open actions with actions:read.
get_robot_statusmeetings:readWhere the bot stands in a meeting.
list_action_itemsactions:readThe actions of recent minutes, filtered by owner or status.
search_passagestranscripts:readThe passages matching a search, by meaning or by exact word.
ask_meetingsreports:read and transcripts:readThe answer to a question, with its sources; found is false when the information is missing.
get_usageusage:readThe month’s time: included, used, remaining.

Prepare, then confirm

An assistant connected through OAuth can prepare an action; it is only carried out once confirmed by the person, in the assistant’s view or on a Meet page. Never through an API key, never through the REST API.

ToolPermissionWhat confirmation will do
send_robotmeetings:writeSends the bot into the video call, now.
stop_robotmeetings:writeRemoves the bot from the meeting.
create_meetingmeetings:writeNotes a meeting in Meet, with no video link and no calendar invitation.
update_action_itemactions:writeTicks or unticks an action in the minutes.
share_reportreports:shareSends each recipient a viewing link to the minutes, valid for 7 days.

A prepared action waits for 10 minutes. What leaves Meet with no way back (an email sent, the bot sent through a pasted link) can only be confirmed on the Meet page. No deletion, no payment, no sending of a transcription or recording by this route.

OAuth authorisation

Meet follows the authorisation part of the MCP specification: OAuth 2.1, public clients, mandatory PKCE S256, dynamic registration and client metadata documents. The consent page lists permissions in two groups, Read and Act; only the four meeting reads are ticked by default, nothing that acts. The access token lasts an hour and is renewed; Développeurs › Serveur MCP lists the connected assistants, with "Revoke".

Connecting the assistant

  • Claude: Settings › Connectors › "Add custom connector", name "Escouade Meet", address https://meet.escouade.io/mcp; "Connect", then your Escouade account, the permissions, "Allow".
  • ChatGPT: in developer mode, a connector with the same address and OAuth authentication.
  • Claude Code:
Terminal
claude mcp add --transport http escouade-meet https://meet.escouade.io/mcp

A connector already connected to https://robotmeet.fr/mcp keeps working; moving to the new address means connecting it again, then revoking the old one.

This page in Markdown: /en/docs/meet/developpeurs.md All the docs for an agent: /en/docs/llms.txt Legal notice · Terms · Privacy · Service status