# API overview and authentication

Understand identities, workspace scope, browser origins, and response formats before making requests.

Ralti’s application API lives under the app host at /api. The public marketing website is a separate service. The endpoint catalog covers all 75 explicitly exported HTTP handlers across 53 route paths in the current source. It describes the application contract that exists today; it does not imply a separate versioned public developer platform or a new API-key system.

## Choose the correct identity

| Client | Credential | Important distinction |
| --- | --- | --- |
| Web and installed iPhone/iPad app with Clerk | Clerk session cookie managed by Clerk | Use the shared Clerk website sign-in flow. Explicit iOS provider actions return through the native session handoff; POST /api/auth is not a replacement for Clerk sign-in. |
| Earlier Android client or direct API client with Clerk | Authorization: Bearer <current Clerk session JWT> | Obtain a current token through the client SDK; never embed Clerk server secrets. |
| Explicit local development | Ralti session cookie or opaque native bearer token | Local signup/signin/signout are development flows, without Clerk’s recovery or email-verification guarantees. |
| External AI/MCP | A scoped Ralti MCP connection token | Issued separately, bound to one workspace, and accepted at /api/mcp. It is not a normal app session. |
| Published form | x-ralti-form-key capability | Authorizes only the published form; it is not workspace membership. |

GET /api/session is the bootstrap for ordinary app clients. In Clerk mode an unsigned request receives 401 clerk_signin_required and does not create a guest. In explicit local mode it can create an empty guest workspace. A local native bootstrap identifies itself with x-atlas-client: native and receives an opaque token only when the response creates that session. Existing session reads do not continuously return or rotate a token.

## Keep workspace scope explicit

Send X-Atlas-Workspace when a request belongs to a selected workspace. If omitted, the server resolves the account’s saved preference. The header selects a resource boundary; it never proves membership or changes the permissions attached to the identity. Keep it tied to the screen, draft, or asynchronous action that initiated the request so a workspace switch cannot redirect in-flight work.

```http
GET /api/session HTTP/1.1
Host: app.your-domain.example
Authorization: Bearer <current-session-jwt>
X-Atlas-Workspace: workspace_example
X-Ralti-Workspace-Mode: paged
```

The session response includes the public user, workspace, access, workspace list, member directory, and capabilities. Request paged mode for a bounded workspace representation, then use the record page endpoints. Capabilities tell the client whether cloud AI is configured and which storage/auth mode the server reports; they do not replace feature-specific permission checks.

## Browser writes and native requests

Browser mutations require an Origin that exactly matches the application’s configured public origin. A different scheme, host, or port is a different origin. Requests with a supplied mismatched Origin are rejected even when they also carry a bearer token. Native bearer requests can omit Origin when they are not identified as cross-site browser requests. Ralti does not grant blanket cross-origin browser access to its API.

For JSON endpoints send Content-Type: application/json and an object body. Limits vary by endpoint. File uploads use multipart/form-data; let the client library generate its boundary. Keep authentication tokens and mailbox passwords out of logs, screenshots, URLs, and exported examples.

## Read the response type before parsing

- Normal JSON responses use no-store and nosniff headers; failures usually contain error and code.
- Attachment, CSV/JSON sheet export, and document PDF routes return download bytes on success.
- Email OAuth callback routes redirect with HTTP 303 on both success and failure.
- Immediate interpretation can return NDJSON when stream:true.
- MCP uses the SDK’s JSON-RPC/protocol transport and its own error behavior.
- GET /api/health is public liveness only and does not prove database, authentication, provider, or worker readiness.

> **Synthetic examples** Every example in this reference uses synthetic IDs, dates, and addresses. Replace identifiers and revisions with values returned from your own authorized session. Placeholder bearer strings are explanatory text, not working credentials.

