API Reference

Ragz exposes a REST API for everything the web app does — auth, workspaces, documents, chat — plus a separate, API-key-authenticated surface for programmatic and OpenAI-compatible access. Every route returns JSON (chat responses stream as Server-Sent Events).

The source of truth

This section is a guided tour. The complete, always-accurate machine-readable spec is served live by the backend at /api/openapi.json (interactive Swagger UI at /api/docs, when enabled). If anything here and the running server disagree, the server wins — generate your client from the OpenAPI document, don't hand-write it against these pages.

Base URLs

SurfaceBase pathAuth
Web app / session API/api/v1Bearer JWT (access token)
External / programmatic API/external/v1API key

A self-hosted instance is reachable at whatever origin you deployed it to — these examples use https://ragz.example.com.

curl https://ragz.example.com/api/openapi.json

Two auth modes

  • Session JWT — used by the Ragz web app. A 15-minute access token (Authorization: Bearer <token>) issued by POST /api/v1/auth/login, backed by a rotating refresh token in an httpOnly cookie. See Authentication.
  • API keys — used by scripts, backend integrations, and the OpenAI-compatible endpoint. A superadmin issues a key scoped to one user and one workspace; it's sent the same way, as a bearer token (or X-API-Key), against the /external/v1/* routes.

Both credential types resolve to the same tenant-scoped permission model — an API key can never see more than the workspace it was issued for.

Errors

Every error response is application/problem+json (RFC 9457):

{
  "type": "about:blank",
  "title": "Not permitted",
  "status": 403,
  "detail": "requires permission documents.upload"
}

Common status values: 400 bad request, 401 authentication failed, 403 not permitted, 404 not found, 409 conflict, 413 payload too large, 429 rate limited / quota exhausted, 502 upstream (LLM/provider) error.

Rate limiting

Auth endpoints (login, register, refresh, password reset, invitation accept) and chat message sends are rate-limited per account/user — a 429 with Too many requests means back off and retry. Limits are enforced server-side (Redis-backed); there is no client-visible quota header today.

Pagination and streaming

  • List endpoints (documents, chats, audit events) return a plain JSON array or an explicit { rows: [...] } / cursor page — check each endpoint's response model in the OpenAPI spec.
  • The audit log (GET /api/v1/admin/audit) is cursor-paginated (cursor query param, next_cursor in the response).
  • Chat is streamed: POST /api/v1/chats/{id}/messages and POST /messages/{id}/regenerate respond with text/event-stream (Server-Sent Events), not a single JSON body. See Chat for the event frames.

Multi-tenant by construction

Every route above is scoped to the caller's organization and workspace membership. There is no way to pass a different tenant's id and read its data — that boundary is enforced server-side on every request, not just in the UI.