---
title: "Create Session"
method: POST
path: "/v1/auth/session"
tags: ["auth"]
---

# Create Session

`POST /v1/auth/session`

Verify a sign-in credential and set the HttpOnly session cookie.

The session is bound to the identity that authenticated, so every request it
later authenticates resolves a user and that user's active organization
rather than only "a credential was presented once". The response names both,
so a client knows who it is signed in as without a second call.

The rate-limit check deliberately runs only after a failed verification,
not before it: a pre-verification gate can't know whether *this* attempt
would have succeeded, so once an IP has used up its failure quota it
would end up blocking that IP's legitimate owner too, not just further
attackers. Running after verification also means the throttle bounds how
many verdicts an IP gets, not how much work it can cause: a password attempt
pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and
one is burned against a stand-in hash even for an address nobody holds)
before the limit is consulted, so a 429 costs the same as a 401. A gateway
exposed to the internet should rate-limit this path at the proxy as well.

## Request body

- CreateSessionRequest — Sign in to the dashboard with exactly one credential. A flat body with an optional field per credential, rather than a tagged union: it is one extra key on the wire, it generates a client type a hand-written form can fill in, and the validator below makes the two forms exclusive anyway. The example carries one credential, because a generated example is a body somebody will post: the schema alone would produce every field at once, which is the one shape the validator below refuses.
  - `email` string, nullable — The identity's sign-in address.
  - `master_key` string, nullable — The gateway master key; verified once and never stored by the browser. Accepted only while no identity on this deployment has a password (see GET /v1/bootstrap).
  - `password` string, nullable — The identity's password.

## Response `200`

Successful Response

- SessionResponse — A freshly minted dashboard session (the token travels only in the cookie).
  - `active_organization_id` string, uuid, required — The organization that identity is acting in, which scopes every tenancy surface.
  - `expires_at` string, date-time, required — When the session cookie stops being accepted.
  - `user_id` string, uuid, required — The identity this session speaks for.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/mozilla-ai/apis/otari.md) · [All operations](https://skmtc.net/mozilla-ai/apis/otari/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mozilla-ai/otari/revisions/a4401e66e263/schema)
