API Overview
Authenticate with an API key, hit the OpenAPI described REST surface, and use the interactive Scalar reference to explore endpoints.
The Aviato server exposes the same REST API the web app uses. It is described by an auto generated OpenAPI 3.1 document, served from the running server. There is no hand written schema to drift; every route is defined with @hono/zod-openapi, so the interactive reference and any generated clients are always in sync with the code.
This page covers what you need before opening the API reference: how to get an API key, how to authenticate, and what to expect from response shapes, errors, and versioning.
Where the spec lives
The OpenAPI document is available in two places:
| Where | What it serves |
|---|---|
| /docs/developer/api | Published reference for the current Aviato release. Browse without a server. |
/api/docs on your server | Interactive reference (Scalar UI) loaded against the live spec |
/api/docs/openapi.json on your server | The raw OpenAPI 3.1 JSON document for client generation |
The published reference is the easiest way to explore the surface before you stand up an Aviato instance. Once you have a server running, the in-product reference is the source of truth for that exact build, since it is generated from the running code.
If you want to generate a typed client, fetch /api/docs/openapi.json from a server you control and feed it to your generator of choice. See Generating a typed client below.
Creating an API key
API keys are managed by an admin from Settings → Security → API Keys:
- Open Settings as an admin user.
- Go to the Security pane.
- Scroll to the API Keys section and click Create key, then give it a name (and an optional description and expiry).
- Copy the token immediately. The plaintext key is shown once. Aviato stores only a SHA-256 hash; if you lose the key you have to make a new one.
Tokens look like:
avt_3c8e4fa1c4d1b09d0f6f7e1a2b3c4d5e6f7a8b9cabcdef0123456789abcdefThe avt_ prefix is how the server tells API key tokens apart from session tokens, so do not strip it.
⚠️ API keys grant admin level access. They authenticate as a synthetic admin user with full permissions on this server. Treat them like a database password. Store them in a secret manager, never in source control, and rotate them when a teammate leaves.
You can revoke a key at any time from the same screen. Revocation is immediate.
Authenticating
Send the token in the Authorization header as a Bearer token. This works on every authenticated route:
curl -H "Authorization: Bearer avt_..." \
https://aviato.example.com/api/librariesStreaming routes (/api/stream/*, /api/events, /api/assets/*) also accept ?token= as a query string, because the browser cannot set headers on <video>, <img>, or EventSource requests. Prefer the header anywhere it is available; query strings end up in proxy logs.
A handful of routes are unauthenticated by design: /api/health, /api/info, /api/auth/*, /api/invites/accept, /api/invites/register, and /api/docs/*. Everything else requires a valid token.
Quick examples
List libraries
curl -sH "Authorization: Bearer $AVIATO_API_KEY" \
https://aviato.example.com/api/libraries// Node / Bun
const res = await fetch('https://aviato.example.com/api/libraries', {
headers: { Authorization: `Bearer ${process.env.AVIATO_API_KEY}` }
})
const { libraries } = await res.json()# Python
import os, httpx
r = httpx.get(
"https://aviato.example.com/api/libraries",
headers={"Authorization": f"Bearer {os.environ['AVIATO_API_KEY']}"},
)
r.raise_for_status()
libraries = r.json()["libraries"]Trigger a library scan
curl -sX POST \
-H "Authorization: Bearer $AVIATO_API_KEY" \
https://aviato.example.com/api/libraries/lib_movies/scanThe exact set of endpoints (paths, parameters, response shapes, and error codes) lives in the API reference. This page deliberately does not duplicate it.
Response shapes
All responses are JSON. The server sets Content-Type: application/json and uses standard HTTP semantics:
| Status range | Meaning |
|---|---|
2xx | Success. The body matches the response schema declared in OpenAPI. |
400 | Validation failure. The request did not match the declared input schema. |
401 | Missing or invalid token (or token expired). |
403 | Authenticated but not authorised for this resource. |
404 | Resource does not exist (or the caller cannot see it). |
5xx | Server side error. Treat as transient; retry with backoff if you must. |
Error responses use a flat shape:
{ "error": "Description of what went wrong" }Some endpoints attach extra fields (e.g. validation issues from Zod) under additional keys. Check the route's response schema in the OpenAPI document if you need to handle them precisely.
Versioning
The API is versioned by surface, not by URL. Routes are added regularly; routes are removed only with deprecation. Breaking changes to existing response shapes are avoided in favour of additive evolution. Consumers should:
- Treat unknown JSON keys as forward compatible. Do not fail on extra fields.
- Read the OpenAPI document as the contract for your version of the server.
- Pin the server version (Docker tag, release) if you need exact byte for byte stability.
There is no /v1 prefix. The OpenAPI document's info.version reflects the running server.
Rate limits and backpressure
The REST API does not impose request rate limits at the moment. Heavy clients should still be polite:
- Use webhooks instead of polling for events. The webhooks doc covers the full event vocabulary.
- Cache responses where appropriate; many endpoints are stable for the lifetime of the underlying entity.
- Send concurrent requests in moderation. The server is single instance and shares a SQLite (or Postgres) connection pool with the UI.
If you need to import or migrate large amounts of data, prefer batch endpoints where they exist, and consider a plugin if you need first class lifecycle and progress reporting.
Generating a typed client
Because the spec is OpenAPI 3.1, any standard generator works against /api/docs/openapi.json. A few popular options:
- TypeScript:
openapi-fetch,orval, oropenapi-typescriptconsume the spec URL directly. - Swift:
swift-openapi-generator(used by the official Aviato Apple app). - Python:
openapi-python-clientproduces a typedhttpxbased client. - Go:
oapi-codegenproduces an idiomatic client and server stubs.
You can either point your generator at a running server's /api/docs/openapi.json or download the file once and check it into your client repo so builds are reproducible. Regenerate when you upgrade Aviato. The OpenAPI document is the contract; generated code is just a convenience layer.
Where to read the reference
You have two equivalent views of the same OpenAPI spec:
- Published reference on this site. Browse the API surface without a running server. This tracks the current Aviato release.
- In-product reference at
/api/docson your own server. Same Scalar UI, but loaded against the live spec for the exact build you are running, with an inline "try it" panel that uses your session.
Use the published reference for general exploration and link sharing. Use the in-product reference when you need to verify what your server actually exposes (e.g. after an upgrade, or when running a pre-release build).