- 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.
Control-plane origin (no trailing slash needed). Python:
base_url.API key with
streams:* scopes, sent as Authorization: Bearer. Python:
api_key.Default org/tenant id for every tenant-scoped call. Required for
liveInputs.* and signingKeys.*. Python: org_id.(TS only) Override
fetch for test fakes or custom transports. Defaults to
globalThis.fetch.| Helper | TS | Python |
|---|---|---|
| Live inputs | streams.liveInputs | streams.live_inputs |
| Signing keys | streams.signingKeys | streams.signing_keys |
liveInputs
Create a live input.
ingest is one of fmp4 (default) | whip | rtmp |
srt. Returns { input, streamKey } — the cleartext streamKey is returned
only here (and on rotateStreamKey). Python: create(name=, ingest=)
returning LiveInputWithSecret(input, stream_key).Fetch a live input by id. Python:
get(id=).List inputs (default
page=1, perPage=50). Python: list(page=, per_page=).LiveInput handle carries snapshot fields and bound methods:
The path segment used in publish/playback URLs (the
<input_id>).Current ingest state.
Mint a signed playback URL (
?tok=<jwt> attached). ttlSeconds is
server-clamped to 30 s – 24 h (default 3600). Returns { url, kid, alg, expiresAt }. Python: signed_playback_url(ttl_seconds=).Rotate the stream key. Returns a fresh cleartext
streamKey (captured once).
Python: rotate_stream_key().signingKeys
The org’s playback signing keys. Playback JWTs are signed with one of these; the
kid header on each token names the key.
Create a signing key.
alg is Ed25519 (default) | RS256; use is
playback. Returns a SigningKey with { id, alg, publicKeyPem, status }.
Python: create(alg=, use=).List the org’s signing keys.
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 ride 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, reach them through the control-plane API directly with the same
CLUTCHCALL_CREDENTIALS bearer key. Treat these surfaces as Preview.Data plane — BroadcastPublisher
Push a broadcast into a live input over MoQT, authorized by the per-input stream
key. The TypeScript publisher fragments a browser MediaStream to CMAF; the
Python publisher takes raw CMAF chunks you supply (server-side packaging).
- TypeScript (browser MediaStream)
- Python (raw CMAF chunks)
TypeScript surface
Construct a publisher.
opts: mimeType? (MediaRecorder mime, default
video/mp4; codecs="avc1.42E01E,mp4a.40.2"), timesliceMs? (fragment cadence,
default 1000), serverCertificateHash?, webTransport?, onError?.Connect to
/publish/<input>?sk=<streamKey>, announce the track, and stream
CMAF fragments from media (a MediaStream). namespace is the MoQ namespace
the relay expects (stream/<org>/<input>).Stop recording, close the track, and tear down the session.
Python surface
Open a publisher. Args:
input_id, stream_key, relay_host?, codecs?
(PublisherCodecs(video=, audio=)), on_close?.Push 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).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
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?.Attach the
<video> element the stream renders into. Chainable.Resolve and play.
lv_* plays live over MoQT (subscribes the .catalog
track in-band, then media tracks); pb_* plays VOD over HTTPS from the
catalog.Tear down every track subscription and end the
MediaSource.Python surface
Connect to a signed
moq://…/playback/<input>?tok=<jwt> URL and forward
chunks. on_chunk(is_init, chunk) fires per segment; the first has
is_init=True. chunk is a BroadcastChunk(data, timestamp_us, priority, is_init).Close the session; fires
on_close("closed_by_caller", None).Events & close reasons
Both surfaces report terminal state through callbacks rather than an emitter:(Viewer) Playback has begun — first segment buffered.
Connection or decode error. If no handler is set, errors throw from
play() /
publish().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).
