# Metered TURN Server Service — llms.txt reference Metered TURN Servers as a Service provide a globally distributed relay network for WebRTC traffic. The service guarantees connectivity through NATs and firewalls via TURN (Traversal Using Relays around NAT). - 31+ regions, 100+ edge PoPs, <30 ms latency, 99.999% uptime SLA - UDP, TCP, TLS, DTLS on ports 80/443. No bandwidth caps per allocation. - Standards: STUN (RFC 5389), TURN (RFC 5766), ICE - Private high-speed backbone for cross-continent relay - REST API for credentials, usage tracking, project isolation - Dashboard: https://dashboard.metered.ca | Pricing: https://www.metered.ca/pricing ## Getting Started 1. **Sign up** at https://dashboard.metered.ca/signup to create a free Metered account. 2. Your **app name** (e.g. `yourappname`) is shown on the Dashboard home page. It forms part of the REST API base URL: `https://yourappname.metered.live/api/v1/turn/`. 3. Go to **Dashboard → Developers** to find your **Secret Key**. Use this for all server-side API calls (creating credentials, fetching usage, managing projects). Never expose it in front-end code. 4. **Create a TURN credential**: Go to **Dashboard → TURN Server → Credentials** and click **Create Credential** (classic dashboard: **TURN Server** page → **Add Credential**), or use the Create Credential REST API. Each credential gets: - `username` and `password` — used in the ICE server config for WebRTC connections - `apiKey` — a credential-scoped key, **safe for front-end use**, used only with the Get Credential API to fetch the ICE server config 5. Click **Get credential → Show ICE Servers Array** on any credential (classic dashboard: the **Show ICE Servers Array** button on the row) to get a ready-to-use ICE config for your WebRTC app. The **ICE** button on a row copies the same array to the clipboard. **Two dashboards.** Metered has a redesigned dashboard (https://dashboard.metered.ca/v2) and the classic dashboard; both manage the same account, and the API is identical. Users switch with the **Old dashboard** button (new → classic) or by opening /v2 (classic → new). Navigation map (new → classic): - TURN Server → **Credentials** → *Create Credential* ↔ TURN Server page → *Add Credential* - Credentials row → **Get credential** → *Show ICE Servers Array* / *Show API Key* / *Delete credential* ↔ row buttons *Show ICE Servers Array* / *Show API Key* / *Remove* - Credentials row → **ICE** button copies the ICE servers array to the clipboard (no classic equivalent) - Credentials page → **TURN region** card (new: also a per-credential *Region* in Create Credential) ↔ TURN Server page → *Default TURN Server Region* dropdown - TURN Server → **Projects** → *New project* / card *Edit* / *Manage* ↔ Projects section on the TURN Server page → *Create Project* / *Edit Project* / *Manage TURN Credentials* - TURN Server → **Analytics** (new only), **Emergency support** page ↔ Emergency Phone Support panel on the TURN Server page - **Developers** → *Reveal* / *Reissue it* ↔ Developers → secret key shown / *Regenerate Secret Key* - **Plans & pricing** page, *Manage subscription* ↔ plan cards at the bottom of the TURN Server page - Account → **Billing** → *Auto-reload* / *Add Funds* / *Usage History* / *Payment History*; Account → **Team**; Account → **Branding** ↔ Account → *Automatic Billing* / *Add Funds* / *Usage History* / *Payment History* / *Members* / *Custom Branding* **Three types of API keys:** - **`secretKey`** — account-scoped, server-side only. Found in Dashboard → Developers. - **`apiKey`** — credential-scoped, safe for front-end. Returned when creating a credential. Used only for the Get Credential endpoint. - **`projectApiKey`** — project-scoped, alternative to secretKey for project-level operations. Found in Dashboard → TURN Server → Projects. --- ## Overview & Setup ICE tries connections in order: host candidates (direct), STUN (public IP discovery), then TURN (full relay fallback). TURN guarantees connectivity through symmetric NAT, carrier-grade NAT, and strict firewalls. The relay forwards encrypted payloads (SRTP/DTLS) without decrypting them. Use cases: voice/video calls, live streaming, IoT devices, AI/3D/AR/VR, surveillance, DataChannels (chat, gaming, file-share). ### Custom Domain Point a CNAME at Metered infrastructure (global or region-specific hostname). TURN over TCP and UDP work with CNAME; TURN over TLS does not. --- ## TURN URLs & Ports ### Global Endpoint (recommended) `global.relay.metered.ca` — automatic geo-routing to nearest edge. STUN: `stun:stun.relay.metered.ca:80` | Port | Protocol | URI | |------|----------|--------------------------------------------------| | 80 | UDP | turn:global.relay.metered.ca:80 | | 80 | TCP | turn:global.relay.metered.ca:80?transport=tcp | | 443 | UDP | turn:global.relay.metered.ca:443 | | 443 | TLS | turns:global.relay.metered.ca:443?transport=tcp | Best practice: include multiple entries (UDP first, then TCP/TLS) for ICE fallback. ### Recommended ICE Servers Array ```json [ { "urls": "stun:stun.relay.metered.ca:80" }, { "urls": "turn:global.relay.metered.ca:80", "username": "", "credential": "" }, { "urls": "turn:global.relay.metered.ca:80?transport=tcp", "username": "", "credential": "" }, { "urls": "turn:global.relay.metered.ca:443", "username": "", "credential": "" }, { "urls": "turns:global.relay.metered.ca:443?transport=tcp", "username": "", "credential": "" } ] ``` ### Region-Specific Endpoints All use ports 80/443. Paid plans only (free plan: `standard.relay.metered.ca` only). | Region | Endpoint | API region value | |------------------|--------------------------------|---------------------| | Global | global.relay.metered.ca | global | | North America | na.relay.metered.ca | north_america | | Europe | europe.relay.metered.ca | europe | | European Union | eu.relay.metered.ca | eu | | Asia | asia.relay.metered.ca | asia | | Oceania | oceania.relay.metered.ca | oceania | | US West | us-west.relay.metered.ca | us_west | | US Central | us-central.relay.metered.ca | us_central | | US East | us-east.relay.metered.ca | us_east | | Canada Central | ca-central.relay.metered.ca | canada_central | | Canada East | ca-east.relay.metered.ca | canada_east | | Europe West | eu-west.relay.metered.ca | europe_west | | Europe Central | eu-central.relay.metered.ca | europe_central | | Asia West | asia-west.relay.metered.ca | asia_west | | Asia East | asia-east.relay.metered.ca | asia_east | | Middle East | middle-east.relay.metered.ca | middle_east | | Canada | ca.relay.metered.ca | canada | | USA | us.relay.metered.ca | usa | | UK | uk.relay.metered.ca | uk | | Singapore | sg.relay.metered.ca | singapore | | India | in.relay.metered.ca | india | | Seoul | seoul.relay.metered.ca | seoul | | France | fr.relay.metered.ca | france | | Germany | de.relay.metered.ca | germany | | Italy | it.relay.metered.ca | italy | | Japan | jp.relay.metered.ca | japan | | Sweden | se.relay.metered.ca | sweden | | Spain | es.relay.metered.ca | spain | | Netherlands | nl.relay.metered.ca | netherlands | | Australia | au.relay.metered.ca | australia | | Qatar | qa.relay.metered.ca | qatar | | Standard (free) | standard.relay.metered.ca | standard | --- ## Creating Credentials **Dashboard**: Log into https://dashboard.metered.ca -> TURN Server -> Credentials -> "Create Credential", then the row's "Get credential" -> "Show ICE Servers Array" to get the config (classic dashboard: TURN Server page -> "Add Credential" -> "Show ICE Servers Array"). **REST API**: POST to Create Credential endpoint (see below). Response includes `username`, `password`, and `apiKey`. Use the `apiKey` to call Get Credential from the front-end. The `apiKey` is credential-scoped and safe for front-end use. The `secretKey` must never be exposed in front-end code. **Propagation delay**: a newly created credential is not usable immediately. It has to propagate across the global TURN network, which can take **up to 2 minutes**. Before it has propagated, an authenticated Allocate can be rejected and no relay candidate is gathered, even though the credential is valid. Never create a credential at call-setup time; create it ahead of time from the back-end and reuse it. See "Rotating Credentials" below. --- ## Region Pinning **Dashboard**: Pick the region in the "TURN region" card on the Credentials page, or set a per-credential Region in "Create Credential" (classic dashboard: the "Default TURN Server Region" dropdown); "Show ICE Servers Array" then returns region-scoped endpoints. **API**: Pass `region` query param to Get Credential API for a specific region. Omit it to use the credential's own region if it was pinned when created on the new dashboard (paid plans), otherwise the dashboard default. Different credentials can target different regions. **Dynamic updates**: If you use the Get Credential API (with `apiKey`), changing the dashboard region automatically updates what the API returns (for credentials without their own pinned region). --- ## REST API — Authentication Replace `` with your app name (Dashboard -> Developers). **v1 endpoints** (base: `https://.metered.live/api/v1/turn/`): Get Credential, Create Credential, Enable Credential, Disable Credential, Delete Credential, Current Usage, Current Usage by Date, Current Usage for User. **v2 endpoints** (base: `https://.metered.live/api/v2/turn/`): Update Credential Label, List Credentials, Current Usage by User, Daily Usage by User, Delete Credential by Label, all Project endpoints. **v2 payment endpoint** (base: `https://.metered.live/api/v2/payment/`): Get Usage Charges — note this uses `/api/v2/payment/`, NOT `/api/v2/turn/`. Each endpoint below shows its full path including the correct version prefix. Auth methods (all via query param): 1. `apiKey` — credential-scoped, safe for front-end. Only for Get Credential endpoint. 2. `secretKey` — account-scoped, server-side only. Dashboard -> Developers. 3. `projectApiKey` — project-scoped, alternative to secretKey for project endpoints. --- ## REST API — Credentials ### Get TURN Credential (ICE Servers Array) Returns the ICE Servers array. Safe for front-end use. ``` GET /api/v1/turn/credentials?apiKey= ``` Query: `apiKey` (required), `region` (optional, overrides dashboard default). Response `200 OK` — array of ICE server objects (STUN + TURN entries with urls, username, credential). Errors: `400` (no API key), `401` (invalid API key). ### Create TURN Credential ``` POST /api/v1/turn/credential?secretKey= Content-Type: application/json ``` Body (JSON): - `expiryInSeconds` (integer, optional) — auto-expire after this many seconds - `label` (string, optional) — a label for the credential Response `200 OK` — object with `username`, `password`, `expiryInSeconds`, `label`, `apiKey`. Errors: `400` (invalid expiry or not subscribed). **Propagation delay**: a newly created credential is not usable immediately. It has to propagate across the global TURN network, which can take **up to 2 minutes**. Before it has propagated, an authenticated Allocate can be rejected and no relay candidate is gathered, even though the credential is valid. Never create a credential at call-setup time; create it ahead of time from the back-end and reuse it. See "Rotating Credentials" below. ### Enable TURN Credential Re-enables a previously disabled credential. ``` POST /api/v1/turn/credential/enable?secretKey= ``` Body: `{ "username": "" }` Response `200 OK`: `{ "message": "Credential enabled successfully" }` Errors: `400` (missing username, already enabled), `401` (invalid key, not found). ### Disable TURN Credential ``` POST /api/v1/turn/credential/disable?secretKey= ``` Body: `{ "username": "" }` Response `200 OK`: `{ "message": "Turn credential disabled successfully" }` Errors: `400` (missing username, already disabled), `401` (not found). ### Delete TURN Credential ``` DELETE /api/v1/turn/credential?secretKey= ``` Body: `{ "username": "" }` Response `200 OK`: `{ "success": true, "message": "credential removed" }` Errors: `400` (credential not found). ### Update TURN Credential Label ``` POST /api/v2/turn/credential/update_label?secretKey=&username= ``` Body: `{ "label": "" }` Response `200 OK` — object with `username`, `password`, `expiryInSeconds`, `label`, `apiKey`. Errors: `400` (credential not found). ### List TURN Credentials (v2) ``` GET /api/v2/turn/credentials?secretKey= ``` Query params: - `secretKey` (string, required) - `all` (boolean, optional) — include expired credentials; default false - `page` (integer, optional) — page number for pagination - `label` (string, optional) — filter by label Response `200 OK` — object with `data[]` and `pagination`. Each credential in `data[]`: `username`, `password`, `apiKey`, `expiryInSeconds`, `label`, `expired` (bool). `pagination`: `total_records`, `current_page`, `total_pages`, `next_page`, `prev_page`. Errors: `400` (not subscribed, not available under free plan). ### Delete TURN Credential by Label Deletes all active (non-expired) credentials matching a label. ``` DELETE /api/v2/turn/credential/by_label?secretKey=&label=