AviatoAviato
Developer

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:

WhereWhat it serves
/docs/developer/apiPublished reference for the current Aviato release. Browse without a server.
/api/docs on your serverInteractive reference (Scalar UI) loaded against the live spec
/api/docs/openapi.json on your serverThe 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:

  1. Open Settings as an admin user.
  2. Go to the Security pane.
  3. Scroll to the API Keys section and click Create key, then give it a name (and an optional description and expiry).
  4. 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_3c8e4fa1c4d1b09d0f6f7e1a2b3c4d5e6f7a8b9cabcdef0123456789abcdef

The 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/libraries

Streaming 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/scan

The 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 rangeMeaning
2xxSuccess. The body matches the response schema declared in OpenAPI.
400Validation failure. The request did not match the declared input schema.
401Missing or invalid token (or token expired).
403Authenticated but not authorised for this resource.
404Resource does not exist (or the caller cannot see it).
5xxServer 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, or openapi-typescript consume the spec URL directly.
  • Swift: swift-openapi-generator (used by the official Aviato Apple app).
  • Python: openapi-python-client produces a typed httpx based client.
  • Go: oapi-codegen produces 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/docs on 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).

On this page