MoQ Relay API Reference
The MoQ Relay API manages streams, tokens, signing keys, ladders, webhooks and monitoring for your MoQ Relay account. For concepts, see the MoQ Relay overview.
Note: This API is in beta. Endpoints and fields may change before general availability. Your account manager gives you the API base URL when MoQ Relay access is enabled on your account. The examples below use
$MOQ_APIfor it.
Authentication
Send your API token from Account → API as the key query parameter. The request's source IP must be on your account's API IP ACL, as described in API Access.
curl "$MOQ_API/moqrelay/streams?key=YOUR_API_TOKEN"
Every endpoint except GET /moqrelay/access and POST /moqrelay/access also requires MoQ Relay to be enabled on your account. If it is not, the API returns 401 with the message "Your account is not enabled for the MoQ Relay."
Two endpoints use a different credential:
POST /moqrelay/tokensalso requires a MoQ Relay API key in thex-moqrelay-keyheader. You create one withPOST /moqrelay/keysand kindapiKey.GET /moqrelay/viewerstakes a viewer token asAuthorization: Bearer, not your API token. This lets a player ask for its own stream's viewer count.
Conventions
- Request bodies are JSON. Times are ISO 8601 in UTC.
- Ids in paths, such as
streamId, are integers. An id that does not belong to your account returns 404. - Secrets, ingest keys and tokens are returned once, when they are created. Later reads show only the last four characters.
- Measured figures carry a matching
basisfield, for exampleviewersandviewersBasis, that names the source of the figure. A figure that was not measured isnull.
Errors
| Status | Meaning |
|---|---|
| 400 | A field or the request is invalid. The response names the field. |
| 401 | Missing or rejected credentials, or MoQ Relay is not enabled for the account. |
| 404 | The object does not exist or does not belong to your account. |
| 409 | The request conflicts with the object's current state. |
Access
Check MoQ Relay Access
- GET
/moqrelay/access
Returns entitled, status (none, requested, enabled or disabled), tier, namespacePrefixRoot and the dates access was requested, enabled or disabled.
Request MoQ Relay Access
- POST
/moqrelay/access
Records a request for access. No payload required.
Namespaces
List Namespaces
- GET
/moqrelay/namespaces
Returns each namespace's id, name, prefix and createdOn.
Create a Namespace
- POST
/moqrelay/namespaces
Names are 2 to 63 characters of lowercase letters, digits and hyphens. internal, cluster, origins and public are reserved. Creating a namespace that already exists returns it.
{
"name": "live"
}
Streams
List Streams
- GET
/moqrelay/streams
Optional query parameter namespace filters by namespace name. Each stream includes id, name, namespace, path, inputProtocol, state, ladderSource, enabled, ladder, latencyMode, syncMode, syncDelayMs, rewindSeconds, geoMode, geoCountries, warm, brands, lastInputOn, the ingest URLs for each protocol, renditionsSeen with its basis and time, sourceVideoTrack, and rungs (described below).
Create a Stream
- POST
/moqrelay/streams
{
"namespaceId": 12,
"name": "channel-1",
"inputProtocol": "moq",
"ladderSource": "customer"
}
| Field | Required | Values |
|---|---|---|
namespaceId | Yes | A namespace id |
name | Yes | 2 to 63 characters |
inputProtocol | Yes | srt, rtmp or moq |
ladderSource | No | managed (default) or customer |
ladderId | When ladderSource is managed; optional for customer with moq input | A ladder id. On a customer MoQ stream it adds extra renditions; see below. |
sourceVideoTrack | No | The video track in your broadcast that extra renditions are encoded from. Default video-main. |
latencyMode | No | lowest (default) or smooth |
syncMode | No | off, region or global (default) |
syncDelayMs | No | 0 to 10000 |
rewindSeconds | No | 0, 30 (default), 60, 120 or 300 |
geoMode | No | any (default), allow or block |
geoCountries | With allow or block | ISO country codes |
brandIds | No | Brand ids |
warm | No | true (default) or false |
publishName | No | The name you publish under, if different from name |
enabled | No | true (default) or false |
The response is the stream plus ingestKey, which is shown only once.
Retrieve, Update or Delete a Stream
- GET
/moqrelay/streams/{streamId} - PATCH
/moqrelay/streams/{streamId} - DELETE
/moqrelay/streams/{streamId}
PATCH takes any of the optional fields from create. DELETE requests removal and returns the streamId.
Extra Renditions for Your Own Broadcast
A customer stream with moq input can carry a ladder. NetActuate then subscribes to your video track, encodes the ladder's renditions, and publishes them as a second broadcast named <name>-rungs.hang beside yours. Your own broadcast is not changed. Each extra rendition is a track named after the rendition, in the same framing as your input: H.264 access units as 4-byte length-prefixed NAL units, SPS and PPS at the start of every group, and a new group at each IDR. The object extension 0x01 on each encoded frame carries the same bytes as the source frame it was encoded from, so your player can align renditions with your own timestamps. Audio is not republished.
Set ladderId to a ladder with no passthrough rendition, such as the preset Customer extras 540 + 360, and set it to null to stop. When it is set, the stream's rungs field is:
{
"broadcast": "channel-1-rungs.hang",
"path": "t/4/live/channel-1-rungs",
"tracks": ["video-540", "video-360"]
}
Viewer tokens must list the extra broadcast in subscribe as well as your own.
Start or Stop a Stream
- POST
/moqrelay/streams/{streamId}/start - POST
/moqrelay/streams/{streamId}/stop
Sets enabled and returns the stream.
Rotate the Ingest Key
- POST
/moqrelay/streams/{streamId}/key
Returns the new ingestKey once, with ingestKeyLast4. The old key stops working.
Mint a Publish or Preview Token
- POST
/moqrelay/streams/{streamId}/publishToken - POST
/moqrelay/streams/{streamId}/previewToken
Optional ttlSeconds, at most 3600. The defaults are 600 for publish and 300 for preview. Returns token, expiresOn, broadcast, stream and the relay url to use with it. Requires an active signing key on the account.
Stream Health
- GET
/moqrelay/streams/{streamId}/health
Returns the last observed input: state, protocol, arrivingKbps, video (width, height, fps and codec), bitrateKbps, lossPct, keyframeIntervalMs, connectedSinceOn, basis and observedOn. Fields that were not observed are null, and basis says why. A customer stream with extra renditions also returns rungs, with frames in and out per rendition and the alignment counters, and rungsBasis.
Stream Stats
- GET
/moqrelay/streams/{streamId}/stats
Optional query parameters from (inclusive) and to (exclusive), as ISO timestamps, default to the last hour. step is the bucket size in seconds, default 60. Returns data, a list of points with t, egressBytes and viewers, each with its basis.
Viewers by Country
- GET
/moqrelay/streams/{streamId}/geo
Optional from and to. Returns data, a list of country, viewers and egressBytes, each with its basis.
Monitoring
All Streams at a Glance
- GET
/moqrelay/monitor
Returns streams, a list with streamId, path, state, viewers, ingestBitrate and renditions, each with its basis.
Viewer Count for a Player
- GET
/moqrelay/viewers
Query parameter stream as namespace/name. Authenticate with a viewer token that covers the stream, as Authorization: Bearer. Returns count and basis.
Relays
- GET
/moqrelay/relays - GET
/moqrelay/relays/{relayId}
Lists the relays serving your account, with location, state, deliveryHealth, playersNow, viewersNow, carryingStreams, egressBps, delivered24hBytes and p50LatencyMs, each with its basis. The single-relay form adds the streams it carries and viewers by country, city and network.
Relay Traffic
- GET
/moqrelay/relays/traffic
Optional window (default 6h), relayId, and group=relay for one series per relay. Returns points with t, egressBps and viewers.
Analytics
- GET
/moqrelay/analytics
Optional stream, group (region (default), relay, brand, transport or stream) and window (1h (default), 6h or 24h). Returns series with sessions, bytes, p50 and p95 latency, sync error and stalls per viewer hour, and a summary.
Usage
- GET
/moqrelay/usage
Optional period as YYYY-MM (default the current UTC month) and group (day (default) or stream). Returns rows with deliveredBytes, ingestBytes and renditionSeconds, and an estimate for the period.
Signing Keys and API Keys
List Keys
- GET
/moqrelay/keys
Returns signing keys and MoQ Relay API keys with id, keyType, kid, kind, alg, label, last4, revokedOn, lastUsedOn and createdOn. Public keys are returned as publicJwk.
Add a Key
- POST
/moqrelay/keys
kind | Use | Fields |
|---|---|---|
customerHeld | You sign tokens with your own Ed25519 private key | publicJwk, an Ed25519 OKP public key. Do not send the private part. |
customerHmac | You sign tokens with a shared HMAC secret | alg (HS256 default, HS384 or HS512), optional secret as base64url, optional kid |
apiKey | For the x-moqrelay-key header on POST /moqrelay/tokens | label |
The response includes the kid to put in your token headers. A generated HMAC secret or API key is returned only once.
Revoke a Key
- DELETE
/moqrelay/keys/{keyId}
Tokens signed with a revoked key are refused once the relays receive the updated configuration.
Signing Your Own Tokens
Tokens are JWTs with the key's kid in the header. Use EdDSA for a customerHeld key, or the key's HMAC algorithm for a customerHmac key. The claims are:
| Claim | Meaning |
|---|---|
root | Your tenant root, t/<tenant>/, or a deeper prefix such as t/<tenant>/live/ |
publish | Broadcast names under root the token may publish, for a publish token |
subscribe | Broadcast names under root the token may subscribe to, for a viewer token |
iat, exp | Issued and expiry times in seconds since the epoch |
{
"root": "t/4/live/",
"subscribe": ["channel-1.hang"],
"iat": 1761609600,
"exp": 1761610200
}
Do not add other claims: the relay refuses tokens with fields it does not recognize. A session ends when its token expires, so players should fetch a new token before then.
Managed Tokens
Managed tokens are stored by NetActuate. Publish tokens authorize RTMP, SRT and WHIP ingest through the ingest gateway. A MoQ encoder publishing directly to a relay uses a signed token instead.
List or Create Managed Tokens
- GET
/moqrelay/tokens/managed - POST
/moqrelay/tokens/managed
GET takes optional kind and label filters. POST takes kind (publish or subscribe), label and streams, a list of name and isPattern. Optional fields are expiresOn, allowedOrigins (subscribe only), allowedIps, bindIpOnUse, allowedCountries and deniedCountries. The response includes token once.
Retrieve, Update or Revoke a Managed Token
- GET
/moqrelay/tokens/managed/{tokenId} - PATCH
/moqrelay/tokens/managed/{tokenId} - DELETE
/moqrelay/tokens/managed/{tokenId}
Mint a Viewer Token with an API Key
- POST
/moqrelay/tokens
Send a MoQ Relay API key in the x-moqrelay-key header. Body fields are stream, brand (the brand token) and country (ISO code), with optional ttlSeconds up to 3600. A country blocked by the stream's geo rule returns 401.
Ladders
List or Create Ladders
- GET
/moqrelay/ladders - POST
/moqrelay/ladders - GET
/moqrelay/profiles
GET includes NetActuate presets (isPreset true), which are read-only. POST takes name and renditions, 1 to 12 renditions keyed by name, plus optional overlay settings: overlayMode (none, logo or frame), overlayPosition, overlayScalePct, overlayMarginPct, overlayOpacityPct and overlayImage. profiles is a read-only list of the same ladders.
Retrieve, Update or Delete a Ladder
- GET
/moqrelay/ladders/{ladderId} - PATCH
/moqrelay/ladders/{ladderId} - DELETE
/moqrelay/ladders/{ladderId}
Brands
List or Create Brands
- GET
/moqrelay/brands - POST
/moqrelay/brands
POST takes name, tokenValue (2 to 32 characters) and overlayPosition (topLeft, topRight or lowerThird), with optional accentColor as #rrggbb and assetRef.
Update or Delete a Brand
- PATCH
/moqrelay/brands/{brandId} - DELETE
/moqrelay/brands/{brandId}
Brand Logo
- GET
/moqrelay/brands/{brandId}/logo - POST
/moqrelay/brands/{brandId}/logo - DELETE
/moqrelay/brands/{brandId}/logo
POST takes mimeType (image/png, image/svg+xml or image/webp) and data as base64, at most 256 KiB.
Webhooks
Webhooks send stream events to your HTTPS endpoint. Events are stream.started, stream.ended, viewers.first, viewers.none and webhook.test.
List or Create Webhooks
- GET
/moqrelay/webhooks - POST
/moqrelay/webhooks
POST takes url (HTTPS), events and an optional streamFilter. The response includes the signing secret once.
Retrieve, Update or Delete a Webhook
- GET
/moqrelay/webhooks/{webhookId} - PATCH
/moqrelay/webhooks/{webhookId} - DELETE
/moqrelay/webhooks/{webhookId}
PATCH takes url, events, streamFilter and enabled.
Rotate the Secret, Send a Test, List Deliveries
- POST
/moqrelay/webhooks/{webhookId}/secret - POST
/moqrelay/webhooks/{webhookId}/test - GET
/moqrelay/webhooks/{webhookId}/deliveries
Deliveries lists the last 100 attempts with type, occurredOn, attemptCt, deliveredOn, lastStatusCode and lastError.
Need Help?
Contact support@netactuate.com or open a support ticket from the portal.