Skip to main content

Authentication

Every call to the Cortex API is authenticated. As an integrator you’ll use one of two mechanisms:

  • API key — for backends, game servers, CI and any machine-to-machine calls. This is the one you’ll use most.
  • JWT bearer token — for browser/dashboard sessions where a human has logged in.

Pick the right one and send it with every request.

API keys

An API key identifies a project (or a tenant) and optionally restricts which resources it can touch. Create and manage keys in the dashboard under your project’s Cortex → API Keys. A key looks like ots_live_... and is shown only once on creation — store it securely.

Send it as a header — either form works:

X-API-Key: ots_live_xxxxxxxxxxxxxxxxxxxx
Authorization: ApiKey ots_live_xxxxxxxxxxxxxxxxxxxx

With the SDK:

const client = new CortexClient({
baseUrl: "https://ots.odin.4players.io",
apiKey: process.env.CORTEX_API_KEY,
});
Keep keys server-side

An API key is a secret. Use it from your backend only — never embed it in a browser app, mobile app or shipped game client. If a key leaks, revoke it in the dashboard and create a new one.

Scopes

API keys can be narrowed two ways, so a key only ever has the access it actually needs:

  • Project-scoped — a key can be restricted to a single project. (A tenant-scoped key can see every project in your tenant; prefer project-scoping for production integrations.)
  • Resource scopes — a key can be limited to a subset of resource families: sessions, messages, plugins, plugin-endpoints, gatherings, functions.

For example, a key used only to read transcripts needs just sessions and messages. A call to an endpoint outside a key’s scopes is rejected.

JWT bearer tokens

JWTs are for dashboard / user sessions — when a human signs in, the dashboard exchanges their 4Players login for a short-lived Cortex JWT and sends it as a bearer token:

Authorization: Bearer eyJhbGciOi...
const client = new CortexClient({
baseUrl: "https://ots.odin.4players.io",
accessToken: jwt,
});

Use JWTs when you’re building UI on behalf of a logged-in user; use API keys for everything server-side.

A note on internal service auth

You may notice that ODIN platform services (Voice, Rooms, Fleet) and the serverless function runtime call Cortex using an HMAC-signed project secret rather than an API key. That mechanism exists for internal, server-to-server platform traffic — for example, the function runtime uses it under the hood so your function code gets a pre-authenticated ctx.cortex client for free.

It is not the recommended way to authenticate your own integrations, and we don’t document it as a customer-facing option — use an API key instead. (If you’re writing a serverless function, you don’t deal with it at all: ctx.cortex is already authenticated for you.)

Choosing the right mechanism