Skip to content

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. 1

    Create an API key

    Open Settings, Developers, and create a key with only the permissions you need. It is shown once.

  2. 2

    Call the API

    Send the key as a Bearer token. Create meetings, list recordings, fetch transcripts and summaries.

  3. 3

    Listen for events

    Add a webhook endpoint and react when a meeting ends or a transcript is ready, or poll the events feed.

Create a meetingbash
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", … }
List recordingsbash
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.
A webhook deliveryhttp
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.

Verify a webhook (Node.js)node.js
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))
  );
}
Verify a webhook (Python)python
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.

Base URL: https://mets.ulewicz.space/api/v1/public
  • 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.

Open the interactive reference

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.