Skip to main content

REST API Overview

The REST control plane lives at:

https://rms.metered.ca/v1

Five endpoints, all authenticated with sk_live_… keys via Bearer header.

MethodPathPurpose
POST/v1/tokensMint a JWT for a peer (alternative to signing one yourself)
GET/v1/channels/:id/peersList peers currently subscribed to a channel
POST/v1/channels/:id/publishPublish to a channel from your backend, no WebSocket needed
DELETE/v1/peers/:idForcibly close every WebSocket owned by a peer (admin kick)
GET/v1/usageLive concurrent count + period totals + plan limits

Authentication

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • sk_ keys only. pk_live_… keys are rejected — they're shipped to browsers and must never be able to mint tokens or kick peers.
  • The sk_ key's channelPatterns and actions apply to channel-scoped REST endpoints: a key that can't subscribe to app_abc/* can't GET /v1/channels/app_abc/room-1/peers either.

Errors

All endpoints share an error shape:

{
"error": "channel_not_authorized",
"message": "channel not in key's allowed patterns: other-app/room-1"
}

error is the machine-readable code (stable); message is human-readable detail (informational).

Error codes by HTTP status

HTTPError codesWhen
400invalid_request, channel_reservedMalformed body, missing required fields, reserved channel name
401unauthorizedMissing / malformed / unknown sk, pk used by mistake
403channel_not_authorized, action_not_permittedsk_ valid but lacking scope for this resource
404not_foundUnknown endpoint
413invalid_requestBody exceeds 32 KB cap (REST endpoint cap; WS layer caps at 64 KB)
429(no error code; HTTP only)Per-IP / per-key rate limit hit on REST
503internal_errorPlan-cache failure, infra blip

Same-status-different-code is timing-safe for auth: unauthorized covers unknown / revoked / wrong-type keys with the same response so attackers can't enumerate valid keyIds.

Where to find your sk_ key

  1. DashboardRealtime MessagingKeys
  2. Click + Create key, choose type Secret
  3. Copy the signing secret when it's shown — it is never shown again

The sk_id_… part is the bearer-token value. The sk_secret_… part is the JWT signing material — only needed if you're minting JWTs yourself rather than calling POST /v1/tokens.

OpenAPI spec

Full machine-readable schema for the five endpoints:

Common patterns

You want toUse
Get a connect token to ship to a logged-in userPOST /v1/tokens — recommended; alternative is signing the JWT yourself
Send a server-side broadcast (chat moderation, AI-agent fan-out)POST /v1/channels/:id/publish
Know who's currently in a roomGET /v1/channels/:id/peers
Implement a user-initiated logout that drops their WebSocketDELETE /v1/peers/:id
Read live usage for a billing widgetGET /v1/usage