Skip to content

REST API

Rust-Srec exposes a JSON REST API under /api. The running backend generates the authoritative OpenAPI document for its exact build.

  • Docker default: Swagger UI and OpenAPI JSON
  • Source checkout using rust-srec/.env.example: change port 12555 in those links to 8080

The Swagger link belongs to the running Rust-Srec backend, not to docs.srec.rs.

Authentication

Most routes require an access token in the Authorization: Bearer <token> header. Login returns a short-lived access token and a longer-lived, rotating refresh token.

First Login

The initial account is admin / admin123! and must change its password before it can use other protected endpoints.

bash
curl -X POST http://localhost:12555/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123!","device_info":"API quickstart"}'

The response contains these fields:

json
{
  "access_token": "...",
  "refresh_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_expires_in": 604800,
  "roles": ["admin"],
  "must_change_password": true
}

Use the returned access token to replace the default password:

bash
curl -X POST http://localhost:12555/api/auth/change-password \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{"current_password":"admin123!","new_password":"<unique-new-password>"}'

Sign in again with the new password and use the new access token. While must_change_password is true, other protected routes return 403 PASSWORD_CHANGE_REQUIRED.

Call a Protected Endpoint

bash
curl http://localhost:12555/api/streamers \
  -H "Authorization: Bearer <access-token>"

Refresh and Revoke

POST /api/auth/refresh accepts {"refresh_token":"..."} and rotates the token pair. Store the newly returned refresh token and discard the old one. POST /api/auth/logout accepts the same body and revokes that session; authenticated POST /api/auth/logout-all revokes all sessions for the user.

Treat access tokens, refresh tokens, cookies, and platform credentials as secrets. Do not place tokens in logs or source control.

Route Groups

PrefixPurposeAuthentication
/api/healthLiveness, readiness, and dependency statusMixed; only /live is public when auth is enabled
/api/authLogin, refresh, logout, password change, sessionsMixed; see Swagger
/api/streamersStreamer CRUD, checks, filters, and batch actionsBearer token
/api/configGlobal/platform configuration and backup import/exportBearer token
/api/templatesReusable configuration templatesBearer token
/api/enginesDownload engine instancesBearer token
/api/sessionsRecording sessionsBearer token
/api/pipelineWorkflows, jobs, presets, executions, and outputsBearer token
/api/notificationsChannels, subscriptions, preferences, and eventsBearer token
/api/credentialsPlatform credential state and refresh operationsBearer token
/api/parseURL and metadata parsingBearer token
/api/downloads, /api/logging, /api/media, /api/stream-proxyRealtime or media accessRoute-specific; inspect Swagger

Use the generated OpenAPI document for request and response schemas instead of guessing fields from this summary.

Errors

API errors use one stable envelope:

json
{
  "code": "VALIDATION_ERROR",
  "message": "A human-readable explanation",
  "details": {}
}

details is omitted when unavailable. Common statuses are 400 invalid input, 401 missing/expired credentials, 403 disabled account or required password change, 404 missing resource, 409 conflict, 422 validation failure, 429 too many failed login attempts, 500 internal failure, and 503 unavailable dependency.

POST /api/auth/login is rate limited per account and per source address. After five failed attempts for one account it answers 429 with code TOO_MANY_REQUESTS and a Retry-After header holding the number of seconds to wait; a successful login clears that account's count. A second, much looser budget (100 failures per window) caps password-hashing work per source address.

The source address is the peer of the TCP connection. X-Forwarded-For and X-Real-IP are not trusted, so behind the bundled frontend container, nginx, or any other reverse proxy, every login is attributed to the proxy's address — the per-address budget is a work cap, not a per-client lockout. Usernames longer than 128 characters — counted as characters, not bytes, so non-Latin names are not penalised — are rejected with 400 before either budget is consulted. A configuration import applies the same limit, so it cannot create an account that could never sign in. Both budgets are configurable; see Configuration.

Clients should branch on HTTP status and code, not parse the human-readable message.

Compatibility and Deployment

The v0.5 API paths are not prefixed with a version. Pin the backend image or binary version, keep the matching OpenAPI JSON with generated clients, and test before upgrading. Breaking behavior is described in the Release Notes.

For network deployments, terminate TLS at a reverse proxy, restrict the API to intended clients, and do not expose Swagger publicly unless it is needed. See Security and Production Deployment.

Released under the MIT License.