Developers
Build on Mets
A REST API and signed webhooks for meetings, recordings, transcripts and AI summaries. Your data stays in the EU.
Quickstart
From zero to a meeting in three steps
No SDK required. Plain HTTPS and JSON.
- 1
Create an API key
Open Settings, Developers, and create a key with only the permissions you need. It is shown once.
- 2
Call the API
Send the key as a Bearer token. Create meetings, list recordings, fetch transcripts and summaries.
- 3
Listen for events
Add a webhook endpoint and react when a meeting ends or a transcript is ready, or poll the events feed.
curl -X POST https://mets.ulewicz.space/api/v1/public/meetings \
-H "Authorization: Bearer $METS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Weekly sync",
"scheduled_at": "2026-11-03T09:00:00+01:00",
"duration_minutes": 30,
"settings": { "waiting_room": true, "transcription_auto": true }
}'
# -> 201 { "id": "…", "code": "abc-defg-hjk", "join_url": "https://mets.ulewicz.space/m/abc-defg-hjk", … }curl https://mets.ulewicz.space/api/v1/public/meetings/abc-defg-hjk/recordings \
-H "Authorization: Bearer $METS_API_KEY"
# -> { "data": [ { "id": "…", "kind": "video", "status": "ready",
# "duration_seconds": 1834, "download_url": "https://…" } ] }Webhooks
Know the moment something happens
Each delivery is a signed HTTPS POST. Failed deliveries are retried with exponential back-off, five attempts in total.
meeting.startedThe first participant joined and the meeting is live.meeting.endedThe meeting finished.recording.readyA recording has been processed and can be downloaded.transcript.readyThe transcript is complete.summary.readyThe AI summary is available.registration.createdSomeone registered for one of your webinars.
POST https://your-server.example/webhooks/mets
X-Mets-Event: meeting.ended
X-Mets-Delivery: 7c0f…
X-Mets-Timestamp: 1790000000
X-Mets-Signature: sha256=9f2b…
{
"id": "evt_1042",
"type": "meeting.ended",
"created_at": "2026-11-03T09:31:07Z",
"data": { "meeting": { "id": "…", "code": "abc-defg-hjk", "title": "Weekly sync", "status": "ended" } }
}Verify every request
Mets signs the body with your endpoint secret: X-Mets-Signature is sha256= followed by the HMAC-SHA256 of the timestamp, a dot and the raw body. Compare in constant time and reject timestamps older than five minutes.
import crypto from "node:crypto";
// Express: use express.raw({ type: "application/json" }) so you get the exact bytes.
export function verify(rawBody, headers, secret) {
const ts = headers["x-mets-timestamp"];
const expected =
"sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
const given = headers["x-mets-signature"] ?? "";
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300; // reject replays
return (
fresh &&
given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))
);
}import hashlib, hmac, time
def verify(raw_body: bytes, headers: dict, secret: str) -> bool:
ts = headers["X-Mets-Timestamp"]
mac = hmac.new(secret.encode(), ts.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
expected = "sha256=" + mac
fresh = abs(time.time() - int(ts)) < 300 # reject replays
return fresh and hmac.compare_digest(expected, headers["X-Mets-Signature"])Reference
Everything you need, nothing you do not
Twelve endpoints cover meetings, recordings, transcripts, summaries, webinar registrations and events.
- GET
/me— - GET
/meetingsmeetings:read - POST
/meetingsmeetings:write - GET
/meetings/{id}meetings:read - PATCH
/meetings/{id}meetings:write - DELETE
/meetings/{id}meetings:write - GET
/meetings/{id}/participantsmeetings:read - GET
/meetings/{id}/recordingsrecordings:read - GET
/meetings/{id}/transcripttranscripts:read - GET
/meetings/{id}/summarytranscripts:read - POST
/webinars/{slug}/registrationswebinars:write - GET
/eventsmeetings:read
Scoped API keys
Authorization: Bearer mets_sk_…. Keys carry only the permissions you grant and can be limited to an organization, expire or be revoked at any time.
Fair rate limits
120 requests per minute and bursts of 20 per second per key. Every response carries X-RateLimit headers.
OpenAPI 3
A complete machine-readable schema and an interactive console to try requests.
API included in Business
The Public API and webhooks come with the Business plan, with no per-request fees. Need higher limits or a custom agreement? Write to us.
Ship your first integration today
Create an account, generate a key and make your first request in minutes.