Free WebRTC Signalling Server
Metered Realtime is a free, managed WebRTC signalling server. It handles the part of WebRTC that a TURN server doesn't: helping peers discover each other and exchange the SDP offers/answers and ICE candidates needed to connect — over a single WebSocket, with your Open Relay TURN credentials auto-injected.
No server to run, no Socket.io to wire up. Connect from the browser with a publishable key and you get channels, presence, and direct messages out of the box.
Free tier — no credit card
100 peak concurrent connections and 100,000 messages per month, free. TURN relay included via Open Relay (20 GB/month free).
What is a WebRTC signalling server?
WebRTC lets two browsers talk directly, but they can't find each other on their own. Before any audio, video, or data flows, the two peers have to exchange:
- SDP offer/answer — the codecs and media each side supports.
- ICE candidates — the network addresses to try, including your TURN server.
A WebRTC signalling server (US spelling: signaling server) is the channel that relays those messages until the direct peer-to-peer connection is established. WebRTC deliberately leaves signalling out of the spec — it's up to you to provide it. Metered Realtime is that signalling layer, managed and free.
Browser A ⇄ Metered Realtime (wss://rms.metered.ca/v1) ⇄ Browser B
└─ relays SDP + ICE, then the peers connect directly
Once the handshake completes, media flows peer-to-peer (relayed by TURN only when a direct path isn't possible). The signalling server stays in the loop for presence, reconnection, and any messages you send through it.
Managed vs. building your own signalling server
You can build a signalling server yourself — a Node.js WebSocket relay with Socket.io is the usual starting point. It works until you need presence, reconnection, authentication, rate limiting, and horizontal scaling. Then you're maintaining infrastructure instead of shipping your app.
| Build your own (Node.js / Socket.io) | Metered Realtime | |
|---|---|---|
| Time to first connection | hours – days | minutes |
| Presence (who's online) | build it yourself | built-in |
| Authentication | build it yourself | JWT or publishable key |
| Reconnect handling | build it yourself | built-in (with the SDK) |
| TURN credentials | fetch + embed yourself | auto-injected |
| Scaling & ops | your problem | fully managed |
| Cost | server + maintenance | free up to 100 conns / 100k msgs / mo |
Metered Realtime is a managed service — there's nothing to self-host. If you specifically need to run signalling on your own hardware, an open-source server is the right tool. If you just want signalling that works without running anything, this is it.
Features
- Channels — publish/subscribe with wildcard routing (
room-*,app_xyz/*). - Presence — automatic join/leave events with per-peer metadata (
userId,username, anything you attach). - Direct messages — send to a specific
peerId, no channel required. - JWT or publishable-key auth — go browser-only with a
pk_live_key, or mint scoped JWTs from your backend for per-user permissions. - REST API — mint tokens, list peers, publish server-side, and read usage.
- TURN auto-injection — your Open Relay TURN credentials arrive in the connection's welcome message, so there's no separate fetch-and-embed step.
Quickstart
The fastest path is the open-source @metered-ca/realtime SDK, which speaks the signalling protocol for you:
import { MeteredPeer } from "@metered-ca/realtime";
// Browser-only: a publishable key, no backend required
const peer = new MeteredPeer({ apiKey: "pk_live_..." });
await peer.join("room-42"); // presence + discovery over wss://rms.metered.ca/v1
peer.on("peer-joined", ({ peer: remote }) => {
remote.on("stream-added", ({ stream }) => {
remoteVideo.srcObject = stream; // TURN was auto-applied at connect time
});
});
const cam = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
peer.addStream(cam);
note
The apiKey here is your signalling publishable key (pk_live_...) — free in your dashboard, and separate from the TURN REST API_KEY used to fetch Open Relay credentials directly (with signalling, TURN is auto-injected, so the publishable key is all you need). Create it from Dashboard → Realtime Messaging → Keys → Create key → Publishable, and make sure Send is enabled — it's off by default, and without it peers connect but the video never negotiates (the WebRTC layer can't exchange SDP/ICE). See the full key walkthrough.
Raw WebSocket — any language
No SDK required. The protocol is plain JSON over one WebSocket, so Go, Python, Rust, Swift, Unity — anything that speaks WebSocket — can use it directly:
wss://rms.metered.ca/v1?key=pk_live_...
Every frame is a single JSON object with a type. A full join-and-broadcast round-trip is just a handful of messages:
// ← welcome: the server's first frame, right after you connect
{ "type": "welcome", "peerId": "alice", "maxMessageSize": 65536 }
// → subscribe to a channel
{ "type": "subscribe", "channel": "room-1", "requestId": "1" }
// ← ack, then who's already in the room
{ "type": "ack", "requestId": "1", "ok": true }
{ "type": "presence", "channel": "room-1", "joined": [{ "peerId": "bob" }], "left": [] }
// → broadcast to everyone else in the channel
{ "type": "publish", "channel": "room-1", "data": { "hello": "world" }, "requestId": "2" }
// ← other subscribers receive it
{ "type": "message", "channel": "room-1", "from": "alice", "data": { "hello": "world" } }
That's the whole model — subscribe / publish for channels, send for direct peer-to-peer (SDP, ICE, agent calls), plus presence events. The full protocol reference has every message type, auth (?token= JWT vs ?key=), and close codes.
What you can build
- WebRTC signalling — video and voice calls, the original use case.
- Live presence & chat — who's online, typing indicators, room chat.
- IoT telemetry & control — device events over WebSocket pub/sub.
- AI agent communication — multi-agent coordination and streaming.
One protocol covers all four — see the use-case guides.
FAQ
Is it free? Yes — 100 peak concurrent connections and 100,000 messages per month, no credit card and no overages. TURN relay is included via Open Relay (20 GB/month free).
Is it open source?
The service is managed and free — there's nothing to self-host, so it isn't open source. The client SDK, @metered-ca/realtime, is open source (MIT).
Can I use it from Node.js, Python, or C# without the SDK?
Yes. The SDK is JavaScript/TypeScript, but any language can speak the WebSocket JSON protocol at wss://rms.metered.ca/v1.
Do I need my own TURN server? No. Open Relay TURN credentials are auto-injected into the connection (20 GB/month free).
Can I see who's connected? Yes — presence events fire on join and leave, with whatever per-peer metadata you attach.
Is there an example? Yes — the Quickstart above is a complete browser example; fuller examples (React, raw WebSocket) are in the docs.
Get a free keyUse the @metered-ca/realtime SDK →Metered Realtime pairs with the free Open Relay TURN server and the open-source @metered-ca/realtime library — a complete, free WebRTC stack from one vendor.