CORTEX

Sessions for user-facing apps

If your app authenticates end users with their Cortex credentials, use this endpoint to exchange an API key plus user credentials for a short-lived user JWT.

When you need this

Most integrations don't need sessions. If your service talks to Cortex on its own behalf — a background job, a server-side data pipeline, an automation — use the API key directly as described in Authentication. Every request runs as the API key's identity, and that is the right model for machine-to-machine work.

Sessions exist for a narrower case: you are building a user-facing application where your end users sign in with their own Cortex credentials, and each request needs to be made as that user rather than as your service account. Examples include a customer-built portal, a custom chat UI, or an internal tool that authorizes against Cortex user identities.

Same-organization scope

An API key authenticates users in the same organization that the key belongs to. If your organization is acme and you call /v1/auth/sessions with a user whose account lives in a different organization, the request returns 401 — the same response shape as bad credentials, with no information leak about whether the account exists elsewhere.

Cross-organization authentication (one credential minting JWTs for users in any organization) is reserved for Cortex-operated sign-in portals and is not part of the public developer surface. Within your own organization there is nothing extra to configure — any API key works.

Request

Send the user's email and password as a JSON body, authenticated with your API key:

curl https://api.cortex.cognit-dx.com/v1/auth/sessions \
  -X POST \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@acme.example",
    "password": "..."
  }'

The calling credential must be an API key. A request that presents a JWT in the Authorization header is rejected — JWTs cannot mint new JWTs.

Response

On success, the response is a flat object with the minted token and its expiration:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2026-05-17T15:32:11.123Z"
}

The token is a JWT with an 8-hour lifetime. Treat the token as an opaque string — do not parse it, do not decode the payload, do not rely on its internal structure. The exact format is an implementation detail.

Use expires_at to know when to refresh. Shortly before it expires, exchange the current token for a fresh one with POST /v1/auth/sessions/renew — send the API key in the Authorization header and the current token in the body. No password is required, so you can keep users signed in silently. A token left idle past the 7-day renew window must mint a fresh session with credentials again.

Use the JWT

Send the JWT in the Authorization header on any downstream call. The request runs as the user the JWT was minted for.

curl https://api.cortex.cognit-dx.com/v1/threads \
  -H "Authorization: Bearer $CORTEX_TOKEN"

After 8 hours the JWT expires and the next request returns 401. Refresh silently with POST /v1/auth/sessions/renew (no credentials needed); only once a token is idle past the 7-day renew window do you re-mint with POST /v1/auth/sessions and the user's credentials.

Errors

StatusCodeWhen
401api_key_requiredThe calling credential is a JWT, not an API key. Only API keys can mint sessions.
401invalid_credentialsThe email or password is wrong, or the user belongs to a different organization than the API key. The two cases return the same response.
400invalid_requestThe request body is missing required fields or has the wrong shape.

Chain of trust

Every minted JWT references the API key that minted it. If that API key is later revoked, every JWT derived from it stops working immediately — there is no independent validity window. Revoking a leaked API key is therefore enough to terminate every active user session it produced, without needing to track or invalidate JWTs individually.