Naar de inhoud springen

Ontwikkelaars

Bouw op Mets

Een REST API en ondertekende webhooks voor vergaderingen, opnames, transcripties en AI-samenvattingen. Uw gegevens blijven in de EU.

Quickstart

Van nul tot een vergadering in drie stappen

Geen SDK nodig. Gewoon HTTPS en JSON.

  1. 1

    Een API-sleutel maken

    Open Instellingen, Ontwikkelaars, en maak een sleutel met alleen de rechten die u nodig hebt. Hij wordt één keer getoond.

  2. 2

    De API aanroepen

    Stuur de sleutel als Bearer-token mee. Maak vergaderingen, toon opnames, haal transcripties en samenvattingen op.

  3. 3

    Naar gebeurtenissen luisteren

    Voeg een webhook-endpoint toe en reageer wanneer een vergadering eindigt of een transcriptie gereed is, of raadpleeg de gebeurtenissenfeed.

Een vergadering makenbash
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", … }
Opnames weergevenbash
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

Weet het op het moment dat er iets gebeurt

Elke levering is een ondertekende HTTPS-POST. Mislukte leveringen worden met exponentiële uitstel opnieuw geprobeerd, in totaal vijf pogingen.

  • meeting.startedDe eerste deelnemer is binnengekomen en de vergadering is live.
  • meeting.endedDe vergadering is afgelopen.
  • recording.readyEen opname is verwerkt en kan worden gedownload.
  • transcript.readyDe transcriptie is compleet.
  • summary.readyDe AI-samenvatting is beschikbaar.
  • registration.createdIemand heeft zich geregistreerd voor een van uw webinars.
Een webhook-leveringhttp
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" } }
}

Verifieer elk verzoek

Mets ondertekent de body met het geheim van uw endpoint: X-Mets-Signature is sha256= gevolgd door de HMAC-SHA256 van de tijdstempel, een punt en de ruwe body. Vergelijk in constante tijd en weiger tijdstempels die ouder zijn dan vijf minuten.

Een webhook verifiëren (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))
  );
}
Een webhook verifiëren (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"])

Automatisering

Zapier, Make en n8n zonder code

Polling-triggers plus uitgaande webhooks – dezelfde events die u in de app ziet. Plus meldingen in Slack en Teams.

Polling-triggers

GET /api/v1/public/triggers/{event}?since= geeft events na uw laatste cursor. Zonder since krijgt u de meest recente – handig voor voorbeelddata.

  • meeting.started
  • meeting.ended
  • recording.ready
  • transcript.ready
  • summary.ready
  • registration.created
  • Zapier: app in integrations/zapier (API-sleutelauthenticatie, 6 triggers, acties: vergadering aanmaken, deelnemer registreren).
  • n8n: nodepakket integrations/n8n (Mets + Mets Trigger).
  • Make: HTTP-module + ondertekende uitgaande webhooks.
  • Slack en Teams: Instellingen → Integraties → Kanaalmeldingen.
Een trigger pollenbash
# newest first (first poll / sample), then follow next_cursor
curl -s -H "Authorization: Bearer $METS_API_KEY" \
  "https://mets.ulewicz.space/api/v1/public/triggers/summary.ready?limit=5"

curl -s -H "Authorization: Bearer $METS_API_KEY" \
  "https://mets.ulewicz.space/api/v1/public/triggers/registration.created?since=evt_1234&slug=my-webinar"

MCP

Vergaderingen voor AI-agents (MCP)

Een Model Context Protocol-server (Streamable HTTP). Claude, Cursor en andere agents lezen transcripten, doorzoeken vergaderingen en plannen nieuwe in.

Tools

Endpoint: POST https://mets.ulewicz.space/api/v1/mcp. Resources: mets://meetings/{id}/transcript en /summary.

  • list_meetingsVergaderingen weergeven (statusfilter).
  • get_meetingVergaderdetails op id of code.
  • get_transcriptTranscript als platte tekst, optioneel vertaald.
  • get_summaryAI-samenvatting: TL;DR, besluiten, actiepunten.
  • search_contentZoeken in volledige tekst door transcripten en chat.
  • ask_meetingsVraag in natuurlijke taal (RAG) met bronvermelding.
  • list_tasksVergadertaken en trackerlinks.
  • create_meetingDirecte vergadering met een deelnamelink.
  • schedule_meetingEen vergadering inplannen voor een bepaald tijdstip.

Authenticeer met een API-sleutel (Instellingen → Ontwikkelaar). De tools die u ziet hangen af van de scopes van de sleutel.

Claude Desktop (claude_desktop_config.json)json
{
  "mcpServers": {
    "mets": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mets.ulewicz.space/api/v1/mcp",
        "--header", "Authorization: Bearer ${METS_API_KEY}"
      ],
      "env": { "METS_API_KEY": "mets_sk_..." }
    }
  }
}
Cursor (.cursor/mcp.json)json
{
  "mcpServers": {
    "mets": {
      "url": "https://mets.ulewicz.space/api/v1/mcp",
      "headers": { "Authorization": "Bearer mets_sk_..." }
    }
  }
}
Claude Codebash
claude mcp add --transport http mets https://mets.ulewicz.space/api/v1/mcp \
  --header "Authorization: Bearer mets_sk_..."
Ruwe JSON-RPC-aanroepbash
curl -s https://mets.ulewicz.space/api/v1/mcp \
  -H "Authorization: Bearer $METS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"ask_meetings","arguments":{"question":"What did we decide about pricing?"}}}'

Insluiten

Plaats een Mets-vergadering in uw product

Een frameworkonafhankelijke SDK toont de ruimte in een iframe en communiceert met uw pagina via een klein, geversioneerd postMessage-protocol.

  1. 1

    Sta uw origins toe

    Alleen pagina's op de origins die u opgeeft mogen de ruimte insluiten. De lijst wordt door de browser afgedwongen via CSP frame-ancestors.

  2. 2

    Koppel de SDK

    Laad de script-tag, de ES-module of de React-component en wijs naar een vergadercode of een embed-token.

  3. 3

    Geef tokens uit op uw server

    Maak met uw API-sleutel een kortlevend token voor een gast met naam, zodat de code en de sleutel nooit de browser bereiken.

Parent-origins toestaanhttp
curl -X PUT https://mets.ulewicz.space/api/v1/public/meetings/abc-defg-hjk/embed-origins \
  -H "Authorization: Bearer mets_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "origins": ["https://app.example.com", "https://*.example.com"] }'
Script-taghtml
<div id="meeting" style="height: 640px"></div>
<script src="https://mets.ulewicz.space/embed/mets-embed.js"></script>
<script>
  const meeting = MetsEmbed.MetsMeeting.create({
    container: "#meeting",
    meetingCode: "abc-defg-hjk",
    name: "Anna",            // pre-filled guest name
    locale: "en",
    theme: "dark",
    features: { chat: true, participants: true },
    onEvent: (e) => console.log(e.type, e),
  });

  meeting.on("joined", (e) => console.log("in the room as", e.participant.name));
  meeting.on("participant-count", (e) => console.log(e.count, "people"));
  document.querySelector("#mute").onclick = () => meeting.mute();
</script>
ES-moduletypescript
npm install @mets/embed

import { MetsMeeting } from "@mets/embed";

const meeting = MetsMeeting.create({
  container: document.getElementById("meeting")!,
  joinToken, // from your server, see below
  onEvent: (e) => { if (e.type === "left") showThanks(); },
});
Reacttsx
npm install @mets/embed @mets/embed-react

import { MetsMeeting } from "@mets/embed-react";

export function Room({ joinToken }: { joinToken: string }) {
  const ref = useRef<MetsMeetingHandle>(null);
  return (
    <div style={{ height: 640 }}>
      <MetsMeeting ref={ref} joinToken={joinToken} locale="en" onEvent={(e) => console.log(e)} />
      <button onClick={() => ref.current?.mute()}>Mute</button>
    </div>
  );
}
Embed-token aan serverzijdehttp
# server side — the browser never sees the meeting code or your API key
curl -X POST https://mets.ulewicz.space/api/v1/public/embed/tokens \
  -H "Authorization: Bearer mets_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "meeting": "abc-defg-hjk", "name": "Anna Kowalska", "ttl_seconds": 600,
        "features": { "chat": false } }'

# 201
{ "token": "mets_et_eyJj...", "expires_at": "2026-10-09T12:10:00Z",
  "embed_url": "https://mets.ulewicz.space/en/embed/mets_et_eyJj...", "embeddable": true }

Events (iframe naar pagina)

  • readyDe ingesloten pagina is gestart en accepteert commando's.
  • joinedDe gast is de ruimte binnengekomen (deelnemer- en vergaderinfo).
  • leftDe gast is vertrokken, verwijderd of de vergadering is beëindigd (met reden).
  • participant-countAantal personen dat nu in de ruimte is.
  • recordingOpname gestart of gestopt (active, mode).
  • mediaDe lokale microfoon of camera is aan- of uitgezet.
  • errorDe vergadering is niet beschikbaar (niet gevonden, beëindigd, geannuleerd).

Commando's (pagina naar iframe)

  • muteDemp de lokale microfoon, of de camera met kind: "video".
  • unmuteZet de microfoon (of camera) weer aan.
  • leaveVerlaat de vergadering.
  • toggleChatOpen of sluit het chatpaneel.
  • setThemeWissel tussen licht, donker en systeemthema.
postMessage-protocoljs
// iframe -> host page (posted to exactly one validated origin)
{ source: "mets-embed", v: 1, dir: "event", type: "joined",
  participant: { identity, name, role }, meeting: { code, title } }

// host page -> iframe (accepted only from an allow-listed origin)
{ source: "mets-embed", v: 1, dir: "command", type: "setTheme", theme: "dark" }

Standaard vergrendeld

Zonder toegestane origins kan niets de ruimte insluiten. Events worden naar één gevalideerde origin gestuurd, commando's worden alleen daarvan geaccepteerd en embed-tokens zijn ondertekend, verlopen snel en leggen de gastnaam vast.

Referentie

Alles wat u nodig hebt, niets wat u niet nodig hebt

Twaalf endpoints dekken vergaderingen, opnames, transcripties, samenvattingen, webinarregistraties en gebeurtenissen.

Basis-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

API-sleutels met beperkte rechten

Authorization: Bearer mets_sk_…. Sleutels dragen alleen de rechten die u verleent en kunnen worden beperkt tot een organisatie, verlopen of op elk moment worden ingetrokken.

Eerlijke rate limits

120 verzoeken per minuut en pieken van 20 per seconde per sleutel. Elk antwoord bevat X-RateLimit-headers.

OpenAPI 3

Een volledig machineleesbaar schema en een interactieve console om verzoeken uit te proberen.

De interactieve referentie openen

API inbegrepen in Business

De Public API en webhooks zijn onderdeel van het abonnement Business, zonder kosten per verzoek. Hebt u hogere limieten of een overeenkomst op maat nodig? Schrijf ons.

Lever vandaag nog uw eerste integratie op

Maak een account, genereer een sleutel en doe binnen enkele minuten uw eerste verzoek.