- Control plane — a
Streamsclient over HTTPS that manages live inputs, signing keys, and (preview) assets/API-keys/analytics. - Data plane —
BroadcastPublisherandBroadcastViewer, which move CMAF segments over the persistent MoQT connection.
Import
Control plane — Streams
The control-plane client is stateless HTTPS. Every call is one query or
mutation against the control-plane API. The persistent QUIC connection lives
in the publisher/viewer, not here.
string
required
Control-plane origin (no trailing slash needed). Python:
base_url.string
required
API key with
streams:* scopes, sent as Authorization: Bearer. Python:
api_key.string
Default org/tenant id for every tenant-scoped call. Required for
liveInputs.* and signingKeys.*. Python: org_id.typeof fetch
(TS only) Override
fetch for test fakes or custom transports. Defaults to
globalThis.fetch.liveInputs
Promise<LiveInputWithSecret>
Create a live input.
ingest is one of fmp4 (default) | whip | rtmp |
srt. Returns { input, streamKey }. The API returns the cleartext
streamKey only here (and on rotateStreamKey). Python:
create(name=, ingest=) returning LiveInputWithSecret(input, stream_key).Promise<LiveInput>
Fetch a live input by id. Python:
get(id=).Promise<LiveInput[]>
List inputs (default
page=1, perPage=50). Python: list(page=, per_page=).LiveInput handle carries snapshot fields and bound methods:
string
The path segment used in publish/playback URLs (the
<input_id>).'idle' | 'live' | 'errored'
Current ingest state.
Promise<SignedPlaybackUrl>
Mint a signed playback URL (
?tok=<jwt> attached). The server clamps
ttlSeconds to 30 s – 24 h (default 3600). Returns { url, kid, alg, expiresAt }. Python: signed_playback_url(ttl_seconds=).Promise<LiveInputWithSecret>
Rotate the stream key. Returns a fresh cleartext
streamKey. The API
returns it only once. Python: rotate_stream_key().signingKeys
The org’s playback signing keys. One of these keys signs each playback JWT.
The kid header on each token names the key.
Promise<SigningKey>
Create a signing key.
alg is Ed25519 (default) | RS256. use is
playback. Returns a SigningKey with { id, alg, publicKeyPem, status }.
Python: create(alg=, use=).Promise<SigningKey[]>
List the org’s signing keys.
Promise<void>
Deactivate a key. Existing tokens minted from it stop verifying.
Preview: assets, apiKeys, and analytics
Preview: assets, apiKeys, and analytics
The control-plane API also exposes asset management, API-key administration,
and viewer analytics (overview KPIs, viewer time-series, glass-to-glass
latency histograms, edge-POP health). These use the same
streams.* route
shape as the typed helpers above. Dedicated typed helpers
(streams.assets.*, streams.apiKeys.*, streams.analytics.*) are rolling
out. Until they land in your SDK version, call the control-plane API directly
with the same CLUTCHCALL_CREDENTIALS bearer key. Treat these surfaces as
Preview.Data plane — BroadcastPublisher
Send a broadcast into a live input over MoQT. The per-input stream key
authorizes it. The TypeScript publisher fragments a browser MediaStream to
CMAF. The Python publisher takes raw CMAF chunks that you supply
(server-side packaging).
- TypeScript (browser MediaStream)
- Python (raw CMAF chunks)
TypeScript surface
BroadcastPublisher
Construct a publisher.
opts: mimeType? (MediaRecorder mime, default
video/mp4; codecs="avc1.42E01E,mp4a.40.2"), timesliceMs? (fragment cadence,
default 1000), serverCertificateHash?, webTransport?, onError?.Promise<void>
Connect to
/publish/<input>?sk=<streamKey>, announce the track, and stream
CMAF fragments from media (a MediaStream). namespace is the MoQ
namespace that the relay expects (stream/<org>/<input>).void
Stop recording, close the track, and close the session.
Python surface
BroadcastPublisher
Open a publisher. Args:
input_id, stream_key, relay_host?, codecs?
(PublisherCodecs(video=, audio=)), on_close?.None
Send one CMAF chunk. The first chunk is the init segment (priority 0,
opens a group). Subsequent chunks are media (priority 1). Pass
timestamp_us to override the monotonic timestamp (replay/tape-sync).None
Close the publisher.
reason ∈ closed_by_caller (default) | auth_failed |
network | finished.Data plane — BroadcastViewer
Play a stream from a playback id (TS, browser <video>) or from a signed
playback URL (Python, chunk callback).
- TypeScript (into a <video>)
- Python (chunk callback)
TypeScript surface
BroadcastViewer
Construct a viewer. Data-plane
Streams opts: apiBase? (resolve/catalog
base), relayUrl?, token? (signed JWT, carried as ?tok=),
serverCertificateHash?. Per-viewer extra: onStarted?, onError?,
webTransport?, fetchImpl?.this
Attach the
<video> element the stream renders into. Chainable.Promise<void>
Resolve and play.
lv_* plays live over MoQT. It subscribes to the
.catalog track in-band, then to media tracks. pb_* plays VOD over
HTTPS from the catalog.void
Close every track subscription and end the
MediaSource.Python surface
BroadcastViewer
Connect to a signed
moq://…/playback/<input>?tok=<jwt> URL and forward
chunks. on_chunk(is_init, chunk) fires per segment. The first segment has
is_init=True. chunk is a BroadcastChunk(data, timestamp_us, priority, is_init).None
Close the session. This fires
on_close("closed_by_caller", None).Events & close reasons
Both surfaces report terminal state through callbacks rather than an emitter:callback
(Viewer) Playback started. The first segment is buffered.
callback
Connection or decode error. If you set no handler, errors throw from
play() / publish().callback (Python)
Terminal close.
reason ∈ complete | auth_failed | network |
closed_by_caller. An expired/invalid playback JWT yields auth_failed.Other languages. The streams surface mirrors across the polyglot SDKs.
The control-plane
Streams client, BroadcastPublisher, and
BroadcastViewer keep the same method names (camelCase in TS, snake_case in
Python and the others). The TypeScript and Python signatures above are the
reference shapes.Types reference
LiveInputData / IngestKind / LiveInputStatus
LiveInputData / IngestKind / LiveInputStatus
SignedPlaybackUrl / SigningKeyData
SignedPlaybackUrl / SigningKeyData
Catalog / CatalogTrack
Catalog / CatalogTrack
parseCatalog(json), mseType(track), videoTrack(cat),
audioTrack(cat).
