TypeScript SDK
@4players/odin-cortex is the
official TypeScript SDK for ODIN Cortex. It wraps the entire REST API in a
typed, ergonomic client — and adds live objects and Firestore-style real-time
subscriptions on top.
It’s the same SDK the 4Players console uses for Cortex, and the same one your
serverless functions get pre-authenticated as
ctx.cortex.
Installation
The SDK is published as a stable release — the latest tag on npm (currently 1.13.x).
It follows semantic versioning: minor releases add features, patch releases fix bugs.
Earlier versions were published as prereleases (npm install @4players/odin-cortex@beta).
Switch to the stable release with npm install @4players/odin-cortex@latest.
Requires Node.js 18+ (it uses the global fetch for streaming). It also works in
modern browsers — but keep API keys server-side.
Creating a client
Authenticate with an API key for server-to-server use:
For a browser/dashboard session where a user has logged in, pass a JWT instead:
See Authentication for when to use each.
Project scope
Project-scoped resources are reached through client.project(projectId):
Available resource managers on a project scope include sessions, gatherings,
participants, sanctions, plugins, webhooks, functions, settings and rooms.
A few resources hang off the client directly: client.auth, client.apiKeys and
client.pluginCatalog.
Each call needs the matching API-key scope —
for example sessions for project.sessions, messages for reading a transcript and
rooms.push for project.rooms.send().
Live objects
Methods like create() and get() return live objects. Every field from the API
response is available directly on the object (e.g. session.title), and the object
also exposes action methods and knows its own identity — no need to thread ids back through
every call:
A live object is also plain data: JSON.stringify(session) returns exactly the API payload
(no client internals), and a Session is assignable to SessionResponse. The older
session.data.title form still works but is deprecated — prefer session.title.
Paging and polling
Collections that can grow large have paged variants. Sessions page by cursor:
A transcript can be read incrementally with session.listMessages() — pass the last seen
seq as after, and the previous ETag as ifNoneMatch. When nothing new has arrived the
call resolves to null (HTTP 304), which is cheap for both sides:
See Polling instead of streaming for the full loop.
Real-time watch()
Every list() / get() returns a one-shot snapshot. To receive live updates instead,
call watch() — it loads the initial state over REST and keeps it in sync over
Server-Sent Events:
Watch a single object by id, a session’s transcript, or a gathering’s members and invitations:
All watchers for a project share one auto-reconnecting SSE connection, and every reconnect re-syncs state — so a dropped connection never leaves you stale. Full walkthrough: Real-time updates.
Typed errors
The SDK throws typed errors keyed to HTTP status codes:
Every error carries the HTTP status as err.statusCode. The SDK does not retry
automatically — on a CortexRateLimitError, back off before trying again (see
Rate limits).
Debug logging
Set debug: true to log every request and response (method, URL, status, body) to
console.debug:
API reference
Every class, method and type is documented in the generated reference:
Browse the SDK API reference