API¶
control.plane.api
Sapsan exposes server state over HTTP. The API is format-compatible with the Flussonic Streamer API v3, so existing integrations keep working.
Access¶
API access is protected by a login and password in the api_auth section:
api_auth:
login: admin
password: secret
Endpoints¶
The base prefix is /streamer/api/v3:
| Method and path | Returns |
|---|---|
GET /streamer/api/v3/streams |
list of streams and their state |
GET /streamer/api/v3/config |
current server configuration |
GET /streamer/api/v3/dvrs |
list of DVR storages |
GET /streamer/api/v3/dvrs/{name} |
state of a specific DVR |
GET /streamer/api/v3/rproxy |
Peeklio gateway and agent state |
GET /streamer/api/v3/monitoring/readiness |
readiness probe for orchestrators |
Native API v4¶
The evolving native API lives under the /streamer/api-v4 prefix:
| Path | Returns |
|---|---|
GET /listeners |
listener list |
GET /streams, GET /streams/{name} |
streams and their state |
GET /streams/stats, GET /streams-stats |
stream statistics |
GET /sessions/stats |
session statistics |
GET /live-metrics, GET /sessions-metrics |
live and session metrics |
GET /dvr, GET /dvr/catalog, GET /dvr/metrics |
DVR storage and catalog state |
POST /dvr/rebuild-index, GET (status), DELETE (stop) |
catalog rebuild from disks |
POST /dvr/cleanup, GET /dvr/cleanup |
start archive cleanup / status |
GET /runtime/metrics |
process metrics in Prometheus format |
GET /auth |
authorization state |
GET /license/status |
license state |
GET /rproxy/streampoint-agents |
Peeklio gateway agents |
Note
TODO: response examples, stream management via API (once writes appear).
Next steps¶
Admin API access¶
The Admin API is protected by a separate api_auth section — see Admin API.
Server health¶
- Readiness probe:
GET /streamer/api/v3/monitoring/readiness— for Kubernetes and load balancers. - Stream state:
GET /streamer/api/v3/streams.
Stream stats in the Admin API¶
Stream list¶
GET /streamer/api-v4/streams/stats returns one element per stream — the channels page in the UI lives on this list, and it is also the right thing to poll from scripts.
| Field | What it means | How to use it |
|---|---|---|
status, status_since |
stream state and the moment it entered it | not running for longer than N minutes — alert |
bitrate_kbit |
the measured media bitrate of the active input, by frame timestamps | dropped visibly below nominal — the source degraded. This is not network throughput: a file can be read faster than real time |
source.url |
the input that is actually playing | differs from the first one in the config — the stream lives on a backup |
inputs[] |
runtime status of every configured input: url, status, check age checked_ago_ms, bitrate, error text |
see below |
dvr.from, dvr.to |
the archive window on this server | to lags behind current time — recording stopped; from stopped moving forward — cleanup is not working, disk overflow ahead |
dvr.recorded_hours, dvr.bytes, dvr.periods |
the archive totals: how many hours are recorded, how much disk space the archive takes and how many continuous runs it consists of; updated once a minute, hour precision | recorded_hours notably below the window width to - from — the archive has gaps; bytes — the space the stream takes on the server |
bytes_in, bytes_out |
cumulative byte counters since the stream started | for rates and history use the built-in Prometheus server or Retroview: the snapshot resets on restart |
Statuses of inputs[] elements:
active— playing right now;ok— a backup, alive as of the last check;error— a backup with a recorded problem (text inerror);unchecked— a backup that has never been checked yet.
This answers the main failover question — "will we actually switch when the primary dies". Backups are checked periodically (recheck_secondary_inputs_interval, see backup sources); alert on error, on unchecked, and on a too-old checked_ago_ms — an unchecked backup cannot be considered working.
Single stream¶
GET /streamer/api-v4/streams/stats/{name} adds diagnostic sections to the same fields — they are absent from the list to keep the list cheap.
The input section — counters of the current input:
| Field | Why |
|---|---|
bytes, frames, bitrate_kbit |
whether the input delivers data at all, and how fast |
retries |
reconnects to the source: growing — the source or the network is unstable |
input_switches |
switches between inputs: growing — the input flaps, investigate the primary |
errors |
the aggregate input error counter: growing — there is a problem; the cause is in the extended counters or in Retroview |
num_sec_on_primary_input, num_sec_on_secondary_input |
seconds lived on the primary and on the backup: a notable share on the backup — the primary input is systematically bad |
num_sec_no_data |
seconds with no data at all |
errors_lost_packets, errors_connection_closed, errors_http_request_error, … |
causal error breakdown — only with the "extended counters" option |
The dvr section in the single-stream response is extended with:
| Field | Why |
|---|---|
write.segments_written, write.segments_failed, write.segments_skipped |
fragment write counters: segments_failed growing — the archive is losing data right now, check the disk |
write.segments_written_slow / _delayed / _collapsed, write.segments_discontinuity |
write profiling — only with the "extended counters" option |
Note
The Admin API snapshot resets when the server restarts. It answers "what is happening now", but is suitable neither for bill reconciliation nor for analyzing yesterday's incident — that is what Retroview is for.