Skip to content

API client — getting started ​

@reelvault/sdk/client exports a typed, framework-agnostic HTTP client built on fetch. One instance wraps the whole API: 25 resource clients share a single transport with global GET deduplication, optional caching, automatic retries and token refresh.

bash
bun add @reelvault/sdk   # or bun link, see the SDK overview

Create a client ​

ts
import { ReelVaultClient } from "@reelvault/sdk/client";

const api = new ReelVaultClient({
  baseUrl: "http://localhost:3030",  // required — a trailing slash is trimmed
  accessToken: "<access-token>",     // optional — sent as Authorization: Bearer …
});

baseUrl also accepts a function (baseUrl: () => string), evaluated per request. That is useful when the address is only known at runtime — for example when it is entered on a login screen.

Call the API ​

Every resource client exposes thin, fully typed methods:

ts
// Log in and reuse the session
const { user, session } = await api.auth.login({
  email: "me@example.com",
  password: "…",
});

// Browse the library
const movies = await api.metadata.getAll({ fields: ["posterImages"] });
const detail = await api.metadata.getDetailsView(metadataId);

// Control playback of an existing session
await api.playbackSessions.sendCommand(sessionId, { type: "pause" });

// Admin scope
const { workers } = await api.admin.getWorkers();

Responses are inferred from the shared contracts, so there is nothing to decode by hand. Error handling is covered in Caching, retries & errors.

ClientConfig ​

OptionTypeDefaultDescription
baseUrlstring | (() => string)— (required)API origin; trailing slash trimmed
fetcherFetcherglobal fetchCustom fetch implementation (test seams, proxies)
headersHeadersInput—Default headers merged into every request
accessTokenstring—Sent as Authorization: Bearer …
onTokenExpired() => string | Promise<string>—Called after a 401 to obtain a replacement token
requestInterceptorsRequestInterceptor[][]Run before each request; may rewrite URL/options
responseInterceptorsResponseInterceptor[][]Run after each response
enableRetrybooleantrueRetry transient failures
maxRetriesnumber3Retry limit per request
timeoutnumber30000Per-request timeout, in ms
credentialsRequestCredentials"same-origin"Use "include" for cross-origin cookie sessions
enableCachebooleanfalseTTL cache for successful GETs
cacheTtlMsnumber5000Cache time-to-live, in ms
maxTokenRefreshAttemptsnumber1401-triggered refreshes per request

Instance API ​

Beyond the resource clients (see Resources & realtime), a ReelVaultClient exposes:

MemberDescription
setAccessToken(token) / getAccessToken()Swap or read the bearer token at runtime
clearCache()Drop the shared GET cache and in-flight dedup state

Resource clients ​

Grouped as on the instance:

GroupProperties
Administrationadmin
User & profileauth, setup, profiles, notifications, me
Library & fileslibraries, media
Metadatametadata, collections, companies, genres, keywords, people, images
Video contentseasons, episodes
Browse & playbackdiscover, playbackSessions, downloads, subtitles, providers, plugins, events
Utilitieshealth

Every method is listed with its signature in Client resources.

How it is built ​

  • Thin transport. The client builds URLs, serializes bodies and validates paths; payload validation is the server's job (shared TypeBox schemas). If you catch yourself pre-validating payloads on the client, you are duplicating the server.
  • One shared HttpClient. All resource clients delegate to it, so caching, dedup, retry and token-refresh behave identically across the whole API.
  • No WebSocket management. The client builds the realtime URL (api.events.getWebSocketUrl()) and sends playback commands over HTTP; owning the socket is up to you — see Resources & realtime.

Released under the GNU GPL v3.