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.
| Product | Reference File | Size |
|---|---|---|
| Embed SDK | llms-embed.txt | ~14 KB |
| Video SDK | llms-video-sdk.txt | ~48 KB |
| TURN Server | llms-turn-server.txt | ~22 KB |
| Realtime Messaging — JavaScript SDK | llms-realtime-messaging-sdk.txt | ~26 KB |
| Realtime Messaging — Python SDK | llms-realtime-messaging-python-sdk.txt | ~21 KB |
| Realtime Messaging — Flutter SDK | llms-realtime-messaging-flutter-sdk.txt | ~20 KB |
| Realtime Messaging — Raw WebSocket | llms-realtime-messaging-raw-websocket.txt | ~16 KB |
| Realtime Messaging — Everything | llms-realtime-messaging.txt | ~29 KB |
| Global Cloud SFU | llms-sfu.txt | ~17 KB |
| Everything | llms-full.txt | ~102 KB |
OpenAPI 3.0 spec for the Video SDK REST API: apidoc.yaml
- Download the reference file for your product from the table above (right-click → Save link as…)
- Give it to your AI agent — drop the
.txtfile into Claude Code, Cursor, Copilot, ChatGPT, or any AI coding tool - 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 secret key is: YOUR_SECRET_KEY
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 secret key is: YOUR_SECRET_KEY
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 signing secret is: sk_secret_YOUR_SECRET
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 signing secret is: sk_secret_YOUR_SECRET
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 signing secret is: sk_secret_YOUR_SECRET
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 Secret is: YOUR_SFU_SECRET
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 secret key is: YOUR_SECRET_KEY
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 secret key is: YOUR_SECRET_KEY
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 secret key is: YOUR_SECRET_KEY
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 secret key is: YOUR_SECRET_KEY
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 secret key is: YOUR_SECRET_KEY
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 with embedded iceServers (Metered TURN creds)
- 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 signing secret is: sk_secret_YOUR_SECRET
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
- Cursor Settings > Features > Docs
- Add:
https://www.metered.ca/docs/llms-video-sdk.txt - In chat, use
@Docsto 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 and secret key in the prompt so the AI can write working code. Use environment variables in production — never commit secrets.
- Iterate — start with a prompt template, then ask follow-up questions to refine
- Reference the OpenAPI spec (
apidoc.yaml) if your AI tool supports OpenAPI natively