Skip to main content

Build with AI

Use Claude Code, Cursor, GitHub Copilot, ChatGPT, or any AI coding tool to build with Metered. We provide machine-readable reference files that give your AI tool the complete context it needs to write working code with our APIs and SDKs.

Reference Files​

All reference files in one place. Use the product-specific file when working with a single product to keep the AI's context focused.

ProductReference FileSize
Embed SDKllms-embed.txt15.3 KiB
Video SDKllms-video-sdk.txt52.9 KiB
TURN Serverllms-turn-server.txt30.4 KiB
Realtime Messaging — JavaScript SDKllms-realtime-messaging-sdk.txt28.3 KiB
Realtime Messaging — Python SDKllms-realtime-messaging-python-sdk.txt21.8 KiB
Realtime Messaging — Flutter SDKllms-realtime-messaging-flutter-sdk.txt20.2 KiB
Realtime Messaging — Raw WebSocketllms-realtime-messaging-raw-websocket.txt17.0 KiB
Realtime Messaging — Everythingllms-realtime-messaging.txt30.6 KiB
Global Cloud SFUllms-sfu.txt18.2 KiB
Everythingllms-full.txt117.8 KiB

OpenAPI 3.0 spec for the Video SDK REST API: video-rest-api-openapi.yaml

Quick action — get building in 30 seconds
  1. Download the reference file for your product from the table above (right-click → Save link as…)
  2. Give it to your AI agent — drop the .txt file into Claude Code, Cursor, Copilot, ChatGPT, or any AI coding tool
  3. Describe what you want to build — pick a prompt template from What Are You Building? below, or write your own

What Are You Building?​

Pick your use case — each one links to the right reference file and a ready-to-use prompt.

I want to add video chat to my app in minutes​

Use the Embed SDK — drop an iframe-based video chat into any website or app with a few lines of code. No complex WebRTC setup needed.

Quick start with AI:

Read https://www.metered.ca/docs/llms-embed.txt

Help me embed Metered video chat into my app:
- Create a MeteredFrame component
- Auto-join a specific room on page load
- Listen for participant join/leave events
- Add a button to toggle the chat panel

The room URL is: YOUR_APP_NAME.metered.live/YOUR_ROOM_NAME

Reference file: llms-embed.txt | Full docs: Embed SDK Guide


I want to build a custom video/voice calling app​

Use the Video SDK — full control over the video calling experience with a JavaScript SDK for the client and a REST API for room management, recording, live streaming, composition, and RTMP out.

Quick start with AI:

Read https://www.metered.ca/docs/llms-video-sdk.txt

Build a group video calling application with:
- Create a room via the REST API
- Join the room using the JavaScript SDK
- Display local and all remote video streams
- Mute/unmute audio and pause/resume video controls
- Show list of online participants
- Handle participants joining and leaving

Use vanilla JavaScript with the Metered CDN SDK.
My Metered app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Reference file: llms-video-sdk.txt | Full docs: Video SDK Basic Guide


I need a TURN server for my WebRTC app​

Use the TURN Server Service — a globally distributed relay network (31+ regions, 99.999% uptime) that guarantees WebRTC connectivity through NATs and firewalls. Works with any WebRTC app, not just Metered.

Quick start with AI:

Read https://www.metered.ca/docs/llms-turn-server.txt

Help me build a Node.js service that:
- Creates TURN credentials via the Metered REST API
- Sets credentials to auto-expire after 24 hours
- Serves the ICE server configuration to my WebRTC client
- Monitors usage per credential

My Metered app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Reference file: llms-turn-server.txt | Full docs: TURN Server Overview


I need WebRTC signalling (with Metered TURN auto-included)​

Use Realtime Messaging — a bi-directional WebSocket service that handles SDP / ICE exchange between peers, auto-injects Metered TURN credentials into the connect-time welcome message, and works with the official @metered-ca/realtime SDK or raw WebSocket from any stack.

Quick start with AI (JavaScript / TypeScript):

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a WebRTC video calling app using @metered-ca/realtime:
- Use the MeteredPeer class for channel + per-peer WebRTC orchestration
- Join a room channel and discover peers via presence
- Attach the local camera + mic with addStream(localStream, { role: "camera" })
- Render each remote via the stream-added event
- Show a "reconnecting…" banner on state-change to "reconnecting"
- Handle the unified `error` event for terminal close codes

Use a backend route to mint a JWT (no need to embed iceServers — Metered
TURN is auto-injected when the signalling key has auto-inject enabled).
My Metered app name is: YOUR_APP_NAME
My realtime-messaging key id is: sk_id_YOUR_KEY_ID
My Realtime Messaging secret key is in METERED_REALTIME_SK on my backend. Use it only server-side, to mint client tokens.

Reference file: llms-realtime-messaging-sdk.txt | Full docs: Realtime Messaging SDK · WebRTC Video Call guide


I need real-time pub/sub for chat, AI agents, IoT, or collaborative apps​

Use Realtime Messaging — channel-based pub/sub + directed messaging over WebSocket. Built-in presence with per-peer metadata (usernames, avatars, roles), JWT-based per-user authorization, REST control plane for server-side publishing. Works for live chat, classroom rosters, multi-agent AI coordination, IoT telemetry firehoses, and collaborative cursors.

Quick start with AI (JavaScript / TypeScript):

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a live chat room with @metered-ca/realtime's SignallingClient:
- Connect with a backend-minted JWT carrying { peerMetadata: { username, avatarUrl } }
- Subscribe to a chat channel and render the presence roster from joined/left events
- Send chat messages via publish() and render them from the message event
- Show typing indicators using the same channel, debounced to once per 3 seconds
- Use senderMetadata to render display names on each incoming message
- Add an "auto-reconnecting" indicator when state goes to "reconnecting"

Use vanilla JS with the @metered-ca/realtime npm package.
My Metered app name is: YOUR_APP_NAME
My realtime-messaging key id is: sk_id_YOUR_KEY_ID
My Realtime Messaging secret key is in METERED_REALTIME_SK on my backend. Use it only server-side, to mint client tokens.

Reference file: llms-realtime-messaging-sdk.txt | Full docs: Realtime Messaging SDK · Presence & Chat guide · AI agent guide · IoT telemetry guide


I'm building a React Native mobile app (iOS + Android)​

React Native runs the same @metered-ca/realtime SDK as the browser — you just supply WebRTC with react-native-webrtc. Use the SDK reference file (not the raw-WebSocket one).

Quick start with AI (React Native):

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a React Native video call screen with @metered-ca/realtime and react-native-webrtc:
- Wire the SDK to react-native-webrtc via the rtcPeerConnectionFactory option
- Capture camera + mic with mediaDevices.getUserMedia, then addStream(stream, { role: "camera" })
- Render each remote with <RTCView streamURL={stream.toURL()} /> on the stream-added event
- Re-read .toURL() on every stream-added so the view survives reconnect
- Show a "reconnecting…" banner on state-change to "reconnecting"
- Handle the unified error event for terminal close codes

Target Expo with a dev build (the @config-plugins/react-native-webrtc plugin), not Expo Go.
My Metered app name is: YOUR_APP_NAME
My realtime-messaging key is: pk_live_YOUR_KEY

Reference file: llms-realtime-messaging-sdk.txt | Full docs: React Native guide · React Native example


I'm building a Python app — AI voice agents, IoT bridges, or server-side WebRTC​

Use the metered-realtime Python SDK — an async (asyncio) port built on aiortc. Python is where the "agent in the room" lives: AI voice agents that join a call to run STT → LLM → TTS, IoT/telemetry bridges, recording bots, and headless automation. Same MeteredPeer orchestration, presence, auto-reconnect, and multi-stream metadata as the JavaScript SDK, with a Pythonic API (async/await, @peer.on(...) handlers, async with lifecycle).

Quick start with AI (Python):

Read https://www.metered.ca/docs/llms-realtime-messaging-python-sdk.txt

Build a Python AI voice agent that joins a room and talks to a browser peer using metered-realtime:
- pip install "metered-realtime[webrtc]"
- async with MeteredPeer(api_key=...) as peer: await peer.join("room")
- On the PeerJoined event, listen for the remote's Track event and consume inbound audio frames
- Push synthesized TTS audio into the room with AudioSource + add_stream(...)
- Open a DataChannel for a text control plane alongside the audio
- Re-attach media on the remote's StateChange -> "connected" so it survives reconnects

My realtime-messaging key is: pk_live_YOUR_KEY

Reference file: llms-realtime-messaging-python-sdk.txt | Full docs: Python SDK · AI agent communication guide · Audio agent example


I'm building a Flutter app (iOS + Android + web)​

Use the metered_realtime package — the native Dart/Flutter SDK for Realtime Messaging. It speaks the same wire protocol as the JavaScript SDK (a Flutter peer and a browser peer share a channel), with WebRTC provided by flutter_webrtc. Use the Flutter reference file below, not the raw-WebSocket one.

Quick start with AI (Flutter / Dart):

Read https://www.metered.ca/docs/llms-realtime-messaging-flutter-sdk.txt

Build a Flutter video call screen with the metered_realtime package and flutter_webrtc:
- Create MeteredPeer(MeteredPeerOptions(apiKey: 'pk_live_...')) (or a tokenProvider for production)
- Capture camera + mic with getUserMedia, then peer.addStream(wrapMediaStream(stream), metadata: {'role': 'camera'})
- On peer.onPeerJoined, subscribe to remote.onStreamAdded and bind (ev.stream as FlutterWebrtcMediaStream).native to an RTCVideoRenderer shown with RTCVideoView
- Re-bind the renderer on every onStreamAdded so the view survives reconnect
- Show a "reconnecting…" banner when the connection state changes to "reconnecting"
- Declare camera/mic permissions in AndroidManifest.xml and iOS Info.plist

My Metered app name is: YOUR_APP_NAME
My realtime-messaging key is: pk_live_YOUR_KEY

Reference file: llms-realtime-messaging-flutter-sdk.txt | Full docs: Flutter SDK · WebRTC Video Call guide


I'm building with another non-JavaScript stack (Swift, Kotlin, Go, Rust, Unity, etc.)​

The @metered-ca/realtime SDK covers JavaScript, TypeScript, and React Native; Python has its own metered-realtime SDK and Flutter has its own metered_realtime package (both above). For any other non-JS stack — native Swift/iOS, native Kotlin/Android, Go, Rust, Unity/C#, etc. — implement the Realtime Messaging WebSocket wire protocol directly. It's a small JSON-over-WebSocket protocol with 4 client message types and 7 server message types.

Quick start with AI (any non-JS stack):

Read https://www.metered.ca/docs/llms-realtime-messaging-raw-websocket.txt

Build a Realtime Messaging client in [Go / Swift / Rust / Unity / etc.]:
- Connect via WebSocket to wss://rms.metered.ca/v1?token=<jwt>
- Handle the welcome / ack / error / message / direct / presence / going_away frames
- Send subscribe / unsubscribe / publish / send frames
- Mint the JWT server-side (HS256, signed with sk_secret_…, kid header = sk_id_…)
- Implement exponential backoff + jitter for reconnects (terminal codes 4001/4003/4012/4020)
- Re-subscribe to all channels after each reconnect

My Metered app name is: YOUR_APP_NAME
My realtime-messaging sk_id is: sk_id_YOUR_KEY_ID
My Realtime Messaging secret key is in METERED_REALTIME_SK on my backend. Use it only server-side, to mint client tokens.

Reference file: llms-realtime-messaging-raw-websocket.txt | Full docs: Wire Format · Authentication · Use Case Guides


I want to build a custom real-time streaming platform​

Use the Global Cloud SFU — a pub-sub service for audio, video, and data channels using native WebRTC API and HTTP. No SDK required. Build broadcasting, surveillance, AR/VR, or any custom real-time app.

Quick start with AI:

Read https://www.metered.ca/docs/llms-sfu.txt

Build a broadcasting app where:
- A publisher connects to the SFU and publishes their camera + microphone
- Viewers can subscribe to the published tracks
- Use the native WebRTC API (no external SDK)
- Use fetch() for all HTTP API calls to the SFU

My SFU App ID is: YOUR_SFU_APP_ID
My SFU app secret is in the SFU_APP_SECRET environment variable on my server; use it only in server-side calls.

Reference file: llms-sfu.txt | Full docs: SFU Quick Start Guide


More Prompt Templates​

Once you've picked your product, here are additional prompts for common tasks.

Video SDK​

Add recording to an existing app​

Read https://www.metered.ca/docs/llms-video-sdk.txt

I have an existing Metered video call app. Help me add:
- Start/stop recording via the REST API
- List all recordings for a room
- Download a specific recording
- Delete old recordings

Show me the REST API calls needed with fetch() examples.
My app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Set up live streaming with HLS​

Read https://www.metered.ca/docs/llms-video-sdk.txt

Help me set up HLS live streaming for a Metered video meeting:
- Create a room with live streaming enabled
- Start the live stream
- Build a viewer page that plays the HLS stream
- Stop the stream when the meeting ends

My app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Stream to YouTube Live / Twitch via RTMP​

Read https://www.metered.ca/docs/llms-video-sdk.txt

Help me stream a Metered video meeting to YouTube Live via RTMP:
- Create a room with RTMP out enabled
- Configure the RTMP ingest URL from YouTube
- Start and stop the stream

My app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

TURN Server​

Set up TURN with region pinning for GDPR​

Read https://www.metered.ca/docs/llms-turn-server.txt

I need to restrict TURN server traffic to the EU region for GDPR compliance.
Help me:
- Identify the correct EU region-specific TURN endpoints
- Configure my ICE servers to use only EU relays
- Create credentials pinned to the EU region

My Metered app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Set up multi-tenant TURN with projects​

Read https://www.metered.ca/docs/llms-turn-server.txt

I have a multi-tenant app and need separate TURN credential management per tenant.
Help me:
- Create a TURN project per tenant via the REST API
- Set usage quotas per project
- Create and manage credentials within each project
- Monitor usage per project

My Metered app name is: YOUR_APP_NAME
My Metered secret key is in the METERED_SECRET_KEY environment variable on my server. Read it from there; never hard-code it or send it to the browser.

Realtime Messaging​

Build a WebRTC video call with the SDK (no manual SDP/ICE)​

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a multi-party WebRTC video call using @metered-ca/realtime's MeteredPeer class:
- Backend route to mint a JWT (no need to embed iceServers — Metered TURN is auto-injected when the secret key has "Auto-inject TURN" enabled, the default)
- Browser: const peer = new MeteredPeer({ tokenProvider }); peer.addStream(localStream, { role: "camera" }); await peer.join(channel)
- Render each remote via remote.on("stream-added", ({ stream, metadata }) => ...)
- Wire mute, camera-off, and a screen-share toggle using addStream + removeStream with role metadata
- Use peer.send for broadcast chat in the same channel

Show me how to do this with vanilla JS, no framework.
My app name is: YOUR_APP_NAME
My realtime-messaging key id is: sk_id_YOUR_KEY_ID
My Realtime Messaging secret key is in METERED_REALTIME_SK on my backend. Use it only server-side, to mint client tokens.

Build a React Native (Expo) video call​

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a React Native (Expo dev build) video call with @metered-ca/realtime + react-native-webrtc:
- Wire rtcPeerConnectionFactory to react-native-webrtc's RTCPeerConnection (WebSocket is already global in RN)
- getUserMedia via react-native-webrtc mediaDevices; addStream(stream, { role: "camera" })
- Render remotes with <RTCView streamURL={stream.toURL()} /> on stream-added; re-read .toURL() each time
- Add mute + camera-off toggles and a "reconnecting…" banner on state-change
- Configure the @config-plugins/react-native-webrtc Expo plugin (the app won't run in Expo Go)

My app name is: YOUR_APP_NAME
My realtime-messaging key is: pk_live_YOUR_KEY

Build a Flutter (iOS + Android) video call​

Read https://www.metered.ca/docs/llms-realtime-messaging-flutter-sdk.txt

Build a Flutter video call with the metered_realtime package + flutter_webrtc:
- final peer = MeteredPeer(MeteredPeerOptions(tokenProvider: ...)); await peer.join(channel)
- getUserMedia({'audio': true, 'video': true}); peer.addStream(wrapMediaStream(stream), metadata: {'role': 'camera'})
- Render each remote: on remote.onStreamAdded set an RTCVideoRenderer.srcObject = (ev.stream as FlutterWebrtcMediaStream).native and show it with RTCVideoView; re-bind on every onStreamAdded
- Add mute + camera-off toggles, and a camera↔screen-share swap with peer.replaceTrack
- Show a "reconnecting…" banner when the connection state changes
- Declare camera/mic permissions in AndroidManifest.xml + iOS Info.plist

My app name is: YOUR_APP_NAME
My realtime-messaging key is: pk_live_YOUR_KEY

Add chat + presence to an existing app (no WebRTC)​

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Help me add chat + live presence to my existing app using the SignallingClient class from @metered-ca/realtime:
- Mint per-user JWTs with peerMetadata containing username and avatarUrl
- Connect and subscribe to a chat channel
- Render a live roster from the presence event (joined + left arrays of { peerId, metadata })
- Append chat messages with sender username from senderMetadata
- Show a "reconnecting…" indicator when state transitions to "reconnecting"
- Auto-resubscribe is on by default — verify that subscriptions survive reconnects

Use vanilla JS. My app name is: YOUR_APP_NAME

Run multi-agent AI coordination with directed sends + broadcast channels​

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build a coordinator + worker-agents system using SignallingClient:
- Each agent connects with a JWT carrying its agent ID as sub
- Workers subscribe to tasks/{workerId} for direct dispatch
- Coordinator publishes tasks to specific worker queues
- Workers reply via client.send(coordinatorPeerId, result)
- Use reconnect: { maxAttempts: Infinity, maxDelayMs: 60_000 } so agents run forever
- Wire peer.on("error", ({err}) => ...) to log fatal conditions (account suspended, invalid token)

Show me Node.js code for both the coordinator and a worker template.
My app name is: YOUR_APP_NAME

Stream telemetry from IoT devices​

Read https://www.metered.ca/docs/llms-realtime-messaging-sdk.txt

Build an IoT fleet with @metered-ca/realtime's SignallingClient:
- Each device connects with its own JWT (sub = device ID, channels = ["fleet/{deviceId}/**"])
- Device publishes sensor readings to fleet/{deviceId}/telemetry every 5 seconds
- Backend dashboard subscribes to fleet/sensor-*/telemetry for the firehose
- Devices buffer locally while disconnected and flush on reconnect (isReconnect=true)
- Backend can publish to fleet/{deviceId}/cmd to send commands; device subscribes and handles them
- Devices run with reconnect: { maxAttempts: Infinity }

Show me both the device-side Node.js code and the dashboard-side subscriber.

Embed SDK​

Embed video chat in a React app​

Read https://www.metered.ca/docs/llms-embed.txt

Help me embed Metered video chat into my React application:
- Create a VideoChat component using MeteredFrame
- Auto-join a specific room on mount
- Listen for participantJoined and participantLeft events
- Add a button to toggle the chat panel
- Clean up on unmount

The room URL is: YOUR_APP_NAME.metered.live/YOUR_ROOM_NAME

Setting Up Your AI Tool​

Claude Code​

One-liner — paste this and start building:

Read https://www.metered.ca/docs/llms-video-sdk.txt and help me build a video calling app.

Or reference a downloaded file with @llms-video-sdk.txt in your prompt.

Cursor​

  1. Cursor Settings > Features > Docs
  2. Add: https://www.metered.ca/docs/llms-video-sdk.txt
  3. In chat, use @Docs to reference it

GitHub Copilot​

In Copilot Chat, include the URL in your message:

Using the Metered Video SDK docs at https://www.metered.ca/docs/llms-video-sdk.txt,
help me add screen sharing to my video call app.

ChatGPT / GPT Codex​

Upload the .txt file or paste its contents, then describe what you want to build. For Codex agents, include the reference file URL in your task description.

Windsurf / Other AI Tools​

Most AI coding tools accept URLs or file contents as context. Download the appropriate .txt file and provide it to your tool however it accepts external documentation.


Tips​

  • Use the product-specific file rather than llms-full.txt — smaller context means more focused, accurate responses
  • Include your app name in the prompt. Never paste a secret key into an AI tool: tell it which environment variable holds the key.
  • Iterate — start with a prompt template, then ask follow-up questions to refine
  • Reference the OpenAPI spec (video-rest-api-openapi.yaml) if your AI tool supports OpenAPI natively