Create Meeting Tokens on Your Server
Your server holds the secret key. It makes the room, then one token for each person who joins.
Every example reads the key from the environment, makes a private room with a name Meet generates, and mints a host token valid for one hour. Set the key first:
export MEET_API_KEY=mk_test_xxxxxxxxNever put the key in a web page, a mobile app or a repository. Give the browser only the token.
Publishing. The SDK packages are not on npm, PyPI, Packagist or the Go module proxy yet. Until they are, the REST API works from any language over plain HTTPS: every REST reference page has a curl example.
Node#
npm i @respiresoft/meet// token.mjs (Node 18 or newer)
import { Meet } from "@respiresoft/meet";
const meet = new Meet({ apiKey: process.env.MEET_API_KEY });
const room = await meet.rooms.create({ privacy: "private" });
const { token, url } = await meet.rooms.createToken(room.name, {
user_id: "u-77", name: "Ann", role: "host", ttl: 3600,
});
console.log(room.name, url); // send `token` and `room.url` to the browserRun it with node token.mjs. The SDK retries on 429 and 5xx, and adds an Idempotency-Key to every POST. Details are in the
Node SDK page.
Python#
pip install respiresoft-meet# token.py (Python 3.10 or newer)
import os
from respiresoft_meet import Meet
meet = Meet(api_key=os.environ["MEET_API_KEY"])
room = meet.rooms.create(privacy="private")
result = meet.rooms.create_token(room["name"], user_id="u-77", user_name="Ann", role="host", ttl=3600)
print(room["name"], result["url"]) # send result["token"] and room["url"] to the browserPHP#
No package is needed. This uses the cURL extension that ships with PHP.
<?php
// token.php (PHP 8 with ext-curl)
function meet(string $method, string $path, ?array $body = null): array {
$ch = curl_init("https://meet.respiresoft.com" . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("MEET_API_KEY"),
"Content-Type: application/json",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => $body === null ? null : json_encode($body),
CURLOPT_TIMEOUT => 15,
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
$data = json_decode((string) $raw, true) ?? [];
if ($status >= 400) {
throw new RuntimeException(($data["error"]["code"] ?? "error") . ": " . ($data["error"]["message"] ?? $status));
}
return $data;
}
$room = meet("POST", "/api/v1/rooms", ["privacy" => "private"]);
$token = meet("POST", "/api/v1/rooms/" . rawurlencode($room["name"]) . "/tokens",
["user_id" => "u-77", "name" => "Ann", "role" => "host", "ttl" => 3600]);
echo $room["name"], " ", $token["url"], "\n";Go#
No package is needed. This uses the standard library.
// token.go (Go 1.21 or newer)
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"time"
)
var client = &http.Client{Timeout: 15 * time.Second}
func meet(method, path string, body any, out any) error {
var rd *bytes.Reader
if body != nil {
b, _ := json.Marshal(body)
rd = bytes.NewReader(b)
} else {
rd = bytes.NewReader(nil)
}
req, _ := http.NewRequest(method, "https://meet.respiresoft.com"+path, rd)
req.Header.Set("Authorization", "Bearer "+os.Getenv("MEET_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode >= 400 {
var e struct{ Error struct{ Code, Message string } }
json.NewDecoder(res.Body).Decode(&e)
return fmt.Errorf("%d %s: %s", res.StatusCode, e.Error.Code, e.Error.Message)
}
return json.NewDecoder(res.Body).Decode(out)
}
func main() {
var room struct{ Name, URL string }
if err := meet("POST", "/api/v1/rooms", map[string]any{"privacy": "private"}, &room); err != nil {
panic(err)
}
var tok struct{ Token, URL string }
err := meet("POST", "/api/v1/rooms/"+url.PathEscape(room.Name)+"/tokens",
map[string]any{"user_id": "u-77", "name": "Ann", "role": "host", "ttl": 3600}, &tok)
if err != nil {
panic(err)
}
fmt.Println(room.Name, tok.URL)
}Run it with go run token.go. Go decodes JSON keys without regard to case, so Name, URL and Token match name, url and token.
What to do with the token#
Send token (and the room's url) to the browser of that one person, then pass them to
Meet.embed or add ?token= to the room link. A token works in one room only. Mint a new one each time
a person opens the meeting. Read Meeting tokens for the roles and permissions you can set.
Errors you may meet#
| Status and code | What to do |
|---|---|
401 invalid_api_key |
The key is wrong or revoked. Make a new one in the dashboard. |
409 room_exists |
Room names are unique across Meet. Leave name out to get a generated one. |
429 rate_limited |
Wait the Retry-After seconds. The limit is 120 requests a minute for each key. |
The full list is in Errors.