Skip to content

API Keys

API keys let you script against the Odeion HTTP API without embedding a username and password or scraping a short-lived JWT. Each key belongs to a single user, carries a fixed set of scopes, and can be revoked at any time without affecting the user’s interactive sessions.

API keys are disabled by default for non-admin users. An administrator must opt a user in before that user can mint keys. Administrators always have API key access and don’t need a toggle.

  1. Open the admin dashboard and click on a user.
  2. In the user modal sidebar, find the Permissions section.
  3. Toggle API Keys on.

The toggle can be flipped off at any time. Disabling it makes every existing key for that user immediately stop working. No further requests will be authenticated until the toggle is turned back on. Existing keys are not deleted by this toggle. To permanently revoke a specific key, use the Revoke button next to it in the same modal.

Once an admin has enabled API key access for your account:

  1. Open Settings → Account.
  2. Scroll to the API Keys section.
  3. Click Generate new key.
  4. Give the key a memorable name (e.g. home-automation-script).
  5. Tick the scopes the key needs. Pick the smallest set that covers your use case.
  6. Click Create.

The plaintext key is shown exactly once, immediately after creation. Copy it somewhere safe (a password manager, a secrets vault) before dismissing the dialog. Odeion only stores a hash of the key, so if you lose it you must revoke and regenerate.

Keys are formatted as odn_ followed by a 52-character base32 string, for example:

odn_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5

API keys do not expire. They live until you (or an administrator) explicitly revoke them.

Send the key in the Authorization header exactly the same way you would a JWT:

Terminal window
curl https://your-odeion.example/api/movies \
-H "Authorization: Bearer odn_a1b2c3d4..."

The server distinguishes API keys from JWTs by the odn_ prefix. JWT-authenticated requests bypass per-route scope enforcement entirely. API-key requests must carry a scope that matches the route they’re calling. Any route not explicitly enabled for API-key access returns 403 Forbidden.

Administrative endpoints (anything under /api/admin/*, plus user management, setup, and licensing routes) are never accessible via API key, even if the underlying user is an admin. If you need to automate administrative actions, use a JWT obtained from POST /api/auth/login.

Scopes are coarse and aligned with the API’s route groups. A key must hold every scope it intends to use; there is no inheritance between scopes.

ScopeGrants access to
profile:readGET /api/users/me
media:readList and fetch movies, series, seasons, and episodes
media:writeUpdate movie and series metadata
progress:readRead continue-watching and per-item watch progress
progress:writeUpdate, stop, clear, or delete watch progress and history
requests:readList media requests and read request status
requests:writeCreate new media requests
downloads:readList and inspect download jobs
downloads:writeCreate, cancel, and confirm download jobs (requires the per-user Download Access permission as well)
playlists:readList playlists, fetch playlist contents, check membership
playlists:writeCreate, rename, delete, and reorder playlists; toggle Watch Later & Favorites
subtitles:readList subtitles for a media item

Scopes are a runtime allow-list. If you need access to an endpoint that doesn’t appear above, that endpoint is not currently exposed to API keys. Open an issue describing your use case.

The same Settings → Account panel lists every key you have created, along with its prefix, scopes, and the timestamp of its last successful use. Click Revoke next to a key to delete it immediately. Revoked keys cannot be restored.

Administrators can also list and revoke any user’s keys from the user modal in the admin dashboard, which is useful when off-boarding a user or responding to a leaked credential.

  • Treat keys like passwords. Never commit them to source control or paste them into chat tools. Use environment variables or a secrets manager.
  • One key per integration. Naming and scoping keys per consumer makes it easy to revoke a single integration without disrupting the others.
  • Use the smallest scope set that works. A key with only media:read can’t accidentally delete a download or wipe a watch history.
  • Rotate keys when staff changes. When a user leaves, an admin should revoke all their keys (or simply turn the per-user toggle off).
  • Watch last_used_at. Keys that haven’t been used in months are good candidates for revocation.