Sign in

API Conventions

Shared conventions for Cosmos service APIs: base URLs, authentication, required headers, error shapes, and pagination styles.

apiconventionsauthenticationheaderserrorspagination

Updated 2026-11-03

Verified 2026-11-03

Cosmos is a set of independent services, each with its own REST or WebSocket API. They share an authentication model and a few headers, but error and pagination shapes differ by service framework. This page describes what is common and where each service differs. The per-service API references link here instead of repeating these rules.

Base URLs

Every service serves its routes under /api/v1/ (health checks are unversioned). How you reach a service depends on the environment:

EnvironmentURL patternExample
Local developmenthttp://localhost:<port> (direct container port)http://localhost:8101/api/v1/users/me/
Per-service hostshttps://<service>-webserver.<domain>https://user-webserver.<domain>/api/v1/users/me/
Gateway deploymentshttps://<host>/cosmos/<service>https://<host>/cosmos/user/api/v1/users/me/

In gateway deployments the gateway strips the /cosmos/<service> prefix before forwarding, so the service sees the same /api/v1/... path in every environment. Gateway path segments are user, configurator, adk, chat, observer, storage, ragflow, voice, and bridge; the knowledge-base API uses kb.

Local development ports:

PortService
8100Configurator
8101User Service
8102MCP Tools Server
8103ADK
8104Observer
8106Voice
8107Storage
8108Chat
8109Bridge
8200RAGflow

Authentication

All non-health endpoints require a JWT issued by the User Service, sent as a bearer token:

http
Authorization: Bearer YOUR_TOKEN
  • User tokens come from POST /api/v1/users/login/ (plus the email-code step when MFA is required) or from the OAuth2 authorization-code flow. See Authentication API.
  • Service tokens are short-lived, audience-bound tokens that services obtain from POST /oauth/token/ with the OAuth2 client_credentials grant. They carry actor_type: "service". When a service acts for an end user it also sends one subject header (see below).
  • Services validate tokens against the User Service JWKS endpoint (/.well-known/jwks.json, RS256).
  • WebSocket endpoints accept the token in the Authorization header. Browser clients that cannot set headers pass it as a WebSocket subprotocol where the service supports it (for example Chat accepts Sec-WebSocket-Protocol: cosmos.v1, cosmos-auth.YOUR_TOKEN). WebSocket authentication failures close the socket with code 4401; authorization failures use 4403.

A missing or invalid token returns 401. A token that is valid but lacks the required permission returns 403.

Required Headers

HeaderRequiredPurpose
AuthorizationYes (except health checks and public auth endpoints)Bearer YOUR_TOKEN
X-Org-IdYes for organization-scoped endpointsOrganization UUID that scopes the request, for example YOUR_ORG_ID. Services check that the caller belongs to this organization.
X-Project-IdOptionalProject UUID that narrows the request to a project. Services that are not project-aware ignore it. Where it is honoured: User Service project routes require it to match the project in the path; Storage uses it for activity attribution; Observer uses it to scope the activity feed; RAGflow uses it for project-scoped knowledge-base search; ADK and Configurator accept it for project-scoped authorization.
X-On-Behalf-Of-User-IdService callers onlyUser ID a service token acts for. Some services also accept X-Subject-User-Id, X-Cosmos-Subject-User-Id, or X-Actor-User-Id; send exactly one.
X-Token-ModeOptional (User Service login and refresh)body returns refresh tokens in the JSON body instead of the cosmos_refresh cookie.
Content-TypeFor request bodiesapplication/json, or multipart/form-data for uploads.

When X-Org-Id is missing, services respond differently: Storage returns 400, Chat and Observer return 401, and User Service rejects organization-scoped and project requests. Health checks and the User Service login, refresh, and password-reset endpoints do not need it.

Errors

Error bodies follow the conventions of each service's framework. Check the status code first; the body shape varies.

ServiceTypical error body
User Service, Configurator (Django REST Framework){"detail": "..."}, or a field map such as {"email": ["This field is required."]} for validation errors. MFA and project endpoints add a machine-readable code: {"error": "invalid_code", "detail": "...", ...} or {"code": "duplicate", "detail": "..."}.
ADK, Observer, Chat, MCP (FastAPI){"detail": "..."}. Request validation errors return 422 with {"detail": [{"type": "...", "loc": [...], "msg": "..."}]}. Auth middleware errors use {"error": "..."} (Observer) or {"error": "unauthorized", "message": "..."} (Chat).
Storage{"error": "BadRequest", "status": 400, "message": "..."}; validation errors use the same shape with status 422.
RAGflowValidation errors return 422 with the FastAPI detail list; service errors return {"detail": "...", "code": "...", "context": {...}}.
Voice{"status": "error", "code": "...", "message": "..."}.

Common status codes:

StatusMeaning
400Invalid request, missing required header or field
401Missing, invalid, or expired token
403Authenticated but not permitted
404Resource not found or not visible to the caller
409Conflict (duplicate name, resource in use, inactive project)
422Request body failed validation (FastAPI services)
429Rate limited (for example MFA and password-reset throttles)
503A dependency (authorization service, analytics backend) is unavailable

Pagination

Services use one of three pagination styles.

Page-number pagination. Query with page (1-based) and page_size.

ServiceDefault / max page_sizeResponse envelope
User Service (most lists)10 / 100{"count", "next", "previous", "results"}
Configurator20 / 100{"total_count", "current_page", "page_size", "total_pages", "next", "previous", "results"}
Observer (sessions, frontend logs)20 / 100Same envelope as Configurator. Observer session lists add summary and the time range.

Cursor pagination. Follow the opaque cursor returned by the previous page.

ServiceParametersResponse envelope
User Service projects and project memberslimit (1–100, default 25), cursor{"results", "next", "previous"}. Cursors are signed, bound to the query, and expire after 24 hours.
Storage item browsepage_size (default 20, max 100), next_cursor{"results", "next_cursor", "page_size"}
Observer activity feedlimit (default 50), cursor; or page/page_sizeCursor page or numbered page

Unpaginated lists. Some admin lists return everything when you pass mode=all (User Service permissions and roles). Other endpoints, such as the User Service project roles list, return {"results": [...]} without paging.