Streams
Home · Health · Prometheus · OpenAPI · Status
| Method | Path | Description |
|---|---|---|
| GET | /play/<tmdb_id> | Movie session → redirect to stream |
| GET | /play/<tmdb_id>/<s>/<e> | TV episode session |
| POST | /play/batch | Batch resolve (JSON body) |
| GET | /watch/... | Built-in HLS player (branded) |
| GET | /s/<sid> | Session entry (IP-locked, optional sig) |
| GET | /proxy?sid=&url= | Playlist/segment proxy (+ Range, ETag) |
Move a session to another device without a new /play:
POST /transfer/create?sid=SESSION_ID
→ { "code": "A1B2C3D4", "expires_in": 300 }
GET /transfer/claim/A1B2C3D4
→ redirects to /s/<sid> on the new device IP
Send Idempotency-Key: <opaque> or ?reuse=1 on /play
to prefer an existing recent session for the same IP + title.
Session creation is limited per IP. Responses include:
X-RateLimit-LimitX-RateLimit-RemainingRetry-After (on 429){
"error": "rate_limited",
"title": "Too many requests",
"message": "...",
"status": 429,
"hint": "...",
"request_id": "..."
}
Send Accept: application/json for JSON error bodies.
Every response includes X-Request-Id.
| Path | Description |
|---|---|
/health/live | Liveness (always 200 if process up) |
/health/ready | Readiness (503 in maintenance) |
/health | Alias of ready |
/metrics | Prometheus text metrics |
/openapi.json | OpenAPI 3 document |
/status | Admin dashboard (STATUS_SECRET) |
/docs | This page |
| HTTP | code | Meaning |
|---|---|---|
| 400 | bad_request / transfer_invalid | Invalid input or transfer code |
| 401 | unauthorized | Missing admin secret |
| 403 | forbidden / title_blocked | IP lock / blocklist / bad signature |
| 404 | not_found | Unknown route |
| 410 | session_expired / token_expired | Session or token gone |
| 429 | rate_limited / max_sessions / bandwidth_limit | Limits hit |
| 500 | extraction_failed / stream_unavailable | Source extract failed |
| 502 | upstream_error | Upstream HTTP/network error |
| 503 | maintenance / circuit_open | Maintenance or circuit breaker |