API reference

h3xed exposes a large HTTP API that the official apps run on. Most of it is internal and may change between releases — this page documents a selected, stable subset to give you a feel for the shape. It isn't exhaustive.

There are two surfaces:

All endpoints return JSON. Protected server endpoints require a JWT via the Authorization: Bearer <token> header or a ?token=<token> query parameter.

Authentication

MethodEndpointAuthDescription
POST/api/auth/setupNoSet initial admin password (first-boot only)
POST/api/auth/loginNoAuthenticate → returns JWT
GET/api/auth/meYesCurrent user info
POST/api/auth/change-passwordYesChange own password

POST /api/auth/login

Body:

{ "username": "alice", "password": "secret" }

Response:

{ "token": "eyJhbG...", "user": { "id": 1, "username": "alice", "isAdmin": true } }

Cloud Authentication

MethodEndpointAuthDescription
POST/api/auth/cloud-loginNoAuthenticate via h3xed.app cloud token
POST/api/auth/setup-from-cloudNoLink server to h3xed.app during initial setup

Server

MethodEndpointAuthDescription
GET/api/serverNoServer name, version, platform
GET/api/statusYesDetailed server status (library/user/session counts)

Libraries

MethodEndpointAuthDescription
GET/api/librariesYesList accessible libraries with item counts
GET/api/libraries/:id/itemsYesBrowse items in a library (paginated)
GET/api/libraries/:id/recentYesRecently added items in a library
POST/api/librariesAdminCreate a new library
PUT/api/libraries/:uuidAdminUpdate a library
DELETE/api/libraries/:uuidAdminDelete a library
POST/api/libraries/:uuid/scanAdminTrigger a library scan
POST/api/libraries/:uuid/refreshAdminRefresh all metadata in a library
GET/api/libraries/:id/recommendedYesRecommended items for a library
GET/api/scan-statusAdminCheck scan progress

GET /api/libraries/:id/items

Query params: offset (default 0), limit (default 50)

Response:

{
  "library": { "id": "uuid", "name": "Movies", "type": "movie" },
  "items": [
    {
      "id": "rating-key",
      "type": "movie",
      "title": "Movie Title",
      "year": 2024,
      "summary": "...",
      "thumb": "/api/artwork/rating-key/thumb",
      "addedAt": 1700000000
    }
  ],
  "totalCount": 150,
  "offset": 0,
  "limit": 50
}

Invites

MethodEndpointAuthDescription
POST/api/invitesAdminCreate a new invite
GET/api/invitesAdminList all invites
DELETE/api/invites/:idAdminRevoke an invite
POST/api/invites/:token/acceptNoAccept an invite and create account
GET/api/invite-info/:tokenNoGet server info for an invite (public)

Media

MethodEndpointDescription
GET/api/media/:ratingKeyItem details (movie/show)
GET/api/media/:ratingKey/childrenSeasons (show) or episodes (season)
GET/api/media/:ratingKey/episodesAll episodes of a season
GET/api/cast/:ratingKeyCast and crew
GET/api/artwork/:ratingKey/thumbPoster image
GET/api/artwork/:ratingKey/artBackground art

GET /api/media/:ratingKey (Movie)

{
  "id": "abc123",
  "type": "movie",
  "title": "Movie Title",
  "year": 2024,
  "summary": "...",
  "rating": 8.5,
  "duration": 7200000,
  "thumb": "/api/artwork/abc123/thumb",
  "art": "/api/artwork/abc123/art",
  "files": [
    {
      "id": 42,
      "streamUrl": "/api/stream/42",
      "container": "mkv",
      "videoCodec": "hevc",
      "audioCodec": "aac",
      "videoResolution": "1080",
      "width": 1920,
      "height": 1080
    }
  ]
}

Playback & Streaming

MethodEndpointDescription
GET/api/stream/:fileIdDirect play file (supports range requests)
GET/api/media/:fileId/playback-infoCan this file direct play? Or needs transcode?
POST/api/transcode/:fileIdStart HLS transcode session
GET/api/transcode/:sessionId/stream.m3u8HLS playlist
GET/api/transcode/:sessionId/:segmentHLS segment
DELETE/api/transcode/:sessionIdStop transcode
GET/api/media/:fileId/infoFull probe info (codecs, audio tracks, subtitles)
GET/api/media/:fileId/subtitle/:indexExternal subtitle file (auto-converts SRT to VTT)

Watch Progress

MethodEndpointDescription
POST/api/progressReport playback position
POST/api/progress/watchedMark as watched
DELETE/api/progress/:ratingKeyMark as unwatched
GET/api/continue-watchingItems with partial progress
GET/api/watch-state?keys=a,b,cBatch watch state lookup

POST /api/progress

{ "ratingKey": "file-rating-key", "offset": 120000 }

Watchlist

MethodEndpointDescription
GET/api/watchlistGet the current user's watchlist
POST/api/watchlist/:ratingKeyAdd an item to the watchlist
DELETE/api/watchlist/:ratingKeyRemove an item from the watchlist

Mark Watched / Unwatched

MethodEndpointDescription
POST/api/mark-watched/:ratingKeyMark an item as watched
POST/api/mark-unwatched/:ratingKeyMark an item as unwatched

Discovery

MethodEndpointDescription
GET/api/search?q=querySearch media by title
GET/api/discover/recentRecently added across all libraries

Users (Admin)

MethodEndpointDescription
GET/api/usersList all users
POST/api/usersCreate a user
PUT/api/users/:idUpdate a user
DELETE/api/users/:idDelete a user
GET/api/users/:id/share-linkGenerate JWT share link
GET/api/users/:id/restrictionsGet content restrictions for an account/profile
PUT/api/users/:id/restrictionsSet content restrictions (rating ceilings, allowed/excluded ratings & labels, allow-unrated)

PUT /api/users/:id/restrictions

Used for managed (kids) profiles. ratingCeilings takes ladder positions like PG-13 or TV-14 and is expanded server-side; allowUnrated governs items with no rating (fails closed when omitted).

{
  "ratingCeilings": ["PG-13"],
  "excludedLabels": ["adult"],
  "allowedLabels": [],
  "allowUnrated": false
}

Profiles

MethodEndpointDescription
GET/api/profilesList profiles on the current account
POST/api/profilesCreate a profile (name, optional avatar, isManaged, pin)
PATCH/api/profiles/:idRename, change avatar, toggle managed, set/clear PIN
DELETE/api/profiles/:idDelete a profile and its watch state
POST/api/profiles/:id/switchSwitch the active profile (PIN required if set)

Co-op

MethodEndpointDescription
GET/api/coop/peersList linked co-op servers
POST/api/coop/syncSync shared libraries from a peer
POST/api/coop/reconcileReconcile the merged catalog (de-dup)

Cloud: device pairing

Apple TV and other devices pair through the cloud. The device requests a short user code, the user approves it from a signed-in device, and the device polls for its token. Served under /cloud on h3xed.app.

MethodEndpointDescription
POST/api/device/codeStart pairing → returns a user code (shown on the device) and a device code to poll with
POST/api/device/approveA signed-in user approves a pairing code
POST/api/device/tokenDevice polls; returns an account token once approved (single use)

Cloud: friends

MethodEndpointDescription
GET/api/friendsList friends
GET/api/friends/requestsPending friend requests
POST/api/friends/requests/:id/acceptAccept a request
POST/api/friends/requests/:id/declineDecline a request
GET/api/friends/blocksList blocked accounts
GET/api/social/presencePresence for your friends

Cloud: watch party

MethodEndpointDescription
POST/api/party/roomsCreate a watch-party room
GET/api/party/code/:codeLook up a room by its 6-character code
GET/api/party/rooms/:idRoom state
POST/api/party/rooms/:id/invitesInvite a friend to the room
POST/api/party/rooms/:id/endEnd the room

Admin

MethodEndpointDescription
GET/api/hardwareDetected transcoding hardware
PUT/api/hardwareUpdate transcoder settings
GET/api/browse-fs?path=/Browse server filesystem
GET/api/genresList all genres
GET/api/logsRecent request logs

Metadata management

MethodEndpointDescription
POST/api/match/:ratingKey/searchSearch TMDB for a metadata match
POST/api/match/:ratingKey/applyApply a TMDB match
POST/api/match/:ratingKey/refreshRefresh metadata from TMDB
GET/api/media-item/:ratingKeyGet editable metadata
PUT/api/media-item/:ratingKeyManually edit metadata