Authentication
Session cookies for the web app, access tokens for native apps, API tokens for scripts and MCP.
The OpenAPI schema declares three security schemes, and each operation lists the ones it accepts.
| Scheme | Sent as | For | Accepted by |
|---|---|---|---|
sessionCookie | semestra_session cookie | The web app | Every signed-in endpoint |
accessToken | Authorization: Bearer <JWT> | Native apps | Every signed-in endpoint |
personalAccessToken | Authorization: Bearer spat_… | Scripts and MCP clients | /mcp and capabilities offered to MCP |
A Bearer header takes precedence over the cookie, and a request with a bad Bearer value does
not fall back to the cookie.
API tokens
Create one in global settings → Account → API tokens (POST /account/tokens from a
signed-in session). The secret is returned once; Semestra stores only its hash.
- Access:
readorread+write. A read-only token can only call operations that read. - Reach: API tokens work for
/mcpand for the HTTP endpoints of capabilities that are offered to MCP, marked withpersonalAccessTokenin the reference. Account, AI provider, token and data-export endpoints refuse them withauth.token_scope. - Expiry: never, or after 30, 90 or 365 days. Revoke a token from the same page.
curl https://semestra.example.com/programs \
-H "Authorization: Bearer spat_…"Session cookies
The sign-in endpoints (/auth/email/verify, /auth/password/login, /auth/google) set two
cookies: semestra_session (HTTP-only) and semestra_csrf. Requests other than GET, HEAD
and OPTIONS must repeat the CSRF cookie's value in the X-Semestra-CSRF header.
Access tokens for native apps
Add ?client=native to a sign-in request to receive tokens in the body instead of cookies:
{ "tokens": { "access_token": "…", "refresh_token": "…", "token_type": "Bearer", "expires_in": 900 } }The access token lasts 15 minutes by default; exchange the refresh token at
POST /auth/token/refresh. API tokens are not accepted on endpoints outside the capability set,
such as file uploads and /events/stream, so native apps use access tokens there.