Docs · REST API

REST API reference

Everything the web UI does goes through this API. The contract is OpenAPI 3.1; every server also serves it at GET /api/v1/openapi.yaml for code generators and Postman.

Overview

  • Base path /api/v1; JSON with snake_case fields. Unknown request fields are rejected, so typos never silently do nothing.
  • Authentication: API key (Authorization: Bearer <key>), user (Basic) or the web UI session. Roles admin (everything) and viewer (all reads; secrets redacted).
  • Durations and bit rates as in the configuration file ("2s", "6000k"); measured values are plain numbers.
  • Every error has the same body: {"error":{"code","message","details":[…]}}.
  • Live updates over server-sent events at GET /events.

Alteox Media Server REST API, version 1 · 74 operations in 17 groups.

Human-readable reference with all rules: docs/API.md. Curl and Python recipes: docs/API-EXAMPLES.md.

  • JSON everywhere except /config (YAML), /events (server-sent events), /health?format=nagios (plain text) and this document.
  • Unknown request fields are rejected (400 bad_request).
  • Every non-2xx response has the Error body.
  • Durations are Go duration strings ("2s", "500ms"), configured bitrates "6000k"/"6M" or an integer (bit/s); measured values are plain numbers (bit/s, seconds).
  • Writes are persisted to the config file (and in a cluster replicated through the raft leader) before the response is sent.

Download openapi.yaml

Quick start

Create a key with alteoxms gen-key -name automation -role admin and put the printed entry into api.keys.

export AMS=http://media.example:8080
export AMS_KEY='…key printed by alteoxms gen-key…'
H="Authorization: Bearer $AMS_KEY"

# create a channel with failover inputs and HLS
curl -sS --fail-with-body -X POST "$AMS/api/v1/channels" -H "$H" \
  -H 'Content-Type: application/json' --data '{
    "name": "sport1",
    "inputs": [ { "url": "srt://encoder-a.example:9000?mode=caller&latency=200" },
                { "url": "udp://239.1.1.1:1234?iface=eth1" } ],
    "failover": { "loss_timeout": "2s", "return_after": "30s", "standby": "hot" },
    "outputs": { "srt": true, "http_ts": true, "hls": { "segment": "4s", "window": 6 } }
  }'

# playback URLs and state
curl -sS -H "$H" "$AMS/api/v1/channels/sport1/status" | jq '.outputs.hls.url'

# change one setting (JSON Merge Patch), restart, health for monitoring
curl -sS -X PATCH "$AMS/api/v1/channels/sport1" -H "$H" \
  -H 'Content-Type: application/merge-patch+json' --data '{"failover":{"loss_timeout":"1s"}}'
curl -sS -X POST -H "$H" "$AMS/api/v1/channels/sport1/restart"
curl -sS -H "$H" "$AMS/api/v1/health?format=nagios"

identity

Identity and server

get /openapi.yaml

This OpenAPI document

Responses

  • 200

    The embedded docs/openapi.yaml.

    string
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

get /me

Who am I

Responses

  • 200

    The authenticated identity.

    Identity
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 429

    too_many_requests: too many failed logins; Retry-After in seconds.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /server

Version, uptime, node, CPU/memory and totals

Responses

  • 200

    Server information.

    ServerInfo
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

auth

Web UI sessions (cookie login

post /auth/login

Log in (web UI) and get a session cookie

Exchanges a user/password (api.users) or an API key (api.keys) for the session cookie alteoxms_session (opaque, HttpOnly, SameSite=Strict, Secure on HTTPS, Path=/). Nothing secret has to be kept by the browser. No credentials are needed for this call; failed attempts are throttled like other logins (429). A browser request from another origin is rejected (403). The response carries the CSRF token that cookie-authenticated POST, PUT, PATCH and DELETE requests must send as X-CSRF-Token.

Request body application/json

LoginRequest

Responses

  • 200

    Logged in; Set-Cookie carries the session.

    Identity
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error
  • 429

    too_many_requests: too many failed logins; Retry-After in seconds.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /auth/logout

End the current UI session

Deletes the session of the alteoxms_session cookie (on every cluster node) and clears the cookie. Needs X-CSRF-Token while the session is valid; without a (valid) session it only clears the cookie (204).

Parameters

NameInTypeDescription
X-CSRF-Tokenheaderstring

Responses

  • 204

    Logged out (cookie cleared).

  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /auth/sessions

Revoke UI sessions (all, or one user's)

Ends the web UI sessions of user (a user or API key name), or of everyone without user. Sessions also end automatically when their user/key is removed or gets another role or password.

Parameters

NameInTypeDescription
userquerystring

Responses

  • 200

    Sessions revoked.

    object
    Fields
    FieldTypeDescription
    revoked*integer
    min: 0
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

health

Health and readiness for monitoring

get /healthz

Liveness probe (no authentication)

200 while the process serves HTTP. Plain text: ok, version, uptime, channel count.

Responses

  • 200

    Alive.

    string

get /readyz

Readiness probe (no authentication)

200 when the node can do its job: configuration loaded, HTTP (and SRT) listeners bound, channels applied and, in cluster mode, joined with a known leader and a replicated configuration. 503 with the failing checks otherwise, also while shutting down.

Responses

get /health

Aggregated health for monitoring (JSON or Nagios)

status is critical when a channel failed, a critical alarm is active or the cluster has no leader; degraded when a channel is degraded (or starting), a warning alarm is active, or a transcoder restarted / an input failed over in the last 10 minutes; else ok. Stopped channels (disabled, or running on another cluster node) are counted but are not problems.

?format=nagios returns one Nagios/Icinga plugin line (ALTEOXMS <STATE> - <text> | <perfdata>). State → exit code → HTTP status: OK → 0 → 200, WARNING → 1 → 200, CRITICAL → 2 → 503, UNKNOWN → 3 → 503; the exit code is also in X-Nagios-Exit-Code. The JSON form always answers 200.

Parameters

NameInTypeDescription
formatquerystring

Responses

  • 200

    Health report (JSON), or a Nagios line with state OK or WARNING.

    Health
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 503

    Nagios format with state CRITICAL (or UNKNOWN); or the API is disabled (JSON error).

    string

channels

Channel configuration and control

get /channels

Channels with status summary

Parameters

NameInTypeDescription
labelqueryarray of string

Label filter, repeatable (all must match): key=value or key (label present).

templatequeryarray of string

Channels using one of these templates (repeatable); empty = channels without template.

Responses

  • 200

    Channels sorted by name.

    object
    Fields
    FieldTypeDescription
    channels*array of ChannelSummary
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

post /channels

Create a channel (starts immediately unless enabled is false)

Parameters

NameInTypeDescription
dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ChannelConfigRequest

Responses

  • 201

    Created; body is the stored configuration.

    ChannelResponse
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /channels/actions

Restart, start or stop many channels

Targets either an explicit channels list or a selector (name_prefix and/or label, both must match; an empty selector is rejected). start/stop change enabled of all targets in one configuration write (persisted / replicated once); if that write fails the request fails as a whole and nothing changed. restart restarts the running channels on this node (up to 8 in parallel).

The response is always 200 when the request itself was valid (multi-status semantics without HTTP 207): see results[].status and the succeeded / failed counts. Names in channels that do not exist are reported with code: not_found. A channel that is itself named actions keeps working with GET/PUT/PATCH/DELETE on this path.

Parameters

NameInTypeDescription
dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

BulkActionRequest

Responses

  • 200

    Per-channel results.

    BulkActionResponse
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /channels/{name}

Channel configuration

Secrets in URLs are verbatim for admins and redacted (***) for viewers or with ?redact=true. A channel with a template is returned in its stored form: only the fields it sets itself (overrides lists their paths), plus the read-only effective channel (template ⊕ channel) the runtime uses.

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

redactqueryboolean

Responses

  • 200

    The channel configuration.

    ChannelResponse
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error

put /channels/{name}

Replace the channel configuration

Full replacement; name may be omitted (renaming is not supported). Omitted enabled, labels, failover.node_standby and outputs.hls.ts_segments keep their stored values. A URL secret of exactly *** keeps the stored value. With template the body is the channel's stored form: omitted fields are inherited from the template, sent fields are stored as overrides; without template a templated channel keeps its template and stores the fields that differ from it; template: null detaches it (docs/API.md 4.14).

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ChannelConfigRequest

Responses

  • 200

    Stored configuration.

    ChannelResponse
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /channels/{name}

Delete the channel (closes its sessions)

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 204

    Deleted.

  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

patch /channels/{name}

Change parts of the channel configuration (JSON Merge Patch)

RFC 7386 JSON Merge Patch over the configuration as an admin's GET returns it: objects merge, null removes a field (it takes its default; for a templated channel: the template's value again), arrays (inputs, outputs.udp) are replaced as a whole. The result is validated exactly like a PUT (same details), with If-Match, dry_run and *** secrets. Content-Type application/merge-patch+json (or application/json).

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/merge-patch+json, application/json

ChannelPatch

Responses

  • 200

    Stored configuration.

    ChannelResponse
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 415

    unsupported_media_type: PATCH body is not application/merge-patch+json / application/json.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /channels/{name}/status

Full live status

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Responses

  • 200

    Live status (refreshed at least once per second).

    ChannelStatus
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error

post /channels/{name}/start

Start a stopped channel (enabled = true, persisted)

Idempotent (changed: false when it already was enabled). The body is ignored.

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 200

    New state.

    EnabledResult
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /channels/{name}/stop

Stop a channel without deleting it (enabled = false, persisted)

Stops inputs, transcoder and outputs and closes the channel's sessions; the configuration is kept and the status shows state: stopped. Idempotent. The body is ignored.

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 200

    New state.

    EnabledResult
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /channels/{name}/make-static

Store a dynamic channel as a configured channel

Copies the configuration a dynamic channel (server.config_lookup) currently runs with into the configuration (persisted like a POST /channels); from then on the configured channel wins and the lookup server is no longer asked for it. The running channel keeps running. Names with "/" cannot be configured channels (422).

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 201

    Stored configuration.

    ChannelResponse
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /channels/{name}/restart

Restart the channel runtime

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Responses

  • 202

    Restarting.

    object
    Fields
    FieldTypeDescription
    status*"restarting"
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error

post /channels/{name}/switch-input

Manual failover (index) or back to automatic (null)

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Request body application/json

object

FieldTypeDescription
index*integer | null
min: 0

Responses

  • 200

    Switch requested (happens at the next keyframe).

    object
    Fields
    FieldTypeDescription
    active_input*integer | null
    failover_mode*FailoverMode
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error

post /channels/{name}/tracks/preview

Resolve a track selection against the live source (nothing is applied)

Any role. Resolves tracks (null = no selection) against the source program of input (default: the active input). A channel that does not run on this node resolves against no source (every slot missing, input null).

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Request body application/json

object

FieldTypeDescription
tracksnull | TracksRequest
inputinteger | null
min: 0

Responses

  • 200

    Resolution.

    TrackMap
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error

post /channels/{name}/preview-token

Short-lived token to play the channel without the auth hook

Admins; viewers only with api.viewer_preview: true.

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Request body application/json

object

FieldTypeDescription
ttlDuration

10s..15m, default 5m

Responses

  • 201

    Token and playback URLs ("" for disabled outputs).

    PreviewToken
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

events

Live updates (server-sent events)

get /events

Server-sent events (live status)

text/event-stream. Events (event: → data: schema): snapshot → EventSnapshot, status → EventStatus (changed channels only), channel_status → ChannelStatus (for ?channel=), channel_added → ChannelSummary, channel_removed → EventChannelRemoved, switch → EventSwitch, alarm_raised / alarm_cleared → AlarmEvent. Keepalive comment every 15 s, retry: 3000, no replay after reconnect.

Parameters

NameInTypeDescription
channelqueryarray of string

Also stream the full status of these channels (repeatable).

Responses

  • 200

    Event stream.

    string
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

profiles

Transcode profiles

get /profiles

Transcode profiles

Responses

  • 200

    Profiles sorted by name.

    object
    Fields
    FieldTypeDescription
    profiles*array of Profile
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

post /profiles

Create a transcode profile

Parameters

NameInTypeDescription
dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ProfileRequest

Responses

  • 201

    Created.

    Profile
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /profiles/{name}

One profile

Parameters

NameInTypeDescription
name*pathName

Responses

  • 200

    The profile.

    Profile
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error

put /profiles/{name}

Replace a profile (channels using it restart their transcoder)

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ProfileRequest

Responses

  • 200

    Stored profile.

    Profile
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /profiles/{name}

Delete a profile (409 in_use when channels use it)

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 204

    Deleted.

  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

patch /profiles/{name}

Change parts of a profile (JSON Merge Patch)

Like PATCH /channels/{name}; video and audio arrays are replaced as a whole.

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/merge-patch+json, application/json

ProfilePatch

Responses

  • 200

    Stored profile.

    Profile
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 415

    unsupported_media_type: PATCH body is not application/merge-patch+json / application/json.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

templates

Channel templates (shared channel settings with per-channel overrides)

get /channel-templates

Channel templates

Responses

  • 200

    Templates sorted by name.

    object
    Fields
    FieldTypeDescription
    templates*array of ChannelTemplate
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

post /channel-templates

Create a channel template

Parameters

NameInTypeDescription
dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ChannelTemplateRequest

Responses

  • 201

    Created.

    ChannelTemplate
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /channel-templates/{name}

One channel template

Parameters

NameInTypeDescription
name*pathName

Responses

  • 200

    The template.

    ChannelTemplate
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error

put /channel-templates/{name}

Replace a template (re-applied to its channels; only channels whose effective configuration changed restart)

The body is the complete set of the template's settings (omitted = not set). Every channel using the template keeps its overrides and gets the new effective configuration; a change that makes one of them invalid is 422 with details under channels[i]... naming the channel.

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json

ChannelTemplateRequest

Responses

  • 200

    Stored template.

    ChannelTemplate
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /channel-templates/{name}

Delete a template (409 in_use with the channels using it)

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Responses

  • 204

    Deleted.

  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

patch /channel-templates/{name}

Change parts of a template (JSON Merge Patch)

Like PATCH /channels/{name}; null removes a setting from the template.

Parameters

NameInTypeDescription
name*pathName
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/merge-patch+json, application/json

ChannelTemplatePatch

Responses

  • 200

    Stored template.

    ChannelTemplate
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 415

    unsupported_media_type: PATCH body is not application/merge-patch+json / application/json.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

capabilities

FFmpeg / hardware probe

get /capabilities

Hardware and encoders available for transcoding

Responses

  • 200

    Probe result (without FFmpeg everything is unavailable, still 200).

    Capabilities
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

post /capabilities/probe

Re-run the FFmpeg/hardware probe

Responses

  • 200

    New probe result.

    Capabilities
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error

sessions

Client sessions

get /sessions

Client sessions (newest first)

Parameters

NameInTypeDescription
channelquerystring
protocolquerystring
modequerystring
limitqueryinteger
offsetqueryinteger

Responses

  • 200

    Sessions.

    object
    Fields
    FieldTypeDescription
    total*integer
    min: 0
    sessions*array of Session
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

delete /sessions

Kick every session of a user, token or client IP (all protocols, cluster-wide), optionally block it

Selectors are combined (all given ones must match); at least one of user, token, ip is required. Kicks SRT (shared listener and dedicated ports), HTTP-TS and HLS/DASH sessions and drops the auth hook's cached decisions for the selector, so reconnects ask the hook again. With block the selector is blocked first: matching clients are rejected before the auth hook is asked (SRT reject 1403, HTTP 403) until the block expires or is removed. In a cluster the kick is forwarded to every node and the block is replicated.

Parameters

NameInTypeDescription
userquerystring
tokenquerystring
ipquerystring

Client IP address or CIDR prefix.

channelquerystring

Only this channel (default all).

blockquerystring

Also block the client(s) for this long (Go duration, 1s..24h, e.g. 10m).

Responses

  • 200

    Kicked sessions (possibly none) and the block.

    KickResult
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /sessions/{id}

Kick a session (optionally block its user/token/IP on its channel)

Drops the auth hook's cached decisions for the session's channel, user, token and IP so a reconnect asks the hook again. In a cluster a session that is not on this node is looked up on the other nodes. With block the session's user (else token, else client IP) is blocked on the session's channel.

Parameters

NameInTypeDescription
id*pathstring
blockquerystring

Also block the client(s) for this long (Go duration, 1s..24h, e.g. 10m).

Responses

  • 200

    Kicked and blocked (with block).

    KickResult
  • 204

    Closed.

  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /blocks

Active temporary blocks (newest first)

Responses

  • 200

    Blocks.

    object
    Fields
    FieldTypeDescription
    blocks*array of Block
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

delete /blocks/{id}

Remove a block (cluster-wide)

Parameters

NameInTypeDescription
id*pathstring

Responses

  • 204

    Removed.

  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

config

Configuration import/export (YAML)

get /config

Export the full configuration (JSON or YAML)

Parameters

NameInTypeDescription
redactqueryboolean

Redact secrets (always for viewers).

formatquerystring

Output format; default: the format of the server's config file.

Responses

  • 200

    Config document (ARCHITECTURE §5 schema) in the config file's format, or the one asked for.

    object
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

put /config

Import the full configuration (JSON or YAML, detected from the content)

Parameters

NameInTypeDescription
If-Matchheaderstring

ETag from a GET; on mismatch 412 precondition_failed. Without it the last writer wins.

dry_runqueryboolean

Validate and answer as usual, but store and apply nothing.

Request body application/json, application/yaml

object

Responses

  • 200

    Applied (or, with dry_run, what would change).

    ConfigImportResult
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 412

    precondition_failed: If-Match does not match the current ETag.

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /config/validate

Validate a configuration (JSON or YAML) without applying it

Request body application/json, application/yaml

object

Responses

  • 200

    Validation result.

    ConfigValidation
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error

post /config/import/flussonic

Import a Flussonic configuration (dry run by default)

Converts a Flussonic flussonic.conf (request body) into channels and transcode profiles and merges them into the current configuration (docs/MIGRATION-FLUSSONIC.md). By default nothing is stored (dry_run=true): the response shows the resulting configuration (config in format, plus the commented yaml), the import report and what would change. With dry_run=false the result is stored and applied like PUT /config. Existing channels are never replaced unless overwrite=true; problems of single streams are reported (severity error) and those parts left out.

Parameters

NameInTypeDescription
dry_runqueryboolean

Default true: only report. false: store and apply.

overwritequeryboolean

Replace existing channels (and differing profiles) of the same name.

disable_allqueryboolean

Import every channel disabled (label flussonic_state keeps the Flussonic state).

no_dashqueryboolean

Do not enable DASH output.

no_hlsqueryboolean

Do not enable HLS output.

no_http_tsqueryboolean

Do not enable HTTP MPEG-TS output.

formatquerystring

Format of the response's config (default the server's config file format, like GET /config).

Request body text/plain

string

Responses

  • 200

    Import result (applied or dry run).

    FlussonicImportResult
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 402

    license_limit: the change would exceed the license's channel limit (enabled configured channels plus running dynamic ones; in a cluster limit × seats). A configuration already above the limit (downgrade) can still be edited while the count does not grow.

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

cluster

Cluster membership and placement

get /cluster

Cluster nodes, roles, health, capacity and placement

Responses

  • 200

    Cluster view (standalone nodes return the short form).

    ClusterStatus | StandaloneStatus
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

get /cluster/placement

Channel placement

Responses

  • 200

    Placement.

    object
    Fields
    FieldTypeDescription
    placement*Placement
    unplaced*array of string
    unplaced_reasons*map of string
    strategy*string
    one of: "spread", "pack"
    max_channels_per_node*integer
    min: 0
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /cluster/events

Cluster events (newest first, last 256)

Parameters

NameInTypeDescription
afterqueryinteger

Responses

  • 200

    Events.

    object
    Fields
    FieldTypeDescription
    events*array of ClusterEvent
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

get /cluster/channels/{name}

Where a channel is served

Parameters

NameInTypeDescription
name*pathChannelNameAny

A channel name; dynamic channels (server.config_lookup) may contain "/" (send it as %2F).

Responses

  • 200

    Location.

    ChannelLocation
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /cluster/nodes

Add a node (raft voter)

Request body application/json

ClusterNodeRef

Responses

  • 201

    Added.

    ClusterNodeRef
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /cluster/nodes/{id}

Remove a node (its channels move)

Parameters

NameInTypeDescription
id*pathstring

Responses

  • 204

    Removed.

  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /cluster/nodes/{id}/drain

Drain a node (maintenance)

Parameters

NameInTypeDescription
id*pathstring

Responses

  • 202

    Draining.

    DrainResult
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

delete /cluster/nodes/{id}/drain

End draining (nothing moves back automatically)

Parameters

NameInTypeDescription
id*pathstring

Responses

  • 202

    No longer draining.

    DrainResult
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

gpus

GPU monitoring

get /gpus

GPU monitoring, admission state and policy of this node (WP 6.3)

Without monitoring configured monitor.state is off and the lists are empty (still 200). Unreported driver values are null.

Responses

  • 200

    GPU view.

    GPUInfo
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

get /gpus/capacity

How many more channels of a profile fit on the GPUs

Parameters

NameInTypeDescription
profile*querystring

Responses

  • 200

    Capacity per GPU, node total and (cluster mode) per node. total -1 when the profile does not use an NVIDIA GPU here or monitoring is off.

    GPUCapacity
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error

get /alarms

Active alarms and the last raise/clear events of this node

Parameters

NameInTypeDescription
afterqueryinteger

Only events with a larger seq.

Responses

  • 200

    Alarms (sorted by name and labels) and events (newest first, at most 256).

    object
    Fields
    FieldTypeDescription
    node*string
    alarms*array of Alarm
    events*array of AlarmEvent
    last_seq*integer
    min: 0
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

license

Licensing: status, license key, EULA, deactivation (docs/LICENSING.md, API.md §16)

get /license

License status of this server (admin)

Status, tier, limits, expiry, lease age, install id, fingerprint, EULA, warnings and the license server's messages (docs/LICENSING.md §5). mode: dev = a build without embedded license keys: nothing is enforced (status: dev, serving: true).

Responses

  • 200

    License status.

    LicenseStatus
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

put /license

Enter a license key (activate) (admin)

Verifies the key (AMS1.…, signed by the license server), activates it at the license server (POST /activate; not for offline licenses) and stores it. Errors: 400 invalid_license (does not verify, offline license for another machine), 409 with the license server's code (seats_exhausted, revoked, expired) or dev_build, 502 license_server_unavailable (the key is stored and activation is retried in the background).

Request body application/json

object

FieldTypeDescription
license*string

The license key text (AMS1.<payload>.<signature>).

max length: 16384

Responses

  • 200

    Activated; the new status.

    LicenseStatus
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    The license server refused the key (seats_exhausted, revoked, expired), or dev_build (a build without license keys cannot verify keys).

    Error
  • 413

    bad_request: request body too large (JSON 1 MiB, YAML 4 MiB).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 502

    license_server_unavailable: the key verified and is stored, but the license server could not be reached; activation is retried in the background.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /license/eula

Accept the EULA (admin)

version must be the eula.version of GET /license (the text the admin was shown); another version is 409 eula_version. The server serves no viewers and outputs before the EULA is accepted (server.license.accept_eula: true accepts it for automated installs).

Request body application/json

object

FieldTypeDescription
version*string

Responses

  • 200

    Accepted; the new status.

    LicenseStatus
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 409

    already_exists, in_use (details list the users) or conflict (impossible in the current state, or a cluster write raced; retry).

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

post /license/deactivate

Release the seat and remove the license from this server (admin)

Tells the license server (POST /deactivate, online licenses) and removes the license here. released: false: the license server could not be told — release the seat in the license portal. The server stops serving viewers and outputs.

Responses

  • 200

    Removed.

    object
    Fields
    FieldTypeDescription
    released*boolean
    messagestring
    license*LicenseStatus
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 503

    unavailable: API disabled (no credentials configured), clustering disabled, no cluster leader / quorum, preview tokens or FFmpeg not available.

    Error

notifications

Operator notifications via Mattermost and e-mail (WP 6.9)

get /notifications

Notification targets (secrets redacted), delivery status and queue of this node

Targets come from the node-local notifications: section. Webhook keys are redacted (https://mm.example/hooks/***), SMTP passwords never shown. state: ok (last attempt succeeded), failing, idle (nothing sent yet). Failures of a target are reported here, in the log and in alteoxms_notification_up — not as alarms.

Responses

  • 200

    Notifier status.

    Notifications
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

post /notifications/test

Send a test message to one target or all (admin)

Sends right away (no hold-down, filter, batching or retry) and waits for the outcome. 200 also when the delivery failed: see ok and results[].error.

Request body application/json

object

FieldTypeDescription
target*string

Target name or "all".

Responses

  • 200

    Outcome per target.

    object
    Fields
    FieldTypeDescription
    ok*boolean

    Every target accepted the message.

    results*array of object
    target*string
    type*string
    one of: "mattermost", "email"
    ok*boolean
    errorstring
    duration_ms*number
    min: 0
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error
  • 403

    forbidden: the role does not allow the action, a cookie-authenticated write failed the CSRF check, or a PUT /config tries to change api.allow_extra_args (detail code read_only). extra_args_disabled: the write would set or change a transcode profile's extra_args while api.allow_extra_args is off (details name the field paths).

    Error
  • 404

    not_found: channel/profile/session/node does not exist.

    Error
  • 422

    validation_failed: semantically invalid; details per field.

    Error

event-sinks

Flussonic-style event sinks (play_closed

get /event-sinks

Event sinks of this node (Flussonic event_sink) with delivery status

Sinks come from the node-local event_sinks: section (or PUT /streamer/api/v3/event_sinks/{name}). URLs are redacted. state: idle (nothing sent yet), ok (last POST succeeded), retrying (last POST failed; the batch is retried with backoff 1 s .. 1 min), rejected (the sink answered 4xx: batch dropped). Events and the mapping: docs/API.md §15.2.

Responses

  • 200

    Sink status.

    EventSinks
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

flussonic-compat

Flussonic HTTP API v3 compatibility subset under /streamer/api/v3 (docs/API.md §15.3)

get /streams

Flussonic API v3: streams (compatibility subset)

Every channel as a Flussonic stream, sorted by name. select keeps only the given dotted paths (comma separated, name is always included; a path through a list applies to every element, e.g. inputs.url). Input URLs are complete for admins, redacted for viewers. Errors use Flussonic's {"errors":[...]} body.

Parameters

NameInTypeDescription
limitqueryinteger
selectquerystring
namequerystring

Only the stream with this name.

Responses

  • 200

    Streams.

    object
    Fields
    FieldTypeDescription
    streams*array of FluStream
    estimated_count*integer

    Streams before limit.

    min: 0
  • 400

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

get /streams/{name}

Flussonic API v3: one stream

Parameters

NameInTypeDescription
name*pathstring
selectquerystring

Responses

  • 200

    The stream.

    FluStream
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 404

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

get /config/stats

Flussonic API v3: server statistics

transcoder_devices are the GPUs of the GPU monitor (type: nvenc for NVIDIA); utilization in percent (0 when not measured).

Responses

  • 200

    Server statistics.

    FluServerStats
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

get /event_sinks

Flussonic API v3: event sinks

Responses

  • 200

    Event sinks.

    object
    Fields
    FieldTypeDescription
    event_sinks*array of FluEventSink
    estimated_count*integer
    min: 0
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

get /event_sinks/{name}

Flussonic API v3: one event sink

Parameters

NameInTypeDescription
name*pathName

Responses

  • 200

    The event sink.

    FluEventSink
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 404

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

put /event_sinks/{name}

Flussonic API v3: create or update an event sink (admin)

Creates the sink or changes the given fields of an existing one; persisted in the config file (event_sinks, node-local, also in a cluster) and applied at once. Unknown fields (other Flussonic event_sink settings) are ignored.

Parameters

NameInTypeDescription
name*pathName

Request body application/json

object

FieldTypeDescription
urlstring

http(s) URL the events are POSTed to (required for a new sink).

eventsarray of string

Only these events (empty = all).

formatstring
one of: "flussonic", "ndjson"

Responses

  • 200

    The stored event sink.

    FluEventSink
  • 400

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 403

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 422

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

delete /event_sinks/{name}

Flussonic API v3: delete an event sink (admin)

Parameters

NameInTypeDescription
name*pathName

Responses

  • 204

    Deleted.

  • 401

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 403

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError
  • 404

    Flussonic API v3 error body (401 carries WWW-Authenticate: Basic realm="alteoxms").

    FluError

status

get /analytics

Per-channel and per-source history (bitrate, viewers, errors, TR 101 290) and node CPU/GPU of the last hour, day or week

In-memory history since the server started (docs/API.md 14): totals per time bucket, per-channel sums ranked by operational errors, and with channel= that channel's full series.

Parameters

NameInTypeDescription
rangequerystring

1h: 10 s buckets, 24h: 1 min, 7d: 10 min.

channelquerystring

Also return this channel's full series.

Responses

  • 200

    Analytics of the range.

    Analytics
  • 400

    bad_request: malformed JSON/YAML, unknown field, wrong type, bad query parameter.

    Error
  • 401

    unauthorized: missing or invalid credentials (WWW-Authenticate: Bearer realm="alteoxms").

    Error

Schemas

ActiveAlarm object
FieldTypeDescription
id*string
severity*string
one of: "critical", "warning", "info"
source*string
subjectstring
message*string
since*Time
AdmissionState string
Alarm object
FieldTypeDescription
name*string
severity*string
one of: "critical", "warning", "info"
labels*map of string
message*string
node*string
source*string
since*Time
updated*Time
AlarmEvent object
FieldTypeDescription
seq*integer
min: 1
type*string
one of: "alarm_raised", "alarm_cleared"
at*Time
alarm*Alarm
duration_snumber

How long it was active (clears).

min: 0
notifications*array of NotificationDelivery

What the notifier did with this event, per target (target "*" for flap suppression and a full queue). Empty without notifications or while waiting for the hold-down.

Analytics object
FieldTypeDescription
range*string
one of: "1h", "24h", "7d"
step_s*integer
from*string (date-time)
to*string (date-time)
totals*array of AnalyticsPoint

All channels per bucket.

sums*AnalyticsCounters
channels*array of object

Channels with data in the range, by error_total (descending), then name.

name*string
bitrate_in_avg*integer
min: 0
bitrate_out_avg*integer
min: 0
bitrate_out_max*integer
min: 0
viewers_peak*integer
min: 0
errors*AnalyticsCounters
error_total*integer
min: 0
spark*array of integer

Bitrate out, at most 60 averages.

seriesarray of AnalyticsPoint

The channel's buckets (with channel=).

sources*array of object

Sources (input URLs, redacted) over all channel inputs using them, worst first: error_total, then TR 101 290 P1+P2, then URL. Errors often belong to a source shared by several channels.

url*string

Redacted input URL; publish inputs are publish://<channel>.

used_by*array of string

Channel inputs that used the source in the range: <channel>#<n>, n from 1.

bitrate_in_avg*integer

Highest per-input average.

min: 0
errors*AnalyticsCounters
error_total*integer
min: 0
system*array of object

The node per bucket: averages, GPU temperature the peak; null: not measured (no procfs, no GPU monitor).

t*string (date-time)
cpu_pct*number | null

Whole machine (FFmpeg included), %.

process_cpu_pct*number | null

This server process, % of all cores.

memory_pct*number | null

System memory used, %.

load1*number | null
gpus*array of object
index*integer
min: 0
util*number | null
encoder*number | null

NVENC utilisation, %.

decoder*number | null

NVDEC utilisation, %.

memory_pct*number | null
temperature_c*number | null
power_w*number | null
gpus*array of object

GPUs seen since the server started.

index*integer
min: 0
name*string
AnalyticsCounters object

Error events of a bucket or range (deltas of the status counters). degraded_s / failed_s: seconds in that health. tr_p1..tr_p3: ETSI TR 101 290 errors of all inputs (not part of error_total).

FieldTypeDescription
cc_errors*integer
min: 0
input_errors*integer
min: 0
reconnects*integer
min: 0
transcoder_restarts*integer
min: 0
transcoder_stalls*integer
min: 0
failovers*integer
min: 0
degraded_s*integer
min: 0
failed_s*integer
min: 0
tr_p1*integer
min: 0
tr_p2*integer
min: 0
tr_p3*integer
min: 0
AnalyticsPoint object

One time bucket: bitrates are averages, viewers the peak, the rest as in AnalyticsCounters.

FieldTypeDescription
t*string (date-time)

Bucket start.

bitrate_in*integer
min: 0
bitrate_out*integer
min: 0
viewers*integer
min: 0
cc_errors*integer
min: 0
input_errors*integer
min: 0
reconnects*integer
min: 0
transcoder_restarts*integer
min: 0
transcoder_stalls*integer
min: 0
failovers*integer
min: 0
degraded_s*integer
min: 0
failed_s*integer
min: 0
tr_p1*integer
min: 0
tr_p2*integer
min: 0
tr_p3*integer
min: 0
Block object
FieldTypeDescription
id*string
channelstring

Omitted = all channels.

userstring
tokenstring

Masked (first 4 characters of long tokens, else ***).

ipstring

Address or CIDR prefix.

created*Time
expires*Time
expires_in_s*number
min: 0
bystring

API user that created the block.

BulkActionRequest object

Exactly one of channels or selector.

FieldTypeDescription
action*string
one of: "restart", "start", "stop"
channelsarray of string
max items: 1000
selectorobject
name_prefixstring
labelstring

key=value or key (present)

BulkActionResponse object
FieldTypeDescription
action*string
one of: "restart", "start", "stop"
dry_run*boolean
matched*integer

Existing channels targeted.

min: 0
succeeded*integer
min: 0
failed*integer
min: 0
results*array of object

Matched channels (sorted for selectors, request order for channels), then unknown names.

name*string
status*string
one of: "ok", "unchanged", "error"
codestring

Error code (e.g. not_found, conflict, internal) for status error.

messagestring
Capabilities object
FieldTypeDescription
ffmpeg*object
available*boolean
path*string
version*string
probed_at*Time
hardware*map of object
auto*string

What hardware "auto" resolves to ("" if nothing works).

encoders*array of string
ChannelConfig object

One entry of channels: in the YAML config (defaults filled in).

FieldTypeDescription
name*ChannelNameAny
dynamicboolean

Read-only: a dynamic channel from the lookup server (server.config_lookup), not stored in the configuration; omitted for configured channels.

inputs*array of object

Array order is priority (index 0 = primary).

min items: 1 · max items: 16
url*string

srt, udp, rtp, http(s) (HLS when .m3u8), hls(s), publish:// or copy://<channel>[/<rendition>]

headers*map of string

Extra HTTP request headers (http/https/hls/hlss inputs); values are secrets ("***" when redacted).

user_agent*string

User-Agent override (http/https/hls/hlss); "" = default.

srt_publish*null | SRTPort

Dedicated SRT publish port of the publish:// input.

failover*object
loss_timeout*Duration
return_after*Duration
standby*string
one of: "hot", "cold"
select*FailoverSelect
max_connected*MaxConnected
node_standbystring
one of: "cold", "hot"
transcode*string | null | InlineProfile

Name of a profile, the channel's own inline profile (object), or null = passthrough.

outputs*object
srt*boolean
srt_play*null | SRTPort

Dedicated SRT play port (callers need no streamid).

http_ts*boolean
hls*null | object
dash*null | object
udp*array of object
max items: 16
url*string
auth*object
publish*boolean
read*boolean
enabled*boolean

false = configured but not running (state stopped).

labels*Labels
tracksnull | TracksConfig

Output track selection (ARCHITECTURE 4.4a); null = every source track.

on_demandboolean

The whole channel (input pulls included) runs only while it has consumers.

transcode_on_demandboolean

The transcoder runs only while a transcoded output has consumers (needs transcode).

on_demand_idleDuration

Time without consumers before it sleeps (default 30s).

ChannelConfigRequest object

Channel configuration in requests. Omitted optional fields take their defaults (PUT: enabled, labels, failover.node_standby, outputs.hls.ts_segments keep the stored values). outputs.hls / outputs.dash also accept true (defaults) and false (off).

FieldTypeDescription
nameName
inputsarray of object
url*string
headersmap of string | null
user_agentstring | null
srt_publishnull | SRTPortRequest
failoverobject | null
loss_timeoutDuration
return_afterDuration
standbystring
one of: "hot", "cold"
selectFailoverSelect
max_connectedMaxConnected
node_standbystring
one of: "cold", "hot"
transcodestring | null | InlineProfileRequest

Profile name, inline profile object, or null = passthrough.

outputsobject | null
srtboolean
srt_playnull | SRTPortRequest
http_tsboolean
hlsSegmentedRequest
dashSegmentedRequest
udparray of object
url*string
authobject | null
publishboolean
readboolean
enabledboolean
labelsmap of string | null | null

A null value removes a label the channel's template sets.

tracksnull | TracksRequest

Omitted in a PUT = keep; null = none.

on_demandboolean

Omitted in a PUT = keep.

transcode_on_demandboolean

Omitted in a PUT = keep; needs transcode.

on_demand_idlestring

Duration 1s..24h ("0" = default 30s); omitted in a PUT = keep.

templatestring | null

Channel template (§4.14): the body is then the channel's stored form (omitted = inherited). null detaches a templated channel.

overridesarray of string

Read only (ignored).

effectiveobject

Read only (ignored).

ChannelLocation object
FieldTypeDescription
channel*string
configured*boolean
primary*string
standbystring
local*boolean
primary_up*boolean
urlstring
srt_addressstring
ChannelNameAny string

A configured channel name (Name) or a dynamic channel name: up to 8 such elements joined by "/" (128 characters at most).

ChannelPatch object

JSON Merge Patch (RFC 7386) of ChannelConfig; null removes a field (default), arrays replace.

FieldTypeDescription
nameName
inputsarray of object | null
failoverobject | null
transcodestring | null | InlineProfileRequest

Profile name, inline profile object, or null = passthrough.

outputsobject | null
authobject | null
enabledboolean | null
labelsmap of string | null | null
tracksobject | null
on_demandboolean | null
transcode_on_demandboolean | null
on_demand_idlestring | null
templatestring | null

Attach (only the fields that differ from the template stay the channel's own) or, with null, detach.

ChannelResponse ChannelConfig | TemplatedChannel

A channel without template (ChannelConfig) or the stored form of a templated channel (TemplatedChannel).

ChannelState string

sleeping = on-demand channel without consumers (inputs stopped; not a failure). license_limit = enabled but not started: the license's channel limit is reached (docs/LICENSING.md §5).

ChannelStatus object
FieldTypeDescription
name*string
state*ChannelState
health*HealthValue
started_at*Time
uptime_s*number
min: 0
active_input*integer | null
pending_input*integer | null
failover_mode*FailoverMode
bitrate_in*integer
min: 0
inputs*array of InputStatus
failover*object
loss_timeout*Duration
return_after*Duration
standby*string
one of: "hot", "cold"
select*FailoverSelect
max_connected*MaxConnected
connected*integer

Pull inputs connected now.

min: 0
preferred*integer | null

Rank 1 of the selection order (best priority; with select quality the best-ranked input). null = none yet.

switches*integer
min: 0
last_switch*null | SwitchEvent
history*array of SwitchEvent
max items: 50
source*null | SourceStatus
track_map*null | TrackMap
transcoder*null | TranscoderStatus
on_demandOnDemandStatus
dynamicDynamicStatus
outputs*object
srt*StreamOutput
srt_playSRTPortStatus
http_ts*StreamOutput
hls*StreamOutput
dash*StreamOutput
udp*array of object
url*string
bitrate_out*integer
min: 0
packets*integer
min: 0
errors*integer
min: 0
viewers*integer
min: 0
bitrate_out*integer
min: 0
ChannelSummary object
FieldTypeDescription
name*string
transcode*string | null

Profile name, "(inline)" for a channel's own profile, null = passthrough.

outputs*array of string
input_count*integer
min: 0
enabled*boolean
labels*Labels
templatestring

Channel template (omitted when none).

dynamicboolean

A dynamic channel from the lookup server (omitted for configured channels).

status*object
state*ChannelState
health*HealthValue
uptime_s*number
min: 0
active_input*integer | null
active_input_url*string
failover_mode*FailoverMode
bitrate_in*integer
min: 0
bitrate_out*integer
min: 0
viewers*integer
min: 0
switches*integer
min: 0
last_switch*null | SwitchEvent
transcoder_state*string | null
one of: "starting", "running", "backoff", "stopped", "sleeping", null
transcoder_gpustring

Where the transcoder was admitted ("nvidia:1", "cpu" for a fallback); omitted without admission control.

transcoder_admissionAdmissionState
video*string
bitrate_history*array of integer
max items: 60
tracks*object

Source tracks of the active input by kind (all 0 without a source).

video*integer
min: 0
audio*integer
min: 0
subtitle*integer
min: 0
teletext*integer
min: 0
scte35*integer
min: 0
data*integer
min: 0
service_name*string

SDT service name of the source ("" if none).

output_viewers*map of integer

Viewers per output kind, one entry per item of outputs (udp is always 0).

on_demandobject

On-demand channels only.

state*OnDemandState
transcoderstring
one of: "sleeping", "waking", "running"
ChannelTemplate PartialChannel & object

A channel template (docs/API.md 4.14): the channel fields it sets (a template never sets name, enabled, inputs or outputs.srt_play), the channels using it and the read-only effective settings (the template applied to a default channel).

FieldTypeDescription
name*Name
used_by*array of string
effective*object
failover*object
transcode*string | null | InlineProfile
outputs*object
auth*object
labels*Labels
tracks*null | TracksConfig
on_demand*boolean
transcode_on_demand*boolean
on_demand_idle*Duration
ChannelTemplatePatch object

JSON Merge Patch (RFC 7386) of a ChannelTemplate; null removes a setting from the template.

FieldTypeDescription
nameName
failoverobject | null
transcodestring | null | InlineProfileRequest
outputsobject | null
authobject | null
labelsmap of string | null | null
tracksobject | null
on_demandboolean | null
transcode_on_demandboolean | null
on_demand_idlestring | null
ChannelTemplateRequest object

A template in requests: the fields of a channel request it sets (omitted = not set by the template); used_by and effective are read only and ignored. inputs, enabled, template and outputs.srt_play are rejected (422).

FieldTypeDescription
nameName
failoverobject | null
transcodestring | null | InlineProfileRequest
outputsobject | null
authobject | null
labelsmap of string | null
tracksnull | TracksRequest
on_demandboolean
transcode_on_demandboolean
on_demand_idlestring
used_byarray of string
effectiveobject
ClusterEvent object
FieldTypeDescription
seq*integer
min: 1
at*Time
type*string
one of: "node_joined", "node_up", "node_down", "node_removed", "node_drain", "node_undrain", "config_changed", "channel_placed", "channel_moved", "channel_promoted", "standby_assigned", "channel_unplaced"
nodestring
channelstring
fromstring
tostring
detailstring
duration_snumber
min: 0
ClusterNodeRef object
FieldTypeDescription
id*string
address*string

Cluster (raft/RPC) address host:port.

ClusterStatus object
FieldTypeDescription
enabled*true
mode*"cluster"
node*string
leader*string
term*integer
config_index*integer
strategy*string
one of: "spread", "pack"
max_channels_per_node*integer
min: 0
nodes*array of object
id*string
address*string
api_url*string
srt_addressstring
role*string
one of: "leader", "follower"
suffrage*string
one of: "voter", "nonvoter", "removed"
state*string
one of: "up", "down", "joining"
draining*boolean
channels*array of string
standby_channels*array of string
running*array of string
capacity*object
cpu_cores*integer
gpus*array of string
transcode*boolean
gpuGPUNodeReport
last_seen*Time
since*Time
version*string
placement*Placement
unplaced*array of string
unplaced_reasons*map of string

Channel → why it is unplaced ("no_gpu_capacity: …").

ConfigChanges object
FieldTypeDescription
channels_added*array of string
channels_removed*array of string
channels_changed*array of string

Effective configuration or stored form changed (a template change lists its channels whose effective configuration changed).

profiles_added*array of string
profiles_removed*array of string
profiles_changed*array of string
templates_added*array of string
templates_removed*array of string
templates_changed*array of string
ConfigImportResult object
FieldTypeDescription
applied*boolean
changes*ConfigChanges
restart_required*array of string
ConfiguredBitrate string | integer

"6000k", "6M" or an integer (bit/s); returned in the stored form.

ConfigValidation object
FieldTypeDescription
valid*boolean
errors*array of Detail
warnings*array of Detail
Detail object
FieldTypeDescription
field*string

Path into the request ("outputs.udp[0].url"); "" = whole object.

lineinteger

YAML line (config endpoints).

min: 1
code*string
one of: "required", "invalid", "out_of_range", "duplicate", "unknown_field", "not_found", "unavailable", "redacted_secret", "in_use", "extra_args_disabled", "read_only", "license_limit", "invalid_license"
message*string
DrainResult object
FieldTypeDescription
id*string
draining*boolean
Duration string

Go duration string.

DynamicStatus object

A dynamic channel from the lookup server (server.config_lookup, docs/API.md §4.15); omitted for configured channels.

FieldTypeDescription
source*string

The lookup server URL, secrets masked (***).

titlestring
providerstring
commentstring
static_list*boolean

From the lookup server's static stream list (runs while listed) rather than a request for its name.

created_at*Time
refreshed_at*Time
last_errorstring

The last refresh failed (the channel keeps its last good configuration); omitted after a successful one.

on_play*boolean

The lookup server gave a play authorization URL (on_play): viewers are authorized by the auth hook (auth.read).

notes*array of object

Remarks of the mapping (unsupported inputs, ignored transcoder options).

severity*string
one of: "info", "warning", "error"
message*string
EnabledResult object
FieldTypeDescription
name*string
enabled*boolean
changed*boolean

false when the channel already was in that state.

dry_runboolean
Error object
FieldTypeDescription
error*object
code*string
one of: "bad_request", "unauthorized", "forbidden", "not_found", "method_not_allowed", "already_exists", "in_use", "conflict", "precondition_failed", "unsupported_media_type", "validation_failed", "too_many_requests", "internal", "unavailable", "extra_args_disabled", "license_limit", "invalid_license", "dev_build", "seats_exhausted", "revoked", "expired", "license_server_unavailable", "eula_version"
message*string
details*array of Detail
EventChannelRemoved object
FieldTypeDescription
name*string
EventSinks object
FieldTypeDescription
event_sinks*array of object
name*string
url*string

Redacted.

format*string
one of: "flussonic", "ndjson"
events*array of string

Event filter (empty = all).

state*string
one of: "idle", "ok", "retrying", "rejected"
queued*integer
min: 0
queue_size*integer
min: 0
sent*integer

Events delivered.

min: 0
dropped*integer

Events lost: queue full, batch rejected (4xx), shutdown while retrying.

min: 0
batches*integer

Successful POSTs.

min: 0
failures*integer

Failed POST attempts.

min: 0
last_error*string
last_success*Time
last_failure*Time
EventSnapshot object
FieldTypeDescription
ts*Time
server*ServerInfo
channels*array of ChannelSummary
alarmsarray of Alarm

Active alarms (snapshot only).

EventStatus EventSnapshot

Same shape; channels holds only changed summaries.

EventSwitch object
FieldTypeDescription
channel*string
at*Time
from*integer | null
to*integer | null
reason*SwitchReason
detailstring
FailoverMode string
FailoverSelect string

Input selection: priority (default) or quality (docs/API.md 4.7b).

FluError object
FieldTypeDescription
errors*array of object
status*string
code*string
title*string
FluEventSink object
FieldTypeDescription
name*string
url*string

Complete for admins, redacted for viewers.

events*array of string
format*string
one of: "flussonic", "ndjson"
statsobject
name*string
url*string
format*string
events*array of string
state*string
one of: "idle", "ok", "retrying", "rejected"
queued*integer
queue_size*integer
sent*integer
dropped*integer
batches*integer
failures*integer
last_errorstring
last_success*string | null
last_failure*string | null
FluMediaInfo object
FieldTypeDescription
tracksarray of FluTrack
FluServerStats object
FieldTypeDescription
server_version*string
hostname*string
uptime*integer

seconds

cpu_usage*integer

percent

memory_usage*integer

percent of system memory

total_clients*integer
total_streams*integer
online_streams*integer

Streams with stats.alive.

transcoder_devices*array of object
id*integer
type*string
name*string
gpu_enc*integer

Encoder utilization %.

gpu_dec*integer

Decoder utilization %.

gpu_sm*integer

GPU (SM) utilization %.

mem_usage*integer

Memory used %.

FlussonicImportResult object
FieldTypeDescription
applied*boolean
yaml*string

The complete resulting configuration as YAML with comments on the imported parts (contains secrets; admin only). Always present; config holds the chosen format.

format*string

The format of config (the format parameter, else the config file format).

one of: "json", "yaml"
config*string

The complete resulting configuration in format, written like GET /config?format=<format> (unchanged parts byte-identical, so a line diff against it shows the import; the YAML is the commented yaml). Contains secrets; admin only.

summary*object
streams*integer
min: 0
templates*integer
min: 0
channels*integer
min: 0
channels_enabled*integer
min: 0
channels_disabled*integer
min: 0
channels_skipped*integer
min: 0
channels_overwritten*integer
min: 0
profiles*integer
min: 0
profiles_reused*integer
min: 0
channel_templates*integer

Channel templates imported (one per Flussonic template used by a stream with only that template).

min: 0
inputs*integer
min: 0
inputs_skipped*integer
min: 0
infos*integer
min: 0
warnings*integer
min: 0
errors*integer
min: 0
report*array of object
severity*string
one of: "info", "warning", "error"
streamstring

Flussonic stream name.

channelstring

Channel the stream became.

templatestring

Set for entries about a Flussonic template (reported once).

directivestring
lineinteger
min: 1
message*string
channels*array of string

Channels imported (added or overwritten).

profiles*array of string

Transcode profiles imported.

templates*array of string

Channel templates imported (added or replaced).

changes*ConfigChanges
FluStream object

A channel as a Flussonic stream. With select only the selected paths are present.

FieldTypeDescription
name*string
staticboolean

false for on-demand channels.

media_infoFluMediaInfo
inputsarray of object
urlstring

Complete for admins, redacted for viewers.

priorityinteger
statsobject
activeboolean
statusstring

Our input state: idle, connecting, receiving, error.

bitrateinteger

kbit/s

retry_countinteger

Reconnects.

errors_lost_packetsinteger

Continuity-counter errors.

media_infoFluMediaInfo
statsobject
aliveboolean

The active input delivers data.

statusstring
one of: "running", "starting", "failed", "sleeping", "stopped"
urlstring

The active input's URL ("" = none).

lifetimeinteger

ms since the channel started.

bitrateinteger

kbit/s of the active input.

online_clientsinteger
inputobject
protostring

Flussonic proto of the active input: tshttp, hls, srt, udp, rtp, publish, copy.

retriesinteger
input_switchesinteger
errors_lost_packetsinteger
retry_countinteger

Reconnects of all inputs.

errorsinteger

Errors of all inputs.

no_audioboolean

The source program has no audio track.

audio_lostboolean

The program has audio tracks but none carries data.

media_infoFluMediaInfo
FluTrack object
FieldTypeDescription
track_idstring
contentstring
one of: "video", "audio", "text", "metadata"
codecstring
pidinteger
widthinteger
heightinteger
fpsnumber
bitrateinteger

kbit/s

langstring
channelsinteger
sample_rateinteger
GPUCapacity object
FieldTypeDescription
node*string
profile*string
hardware*string
uses_gpu*boolean
enforced*boolean
pinned_gpu*integer | null
load*GPULoad
gpus*array of object | null
index*integer
uuid*string
name*string
fits*integer
reasonstring
total*integer

-1 = no estimate

note*string
clusterobject
total*integer
nodes*array of object
node*string
state*string
reported*boolean
enforced*boolean
fits*integer
best_gpu*integer
gpus*integer
GPUCapacityModel object
FieldTypeDescription
encode_mpix_s*number
decode_mpix_s*number
max_sessions*integer
memory_per_channel_mb*number
GPUDevice object
FieldTypeDescription
kind*"nvidia"
index*integer
uuid*string
name*string
driver_version*string
available*boolean

false when no sample for 5 s (alarm gpu_unavailable).

last_sample*Time
utilization*object
gpu*Metric
memory*Metric
encoder*Metric
decoder*Metric
memory*object
total_mb*Metric
used_mb*Metric
used_pct*Metric
temperature_c*Metric
power_w*Metric
power_limit_w*Metric
clock_sm_mhz*Metric
fan_pct*Metric
pstate*string
encoder*object
sessions*Metric
avg_fps*Metric
throttle*object
active*boolean
mask*string
reasons*array of string | null
capacity*GPUCapacityModel
model*object
known*boolean
arch*string
nvenc*integer
nvdec*integer
memory_mb*integer
consumer*boolean
verified*boolean
capacity_source*string
committed*object
encode_mpix_s*number
decode_mpix_s*number
sessions*integer
effective*object
encode_pct*number
decode_pct*number
memory_pct*Metric
session_limit*integer

0 = none

session_limit_source*string
headroom*GPUFree
full*boolean
channels*array of object | null
channel*string
profile*string
pid*integer
memory_mb*Metric
encode_mpix_s*number
decode_mpix_s*number
sessions*integer
since*Time
GPUFree object
FieldTypeDescription
encode_mpix_s*number
decode_mpix_s*number
memory_mb*number

-1 = unknown

sessions*integer

-1 = unlimited

GPUInfo object
FieldTypeDescription
node*string
monitor*object
state*string
one of: "off", "not_found", "starting", "running", "no_devices", "failed"
reason*string
path*string
last_error*string
restarts*integer
parse_errors*integer
samples*integer
last_sample*Time
dropped_fields*array of string | null
apps_at*Time
apps_error*string
enforced*boolean

Admission control active.

policy*object
max_encoder_util*number
max_decoder_util*number
max_memory_used*number
max_temperature*number
max_sessions*string

"auto" or a number

reserve*number
hysteresis*number
on_full*string
retry_interval*string
capacity*GPUCapacityModel
models*map of GPUCapacityModel | null
assume_source*string
gpus*array of GPUDevice | null
waiting*array of object | null
channel*string
profile*string
reason*string
since*Time
cpu_fallback*boolean
queued*boolean
admissions*object
admitted*integer
rejected*integer
cpu_fallbacks*integer
queued*integer
unenforced*integer
session_limits_learned*integer
moves*integer
intel*null | object
GPULoad object
FieldTypeDescription
decode_mpix_s*number
encode_mpix_s*number
sessions*integer
memory_mb*number
GPUNodeReport object

GPU inventory and free capacity a node publishes to the cluster (WP 6.3).

FieldTypeDescription
monitor*string
enforced*boolean
gpus*array of object | null
index*integer
uuid*string
name*string
free*GPUFree
encode_mpix_s*number
decode_mpix_s*number
mem_per_channel_mb*number
load*number
channelsarray of string
waitingarray of string
Health object
FieldTypeDescription
status*string
one of: "ok", "degraded", "critical"
node*string
ts*Time
reasons*array of string

Why the status is not ok.

channels*object
total*integer
min: 0
ok*integer
min: 0
degraded*integer
min: 0
failed*integer
min: 0
stopped*integer

Disabled or running on another cluster node.

min: 0
sleeping*integer

On-demand channels without consumers (not a problem).

min: 0
problems*array of object
channel*string
state*ChannelState
health*string
one of: "degraded", "failed"
reason*string
transcoder_restarts_10m*integer
min: 0
input_failovers_10m*integer

Switches with reason input_lost.

min: 0
alarms_available*boolean

An alarm source (e.g. GPU monitoring) is registered.

alarms*array of ActiveAlarm
cluster*object
enabled*boolean
leader*string

Raft leader ("" = none: critical); standalone: this node.

HealthValue string
Identity object
FieldTypeDescription
user*string
method*string

session: authenticated by the UI session cookie.

one of: "basic", "api_key", "session"
role*string
one of: "admin", "viewer"
allow_extra_args*boolean

Server capability api.allow_extra_args (config file only). false = API writes may not set or change transcode profiles' extra_args (read only in the UI).

csrf_tokenstring

Cookie sessions only: send as X-CSRF-Token with unsafe methods.

expires_atTime

Cookie sessions only: absolute end of the session (idle timeout applies earlier).

InlineProfile object

A channel's own transcode profile (channel.transcode as an object): the fields of a Profile without its name and used_by.

FieldTypeDescription
hardware*string
deinterlace*string
one of: "auto", "on", "off"
deinterlace_ratestring

Omitted = frame. field: one frame per field (25i -> 50p).

one of: "frame", "field"
deinterlacerstring

Omitted = auto (bwdif if available).

one of: "auto", "yadif", "bwdif"
decodestring

NVIDIA decode location (docs/TRANSCODING.md 2.3). Omitted = auto.

one of: "auto", "gpu", "cpu"
cpu_decode_codecsarray of string

Source codecs decode=auto decodes on the CPU.

cropstring

x:y:w:h in source display pixels.

pattern: ^[0-9]+:[0-9]+:[0-9]+:[0-9]+$
scalerstring
one of: "bicubic", "bilinear", "lanczos"
separate_audioboolean

true = encode audio per rendition (default: once, shared via the tee muxer).

video*array of object
name*string
codec*string

none = audio-only rendition (Flussonic add_audio_only).

one of: "h264", "hevc", "copy", "none"
width*integer

0 or -1 = keep aspect ratio.

min: -1
height*integer
min: -1
bitrate*ConfiguredBitrate
max_rateConfiguredBitrate
buf_sizeConfiguredBitrate
gop*Duration
preset*string
profilestring
levelstring
fps*number
min: 0
resizestring
one of: "scale", "fit", "crop"
backgroundstring

Letterbox background for fit: blur or a colour.

sarstring
pix_fmtstring
one of: "yuv420p", "nv12"
rcstring
one of: "cbr", "vbr"
gop_framesinteger

Keyframe interval in frames (Flussonic gop=N); gop is then "0".

min: 0 · max: 1000
bframesinteger
min: 0 · max: 4
open_gopboolean
tunestring
one of: "hq", "ll", "ull"
multipassstring
one of: "disabled", "qres", "fullres"
spatial_aqboolean
temporal_aqboolean
lookaheadinteger
min: 0 · max: 32
audio*array of object
tracks*string
codec*string
one of: "aac", "ac3", "mp2", "copy"
bitrate*ConfiguredBitrate
channels*integer
min: 0
sample_rate*integer
min: 0
subtitles*object
copy*boolean
copy_teletext*boolean
copy_dvbsub*boolean
copy_scte35*boolean
copy_data*boolean
extra_argsarray of string

Raw FFmpeg output options (omitted when empty). Read only unless api.allow_extra_args is set in the config file.

InlineProfileRequest object

channel.transcode as an object in a channel write: the fields of a ProfileRequest without its name and used_by.

FieldTypeDescription
hardwarestring
deinterlacestring
deinterlace_ratestring
deinterlacerstring
decodestring
cpu_decode_codecsarray of string
cropstring
scalerstring
separate_audioboolean
videoarray of object
namestring
codecstring
widthinteger
heightinteger
bitrateConfiguredBitrate
max_rateConfiguredBitrate
buf_sizeConfiguredBitrate
gopDuration
presetstring
profilestring
levelstring
fpsnumber
resizestring
backgroundstring
sarstring
pix_fmtstring
rcstring
gop_framesinteger
bframesinteger
open_gopboolean
tunestring
multipassstring
spatial_aqboolean
temporal_aqboolean
lookaheadinteger
audioarray of object
tracksstring
codecstring
bitrateConfiguredBitrate
channelsinteger
sample_rateinteger
subtitlesobject
copyboolean
copy_teletextboolean
copy_dvbsubboolean
copy_scte35boolean
copy_databoolean
extra_argsarray of string | null

Omitted or null = keep the stored ones (PUT). Setting or changing them needs api.allow_extra_args (else 403 extra_args_disabled); sending the stored value unchanged is always accepted.

InputAnalysis object

Media analysis of an input (docs/API.md 4.7b); the last one (live false) while it is disconnected.

FieldTypeDescription
live*boolean
measured_at*Time
video_codec*string

"" = no video.

width*integer
min: 0
height*integer
min: 0
scan*string
one of: "", "interlaced", "progressive"
fps*number
min: 0
class*string
one of: "uhd", "hd", "sd", "audio", "unknown"
bitrate*integer
min: 0
video_tracks*integer
min: 0
audio_tracks*integer
min: 0
subtitle_tracks*integer
min: 0
teletext_tracks*integer
min: 0
audio_languages*array of string
missing_required*integer

Required track-map slots this input cannot fill.

min: 0
window*object
window_s*number
min: 0
observed_s*number
min: 0
errored_s*integer

Seconds with TR 101 290 P1 or CC errors, a gap or a reconnect.

min: 0
p1*integer
min: 0
p2*integer
min: 0
p1_per_min*number
min: 0
cc_errors*integer
min: 0
reconnects*integer
min: 0
gaps*integer
min: 0
InputPool object

The input's rank, quality score and connection slot (failover.select, failover.max_connected).

FieldTypeDescription
rank*integer
min: 1
score*integer | null

null = never measured.

min: 0 · max: 100
erroring*boolean
stable_for_s*number
min: 0
slot*string
one of: "active", "switching", "pinned", "requested", "pool", "probing", "cooldown", "standby", "connected", "push"
reason*string
failures*integer
min: 0
cooldown_until*Time
last_failure*string
InputStatus object
FieldTypeDescription
index*integer
min: 0
url*string

Secrets redacted.

state*string
one of: "idle", "connecting", "receiving", "error"
connected*boolean
active*boolean
health*HealthValue
bitrate*integer
min: 0
bytes*integer
min: 0
packets*integer
min: 0
errors*integer
min: 0
cc_errors*integer
min: 0
reconnects*integer
min: 0
last_data*Time
last_error*string
remote*string

Peer address; "channel:<source>[/<rendition>]" for copy:// inputs.

healthy_for_s*number
min: 0
srt_publishSRTPortStatus
tr101290TR101290Status
analysisnull | InputAnalysis
poolnull | InputPool
KickResult object
FieldTypeDescription
kicked*integer
min: 0
sessions*array of Session
blockBlock
failed_nodesarray of string

Cluster nodes the kick could not be forwarded to.

Labels map of string

Free key/value tags (at most 32). Keys ^[A-Za-z0-9][A-Za-z0-9_./-]{0,62}$, values ^[A-Za-z0-9_./-]{0,63}$.

LicenseMode string

dev = build without embedded license keys: nothing enforced.

LicenseStatus object
FieldTypeDescription
mode*LicenseMode
status*LicenseStatusValue
serving*boolean

Viewers and outputs are served (valid license and EULA accepted, or dev mode).

reasonstring

Why the server does not serve.

install_id*string
fingerprint*string
license*null | object
lease*null | object
limits*object
max_channels*integer

In force (0 = unlimited; also 0 without a valid license).

min: 0
cluster*boolean
channels*integer

Enabled configured channels plus running dynamic ones.

min: 0
eula*object
version*string
accepted*boolean
accepted_at*null | string
accepted_bystring
text*string
warnings*array of LicenseWarning
messages*array of object

Messages of the license server (last heartbeat).

level*string
one of: "info", "warning"
text*string
cms*object
url*string
last_heartbeat*null | string
heartbeat_errorstring
lease_errorstring
activation_pending*boolean
build_datestring
LicenseStatusValue string
LicenseWarning object
FieldTypeDescription
code*string
one of: "lease_stale", "license_expiring", "eula_required", "cluster_not_licensed"
message*string
daysinteger

Days until expires_at (license_expiring).

min: 1
LoginRequest object

Either user and password, or api_key.

FieldTypeDescription
userstring
passwordstring
api_keystring
MaxConnected integer

Pull inputs connected at once (hot standby only; 0 = all).

Metric number | null

Measured value; null = not reported by the driver ([N/A]).

Name string
NotificationDelivery object
FieldTypeDescription
target*string
type*string
one of: "mattermost", "email", ""
status*string
one of: "sent", "failed", "dropped", "suppressed"
at*Time
digest*boolean

Sent as part of a summary message.

errorstring
Notifications object
FieldTypeDescription
node*string
enabled*boolean

At least one target is configured.

queue_length*integer

Alarm events and messages waiting.

min: 0
queue_capacity*integer
min: 0
pending_hold_down*integer

Raises waiting for the hold-down.

min: 0
hold_down_s*number
min: 0
digest_threshold*integer
min: 0
digest_window_s*number
min: 0
rate_limit_per_minute*integer
min: 0
resolved*boolean

Resolved messages are sent.

sends_cluster_alarms*boolean

This node sends cluster-wide alarms (standalone, or the cluster leader).

dropped*integer

Alarm events dropped (queue full).

min: 0
flaps_suppressed*integer
min: 0
skipped_not_leader*integer
min: 0
unmatched*integer

Raises no target's filter selected.

min: 0
targets*array of object
name*string
type*string
one of: "mattermost", "email"
destination*string

Redacted: webhook URL with the key masked, or smtp://host:port (tls) → recipients.

min_severity*string
one of: "info", "warning", "critical"
events*array of string
labels*map of string
state*string
one of: "ok", "failing", "idle"
last_attempt*Time
last_success*Time
last_error*string
last_error_at*Time
sent*integer
min: 0
failed*integer
min: 0
dropped*integer
min: 0
digests*integer
min: 0
attempts*integer
min: 0
queue_length*integer
min: 0
batched*integer

Events waiting for the next summary.

min: 0
OnDemandState string
OnDemandStatus object

On-demand state of a channel (docs/API.md 4.3); present when on_demand or transcode_on_demand is configured.

FieldTypeDescription
on_demand*boolean
transcode_on_demand*boolean
idle*Duration
state*OnDemandState

The channel (its inputs); always awake without on_demand.

transcoderstring

Omitted for channels without transcoding.

one of: "sleeping", "waking", "running"
consumers*integer

Connected consumers (SRT, HTTP-TS, copy://).

min: 0
transcode_consumers*integer

Of these, consumers of a transcoded rendition.

min: 0
always_onstring

Why it never sleeps, e.g. "1 UDP output" (UDP outputs are permanent consumers).

last_consumer_at*Time
sleeping_since*Time
wakeups*integer
min: 0
last_wake_at*Time
last_wake_latency_ms*integer | null

Wake-up until the first data.

transcoder_wakeups*integer
min: 0
transcoder_last_wake_at*Time
transcoder_last_wake_latency_ms*integer | null
errorstring

Why the current wake-up fails (e.g. "transcoder not admitted (...)", no data in time).

PackagerStatus object
FieldTypeDescription
segments*integer
min: 0
last_segment*Time
status*string
unpackaged_audio*array of object

Source audio tracks missing from the CMAF HLS (index.m3u8) and DASH output because CMAF cannot carry their codec (MP2, AAC-LATM); in_ts_segments = still carried in the TS-segment HLS.

index*integer

n-th audio track of the program (0-based)

min: 0
pid*integer
min: 0 · max: 8191
codec*string

mp2, aac_latm

language*string
in_ts_segments*boolean
reason*string
renditions*array of object
name*string
running*boolean
segments*integer
min: 0
last_segment*Time
restarts*integer
min: 0
status*string
last_error*string
PartialChannel object

The fields of a channel object (§4.1) that a template or a templated channel sets itself; every field is optional and has the shape of ChannelConfig (a label may be null: the channel removes the template's label).

FieldTypeDescription
failoverobject
loss_timeoutDuration
return_afterDuration
standbystring
one of: "hot", "cold"
node_standbystring
one of: "cold", "hot"
transcodestring | null | InlineProfile
outputsobject
srtboolean
srt_playnull | SRTPort
http_tsboolean
hlsnull | object
dashnull | object
udparray of object
url*string
authobject
publishboolean
readboolean
labelsmap of string | null
tracksnull | TracksConfig
on_demandboolean
transcode_on_demandboolean
on_demand_idleDuration
Placement map of object
PreviewToken object
FieldTypeDescription
token*string
expires_at*Time
hls_url*string
dash_url*string
http_ts_url*string
Profile object
FieldTypeDescription
name*Name
hardware*string
deinterlace*string
one of: "auto", "on", "off"
deinterlace_ratestring

Omitted = frame. field: one frame per field (25i -> 50p).

one of: "frame", "field"
deinterlacerstring

Omitted = auto (bwdif if available).

one of: "auto", "yadif", "bwdif"
decodestring

NVIDIA decode location (docs/TRANSCODING.md 2.3). Omitted = auto.

one of: "auto", "gpu", "cpu"
cpu_decode_codecsarray of string

Source codecs decode=auto decodes on the CPU.

cropstring

x:y:w:h in source display pixels.

pattern: ^[0-9]+:[0-9]+:[0-9]+:[0-9]+$
scalerstring
one of: "bicubic", "bilinear", "lanczos"
separate_audioboolean

true = encode audio per rendition (default: once, shared via the tee muxer).

video*array of object
name*string
codec*string

none = audio-only rendition (Flussonic add_audio_only).

one of: "h264", "hevc", "copy", "none"
width*integer

0 or -1 = keep aspect ratio.

min: -1
height*integer
min: -1
bitrate*ConfiguredBitrate
max_rateConfiguredBitrate
buf_sizeConfiguredBitrate
gop*Duration
preset*string
profilestring
levelstring
fps*number
min: 0
resizestring
one of: "scale", "fit", "crop"
backgroundstring

Letterbox background for fit: blur or a colour.

sarstring
pix_fmtstring
one of: "yuv420p", "nv12"
rcstring
one of: "cbr", "vbr"
gop_framesinteger

Keyframe interval in frames (Flussonic gop=N); gop is then "0".

min: 0 · max: 1000
bframesinteger
min: 0 · max: 4
open_gopboolean
tunestring
one of: "hq", "ll", "ull"
multipassstring
one of: "disabled", "qres", "fullres"
spatial_aqboolean
temporal_aqboolean
lookaheadinteger
min: 0 · max: 32
audio*array of object
tracks*string
codec*string
one of: "aac", "ac3", "mp2", "copy"
bitrate*ConfiguredBitrate
channels*integer
min: 0
sample_rate*integer
min: 0
subtitles*object
copy*boolean
copy_teletext*boolean
copy_dvbsub*boolean
copy_scte35*boolean
copy_data*boolean
extra_argsarray of string

Raw FFmpeg output options (omitted when empty). Read only unless api.allow_extra_args is set in the config file.

used_by*array of string

Read only.

ProfilePatch object

JSON Merge Patch (RFC 7386) of Profile.

FieldTypeDescription
nameName
hardwarestring | null
deinterlacestring | null
deinterlace_ratestring | null
deinterlacerstring | null
decodestring | null
cpu_decode_codecsarray of string | null
cropstring | null
scalerstring | null
separate_audioboolean | null
videoarray of object | null
audioarray of object | null
subtitlesobject | null
extra_argsarray of string | null

null removes them; changing them needs api.allow_extra_args.

used_byarray of any | null
ProfileRequest object
FieldTypeDescription
nameName
hardwarestring
deinterlacestring
deinterlace_ratestring
deinterlacerstring
decodestring
cpu_decode_codecsarray of string
cropstring
scalerstring
separate_audioboolean
videoarray of object
namestring
codecstring
widthinteger
heightinteger
bitrateConfiguredBitrate
max_rateConfiguredBitrate
buf_sizeConfiguredBitrate
gopDuration
presetstring
profilestring
levelstring
fpsnumber
resizestring
backgroundstring
sarstring
pix_fmtstring
rcstring
gop_framesinteger
bframesinteger
open_gopboolean
tunestring
multipassstring
spatial_aqboolean
temporal_aqboolean
lookaheadinteger
audioarray of object
tracksstring
codecstring
bitrateConfiguredBitrate
channelsinteger
sample_rateinteger
subtitlesobject
copyboolean
copy_teletextboolean
copy_dvbsubboolean
copy_scte35boolean
copy_databoolean
extra_argsarray of string | null

Omitted or null = keep the stored ones (PUT). Setting or changing them needs api.allow_extra_args (else 403 extra_args_disabled); sending the stored value unchanged is always accepted.

used_byarray of string

Ignored.

Readiness object
FieldTypeDescription
ready*boolean
checks*array of object
name*string
one of: "config", "http_listener", "srt_listener", "channels", "cluster", "shutdown"
ok*boolean
detailstring
reasons*array of string
RemuxStatus object
FieldTypeDescription
copy_teletext*boolean
copy_dvbsub*boolean
copy_scte35*boolean
copy_data*boolean
locked*boolean
offset*integer
offset_ms*integer
packets_remuxed*integer
late_drops*integer
overflow_drops*integer
resyncs*integer
renditions*array of object | null
name*string
locked*boolean
offset*integer
offset_ms*integer
max_residual_ms*number
resyncs*integer
packets_remuxed*integer
pes_remuxed*integer
sections_remuxed*integer
late_drops*integer
overflow_drops*integer
broken_drops*integer
bad_pts*integer
no_pts*integer
queued*integer
pmt_version*integer
pids*array of object | null
source_pid*integer
pid*integer
type*string
one of: "teletext", "subtitle", "data"
codec*string
languagestring
SegmentedRequest boolean | null | object
ServerInfo object
FieldTypeDescription
version*string
commit*string
build_date*string
node*string
started_at*Time
uptime_s*number
min: 0
go_version*string
licenseobject

License summary for every role (UI banner); details in GET /license (admin).

mode*LicenseMode
status*LicenseStatusValue
serving*boolean
reasonstring
warnings*array of LicenseWarning
ffmpeg*object
available*boolean
version*string
cpu*object
cores*integer
usage_pct*number
load1*number
memory*object
rss_bytes*integer
system_total_bytes*integer
system_used_pct*number
totals*object
channels*integer
channels_by_health*object
ok*integer
degraded*integer
failed*integer
sleeping*integer
inputs*integer
sessions*integer
bitrate_in*integer
bitrate_out*integer
Session object
FieldTypeDescription
id*string
protocol*string
one of: "srt", "http-ts", "hls", "dash"
channel*string
mode*string
one of: "read", "publish"
renditionstring

SRT / HTTP-TS readers of one rendition: "source" or a rendition name (omitted for the default read bus).

remote_addr*string
user*string
previewboolean
portinteger

Dedicated SRT port the session arrived on (omitted for the shared listener).

nodestring

Kick responses only: the cluster node the session was kicked on (omitted for this node).

start*Time
duration_s*number
min: 0
bytes*integer
min: 0
bitrate*integer
min: 0
rtt_msnumber
packets_lostinteger
packets_retransinteger
packets_droppedinteger
SourceStatus object
FieldTypeDescription
tracks*array of Track
pcr_pid*integer
service_name*string
provider*string
SRTPort object

Dedicated per-channel SRT listener (outputs.srt_play, inputs[].srt_publish). Callers connect without streamid; the port identifies the channel. Unique across the configuration.

FieldTypeDescription
port*integer
min: 1 · max: 65535
passphrase*string

"" (unencrypted) or 10..79 characters; "***" when redacted.

pbkeylen*integer

0 = 16.

one of: 0, 16, 24, 32
latency*Duration
max_clients*integer

srt_play only; 0 = unlimited.

min: 0
auth*boolean | null

null = like the channel's auth.read / auth.publish.

renditionstring

srt_play only (omitted when ""): what viewers get — "" = the read bus (first rendition when transcoding), "source" = the untranscoded source, or a rendition of the channel's transcode profile. A caller's streamid may name another rendition ("720p", "read:720p", "<channel>/720p").

SRTPortRequest object
FieldTypeDescription
port*integer
passphrasestring
pbkeyleninteger
latencyDuration
max_clientsinteger
authboolean | null
renditionstring

srt_play only: "", "source" or a rendition name.

SRTPortStatus object

State of a dedicated SRT port on this node.

FieldTypeDescription
port*integer
min: 1 · max: 65535
url*string

srt://host:port (no streamid, no passphrase).

encrypted*boolean
bound*boolean

Listening on this node (false on cluster nodes not serving the channel, or while the bind fails).

clients*integer
min: 0
error*string

Last bind error.

viewers*integer
min: 0
bitrate_out*integer
min: 0
renditionstring

srt_play: the configured rendition (omitted for the default read bus).

StandaloneStatus object
FieldTypeDescription
enabled*false
mode*"standalone"
leader*string
nodes*array of object
id*string
address*string
role*"standalone"
state*"up"
channels*array of string
last_seen*Time
version*string
StreamOutput object
FieldTypeDescription
enabled*boolean
viewers*integer
min: 0
bitrate_out*integer
min: 0
url*string

"" when disabled.

ts_urlstring

HLS with ts_segments.

rendition_urlsmap of string

SRT and HTTP-TS of a transcoded channel: URL per rendition name, plus "source" (the untranscoded source). Omitted when the output is disabled or the channel is not transcoded.

packagerPackagerStatus
SwitchEvent object
FieldTypeDescription
at*Time
from*integer | null
to*integer | null
reason*SwitchReason
detailstring
SwitchReason string
TemplatedChannel PartialChannel & object

Stored form of a channel with a template (docs/API.md 4.14): name, template, enabled and inputs, plus only the fields the channel sets itself; overrides lists their paths, effective is the complete channel (read only).

FieldTypeDescription
name*Name
template*Name
enabled*boolean
inputs*array of object
overrides*array of string

Paths of the fields the channel sets itself, e.g. "outputs.hls.window", "labels.tier".

effective*ChannelConfig
Time string (date-time) | null

RFC 3339 UTC with milliseconds; null = never.

TR101290Status object

ETSI TR 101 290 errors of an input since it started (docs/API.md 14.1). Intervals are measured in stream time (PCR); pcr_accuracy_error is not measurable over IP (measured: false).

FieldTypeDescription
p1*integer

Priority 1 errors (sync, PAT, CC, PMT, PID).

min: 0
p2*integer

Priority 2 errors (transport, CRC, PCR, PTS, CAT).

min: 0
p3*integer

Priority 3 errors (NIT/SDT repetition, unreferenced PID).

min: 0
indicators*array of object
name*string
one of: "ts_sync_loss", "sync_byte_error", "pat_error", "continuity_count_error", "pmt_error", "pid_error", "transport_error", "crc_error", "pcr_repetition_error", "pcr_discontinuity_indicator_error", "pcr_accuracy_error", "pts_error", "cat_error", "nit_actual_error", "sdt_actual_error", "unreferenced_pid"
priority*integer
one of: 1, 2, 3
count*integer
min: 0
lastTime
measured*boolean
Track object
FieldTypeDescription
pid*integer
input_pid*integer
stream_type*integer
type*string
one of: "video", "audio", "subtitle", "teletext", "data"
codec*string
profilestring
widthinteger
heightinteger
fpsnumber
interlacedboolean
bitrate*integer
min: 0
languagestring
channelsinteger
sample_rateinteger
hearing_impairedboolean
teletext_pagesarray of object
page*integer
language*string
kind*string
one of: "initial", "subtitle", "hearing_impaired", "info", "schedule"
TrackKind string
TrackMap object

Resolved track mapping (status.track_map, tracks preview).

FieldTypeDescription
configured*boolean

false: no tracks section, every source track passes (selector all).

keep_empty_slots*boolean
input*integer | null

Input resolved against (null = no source program known).

sources*array of TrackSource
slots*array of TrackSlot
warnings*array of string

Unmatched required slots.

TrackMatch object

All given fields must match; {} matches any stream of the kind. pid = fixed binding, anything else = lookup rule.

FieldTypeDescription
pidinteger
min: 16 · max: 8190
langstring

ISO 639 (deu = ger = de).

codecstring
indexinteger

n-th stream of the kind in source PMT order.

min: 1 · max: 64
pageinteger

Teletext page.

min: 100 · max: 899
hearing_impairedboolean
stream_typeinteger
min: 1 · max: 255
name_regexstring
max length: 256
TracksConfig object

Output track selection per kind (docs/API.md 4.1 "tracks"): null = all (default), "all", "none", "first" or an ordered array of selectors (array order = output order; each selector chain is one slot with a fixed output PID).

FieldTypeDescription
video*TrackSet
audio*TrackSet
subtitles*TrackSet
teletext*TrackSet
scte35*TrackSet
data*TrackSet
keep_empty_slots*boolean
TrackSelector object
FieldTypeDescription
match*TrackMatch
fallback*string

next: if nothing matches, the next selector is tried for the same slot.

one of: "skip", "next"
required*boolean

Unmatched: status warning and track_missing alarm.

all_matches*boolean

Take every match (up to 8 PIDs) instead of the first.

also*boolean

The slot may take a source track another slot takes too (e.g. the same audio once copied, once transcoded); it does not claim the track either. Applies to the whole slot (any selector of a fallback chain). Shorthand term also.

out*object
lang*string

Language override (3-letter ISO 639-2); "" = keep.

label*string

HLS/DASH audio rendition name; "" = from the language.

text*string

Shorthand string form (read-only), e.g. lang:deu,required.

TrackSet null | string | array of TrackSelector
TrackSetRequest null | string | array of string | object
TrackSlot object
FieldTypeDescription
kind*TrackKind
slot*integer
min: 0
selector*string

Shorthand, "all" or "first".

fixed*boolean

Fixed PID binding (else lookup rule).

required*boolean
also*boolean

Selector also: the source may be shared with other slots (then several slots show the same matched_source_pid).

state*string
one of: "matched", "missing", "empty"
matched_source_pid*integer | null
source*null | TrackSource
output_pid*integer
langstring
labelstring
TrackSource object
FieldTypeDescription
pid*integer

Source (input) PID.

kind*TrackKind
index*integer
min: 1
stream_type*integer
codec*string
langstring
langsarray of string
pagesarray of integer
hearing_impairedboolean
description*string

What name_regex matches: kind, codec, languages, pages, registration, service.

TracksRequest object
FieldTypeDescription
videoTrackSetRequest
audioTrackSetRequest
subtitlesTrackSetRequest
teletextTrackSetRequest
scte35TrackSetRequest
dataTrackSetRequest
keep_empty_slotsboolean
TranscoderStatus object
FieldTypeDescription
profile*string
state*string

sleeping = on-demand transcoder without consumers (no FFmpeg, no GPU lease).

one of: "starting", "running", "backoff", "stopped", "sleeping"
hardware*string
fps*number
speed*number
uptime_s*number
min: 0
restarts*integer
min: 0
stall_restarts*integer
min: 0
last_exit*string
last_errors*array of string
errorstring
gpustring

GPU admission (WP 6.3); omitted without admission control.

admissionAdmissionState
admission_detailstring
renditions*array of object
name*string
bitrate_out*integer
min: 0
remuxRemuxStatus
gpu_deviceinteger

GPU index (nvidia-smi order) FFmpeg uses; omitted = none / default GPU.

min: 0
decodestring

Where the source video is decoded.

one of: "gpu", "cpu"
decode_reasonstring

Why a GPU plan decodes on the CPU (decode: cpu, cpu_decode_codecs, fallback, source not NVDEC-decodable on this GPU generation / FFmpeg build), or, with decode gpu, that Blackwell NVDEC 4:2:2 frames go through system memory.

shared_audioboolean

Audio encoded once and shared by all renditions.

fallbacksarray of string

Hardware fallbacks applied after FFmpeg errors (sticky until the transcoder restarts).

error_classstring

Class of the last GPU-related FFmpeg error.

one of: "nvdec_unsupported", "nvdec_surfaces", "nvenc_unsupported_feature", "nvenc_session_limit", "gpu_out_of_memory", "gpu_unavailable"
sourceobject

Source video sniffed from the input (PMT, SPS / sequence header, pictures); followed while the transcoder runs when its plan depends on it.

video_codec*string
width*integer
height*integer
chroma_format*integer

1 = 4:2:0, 2 = 4:2:2, 3 = 4:4:4, 0 unknown

bit_depth*integer
interlaced*boolean

The source carries (or may carry) interlaced pictures.

progressive*boolean

The source is known to be progressive (interlaced and progressive both false: unknown).

sarstring

Sample aspect ratio as the decoder reports it (unspecified = 1:1); omitted when unknown.

frame_rate*number
audio_tracks*integer
loadobject

Estimated cost of the current plan (transcode.EstimateLoadFor).

gpu*boolean
decode_on_gpu*boolean
encode_sessions*integer
decode_mpix_s*number
encode_mpix_s*number

Preset-weighted (p4 = 1).

gpu_memory_mb*integer
host_copies_per_s*number
cpu_cores*number
units*number
filtersarray of string

Source-dependent filter decisions of the current plan (docs/TRANSCODING.md §2.5): deinterlacer skipped for a progressive source or run on interlaced frames only, fps moved first, fit/crop/background skipped when the source has the rendition's aspect ratio. A source change that alters them restarts FFmpeg with a new plan.