Skip to main content

mux_api 1.0.0 copy "mux_api: ^1.0.0" to clipboard
mux_api: ^1.0.0 copied to clipboard

Pure Dart client for the Mux API: video, data and system resources, JWT playback-token signing, and webhook verification. Runs on Dart servers, CLIs and Flutter apps.

mux_api #

pub package CI Coverage Status

A pure Dart client for the Mux API. Runs on Dart servers, CLIs and Flutter apps — there is no Flutter dependency, and no code generation step for you.

Used in production at Fullphysio, where it runs inside our Dart Cloud Functions. Bug reports are welcome — see CONTRIBUTING.md.

Warning

The token secret grants full account access. Keep it on a server, a Cloud Function or a CLI — never ship it inside a Flutter app.

final mux = MuxClient(tokenId: tokenId, tokenSecret: tokenSecret);

final upload = await mux.video.uploads.create(
  const UploadCreateParams(
    corsOrigin: 'https://example.com',
    newAssetSettings: AssetOptions(playbackPolicies: [PlaybackPolicy.signed]),
  ),
);
// PUT the file to upload.url, then:
final ready = await mux.video.uploads.retrieve(upload.id);
if (ready.status == UploadStatus.assetCreated) {
  final token = mux.jwt.signPlaybackId(playbackId, expiration: '24h');
  final url = 'https://stream.mux.com/$playbackId.m3u8?token=$token';
}

Why this exists #

No Dart package covers the Mux REST API; the ones on pub.dev are Flutter player widgets. This package is a port of the official TypeScript client, @mux/ts: the runtime — transport, retries, error mapping, pagination, JWT signing and webhook verification — is a hand port, and every model and resource method is generated from Mux's own OpenAPI specification by a generator that lives in this repository. Following a new Mux release is a command, not a rewrite.

Signed playback #

Tokens need no client — just the signing key pair from the Mux dashboard, as PEM or as the base64 PEM Mux hands out:

final token = signMuxPlaybackId(
  playbackId,
  type: MuxPlaybackTokenType.gif,
  params: {'start': 0, 'end': 5, 'fps': 15, 'width': 480},
  expiration: '48h',
  keyId: signingKeyId,
  privateKey: privateKeyBase64,
);

signMuxPlaybackIdTokens returns the playback-token / thumbnail-token / storyboard-token map Mux Player takes; signMuxDrmLicense and signMuxViewerCounts cover the other audiences.

Webhooks #

Verification is static too:

final event = unwrapMuxWebhookEvent(
  request.rawBody,
  request.headers['mux-signature'],
  secret: endpointSecret,
);

Pass the raw request body, never a re-encoded or already-parsed one. Verification uses a constant-time comparison, accepts any one of the signatures in the header (so secret rotation works), and rejects timestamps older than 300 seconds. unwrap returns a typed MuxWebhookEvent; a type this version does not know decodes to UnknownMuxWebhookEvent with its payload intact.

Errors #

Every failure is a MuxException, a sealed hierarchy:

Exception When
MuxBadRequestException … MuxInternalServerException a 400, 401, 403, 404, 409, 422, 429 or 5xx response, with Mux's errorType and messages
MuxUnexpectedStatusException any other non-2xx status
MuxConnectionException, MuxTimeoutException the request never produced a response
MuxWebhookSignatureException a delivery that failed verification

MuxDecodeException (outside the hierarchy) means Mux answered successfully but the payload was missing its id or data envelope.

Fidelity to @mux/ts #

This client reproduces @mux/ts 15.1.0's observable behaviour, including details that are easy to get subtly wrong:

  • Retries on 408, 409, 429, 5xx and connection failures — twice by default — honouring x-should-retry, retry-after-ms and Retry-After (seconds or HTTP-date) over a 0.5 s-doubling backoff capped at 8 s with up to 25 % jitter. Mux defines no idempotency keys, so a retried POST is exactly as eager as upstream.
  • Query arrays use bracket notation, filters[]=a&filters[]=b, percent-encoded with the RFC 3986 unreserved set. One deliberate divergence: @mux/ts 15.1.0 sends Data API array parameters as timeframe[][]=7:days, which Mux answers with a 400 or 500 (checked live); this client sends the single [] Mux accepts.
  • JWT claims are params…, kid, sub, aud, exp — kid in the payload, no iat.

Conformance is enforced by golden tests whose fixtures were captured from the real @mux/ts, not written by hand; the JWT fixtures match byte for byte.

Scope #

Covered. Every endpoint @mux/ts 15.1.0 exposes — 149 operations under client.video, client.data, client.system and client.robots, with typed parameters, models, open enums and discriminated unions generated from Mux's OpenAPI specification — plus a typed class for each of the 117 webhook event types, JWT signing and webhook verification. Every enum tolerates values Mux adds later, and every model keeps its raw payload.

Not covered. The four deprecated /video/v1/signing-keys routes (use client.system.signingKeys) and GET /counts on stats.mux.com, which @mux/ts leaves out too. MuxClient.requestJson reaches them with the same authentication, retries and error mapping.

Never covered: reading credentials from environment variables (pass them in), request cancellation, and playback URL builders (stream.mux.com and image.mux.com URLs are one string interpolation away, as upstream leaves them).

Relationship to @mux/ts and to Mux #

This is an independent port, not an official Mux product and not endorsed by Mux. See THIRD_PARTY_NOTICES for the licence of @mux/ts and of the OpenAPI specification this package is derived from.

0
likes
160
points
480
downloads

Documentation

API reference

Publisher

verified publisherfullphysio.com

Weekly Downloads

Pure Dart client for the Mux API: video, data and system resources, JWT playback-token signing, and webhook verification. Runs on Dart servers, CLIs and Flutter apps.

Repository (GitHub)
View/report issues
Contributing

Topics

#mux #video #api #client

License

MIT (license)

Dependencies

crypto, dart_jsonwebtoken, http, http_parser, meta

More

Packages that depend on mux_api