Skip to main content

HTTP API

Routes are implemented in internal/httpserver. Media and playback-information routes require a valid token in the URL path. The admin routes use a separate derived bearer key. There is no playback-info issuance endpoint in this service.

Successful private media responses use Cache-Control: private, no-store; information and error responses use no-store. Error bodies are JSON of the form {"error":"code","message":"description"}. Unsupported routes return the standard HTTP 404 response. If ALLOWED_ORIGINS is non-empty, a request with an Origin header must match one of its entries exactly. Preflight OPTIONS requests receive 204 and advertise GET, HEAD, OPTIONS and Range, If-Range, If-Modified-Since headers.

Route reference​

Method and pathAuthQuerySuccess response
GET, HEAD /healthzNoneNone200; GET returns {"status":"ok","activeTranscodes":N} JSON; HEAD has no body. Liveness only, not readiness.
GET, HEAD /stream/{token}Stream tokenheight, startOriginal media with range support for DirectPlay, or an FFmpeg output stream for DirectStream/Transcode.
GET /info/{token}Stream tokenheight, startJSON with playMethod, source, availableHeights, and sometimes keyframeStart. Requires FFmpeg/FFprobe.
GET, HEAD /hls/{token}/index.m3u8Stream tokenheightStatic VOD HLS playlist; each segment is encoded on demand. Requires FFmpeg/FFprobe and known duration.
GET, HEAD /hls/{token}/{index}.tsStream tokenheightOne MPEG-TS segment generated on demand. Zero-based integer segment index.
GET /lyrics/{token}Stream token naming an audio fileNoneNeighboring .lrc content as text/plain; charset=utf-8.
GET /subtitles/{token}Stream token naming a video fileNoneJSON list of matching sidecar subtitle tracks.
GET /subtitles/{token}?file={filename}Stream token naming a video filefileMatching .srt or .vtt sidecar converted/passed through as WebVTT.
GET /admin/sessionsAuthorization: Bearer {admin-key}NoneJSON snapshot of FFmpeg availability, configured limit, active process count, and tracked sessions.
DELETE /admin/sessions/{id}Authorization: Bearer {admin-key}NoneCancels the active session and returns 204; missing/expired session returns 404.

Tokens are compact JWTs, so clients should URL-encode them when constructing request URLs. Tokens containing a slash in the path are rejected. The admin key is the lowercase hexadecimal HMAC-SHA256 derived from the shared secret; see Authentication.

Stream options​

height accepts only 240, 360, 480, 720, or 1080. It is a maximum output height; the service never scales a source upward. start is a non-negative number of seconds, capped at seven days. These are optional on /stream and /info; height is also accepted on both HLS paths. /lyrics and /subtitles do not accept playback options. The handler parses the supported parameters; unknown query parameters are not used as options.

DirectPlay responses are served by Go's http.ServeContent: they advertise Accept-Ranges: bytes and can return 206 Partial Content for a valid Range request. Processed output is streamed live with status 200, no content length or byte-range seeking, a Content-Type of video/mp4 or video/webm, and an X-Flixer-Playback-Mode header. Use a new request with start to seek in progressive processed playback.

Example response from /info/{token} (shape; actual values come from FFprobe):

{
"playMethod": "DirectStream",
"source": {
"videoCodec": "h264",
"audioCodec": "aac",
"width": 1920,
"height": 1080,
"durationSeconds": 10
},
"availableHeights": [240, 360, 480, 720],
"keyframeStart": 59.96
}

keyframeStart is present only for a remux/DirectStream request with a positive start, and only when FFprobe can find an earlier keyframe.

Admin session JSON​

GET /admin/sessions returns fields transcodingAvailable, maxTranscodes, activeTranscodes, and sessions. Each session includes the token's playSessionId as id, user/media identifiers, relative file, delivery type (progressive or hls), source probe details, mode, height, positionSeconds, timestamps, bytesSent, running, and an FFmpeg pid while a process is running. This endpoint exposes operational/session metadata; keep it private to the Flixer backend or a trusted management network.

Common status codes​

StatusExamples
400Unsupported/invalid height or invalid start on stream/info/HLS.
401Missing, malformed, invalid, expired, or undecryptable stream token; missing/incorrect admin bearer key.
403An unlisted browser origin when CORS origins are configured.
404Unavailable/disallowed media, missing lyrics/subtitle file, unknown HLS route/segment, or unknown admin session.
405Method not allowed; response includes Allow.
422HLS requested for media with unknown/non-positive duration.
501Required transcoder unavailable, or seek/height requested when FFmpeg is disabled.
503FFmpeg slot not acquired before the 10-second wait; includes Retry-After (5 for progressive playback, 2 for HLS).
500Media probe/open or processed-stream failure.

When FFmpeg is unavailable, /info and /hls return 501. /stream still serves requests without height or start directly from the file; do not assume that the original file will be browser-compatible. Audio files also stream directly and do not go through FFprobe.