API Overview
REST API fundamentals: base URL, authentication, error handling, and workspace scoping.
The DocuStore API is a REST API built on FastAPI. All endpoints require authentication and are scoped to a workspace. The API serves JSON responses and accepts JSON request bodies unless otherwise noted (file uploads use multipart form data).
Base URL
http://localhost:8000In production, the API is served behind a reverse proxy with TLS termination. The base URL is configurable via API_HOST and API_PORT.
Authentication
DocuStore uses Duar for authorization in AuthZ mode. Every request carries two tokens:
curl http://localhost:8000/artifacts \
-H "Authorization: Bearer <idp_token>" \
-H "X-Authz-Token: <authz_token>"The authentication flow:
- The client authenticates with an Identity Provider (IdP) directly (e.g., Google OAuth) and obtains an IdP token.
- The client exchanges the IdP token for a short-lived Duar authorization token scoped to one workspace. Minting needs the service key, so it goes through a server-side route: the portal uses its own
/api/auth/mint, and non-browser clients such as the CLI canPOST /auth/minton the API with{"idp_token": "...", "provider": "google", "workspace_id": "..."}. - The authorization token encodes the user's
workspace_id,user_id, and workspace role. - Every API request sends the IdP token in
Authorizationand the authorization token inX-Authz-Token. The server validates both, checks that they belong to the same user, and extracts the auth context.
The RequestAuth object extracted from the tokens provides:
| Field | Description |
|---|---|
workspace_id | The workspace this request operates within |
user_id | The authenticated user ID |
workspace_role | The user's role in the workspace |
is_admin | Whether the user is a workspace admin or owner |
Workspace Scoping
All data access is scoped to the authenticated user's workspace. List endpoints return only resources belonging to that workspace. Resource endpoints verify workspace membership before returning data.
Additionally, entity-level permissions control access to individual artifacts:
| Permission | Description |
|---|---|
view | Read artifact and its pages |
edit | Modify artifact metadata, trigger workflows |
Artifacts support two visibility levels:
| Visibility | Who Can Access |
|---|---|
private | Owner only |
workspace | All workspace members |
Either way, the owner or a workspace admin can also share an artifact with specific users or groups.
Error Handling
The API returns standard HTTP status codes:
| Status | Meaning |
|---|---|
200 | Success |
201 | Resource created |
202 | Accepted (workflow started, non-blocking) |
204 | No content (successful deletion) |
400 | Invalid request (rejected by the application) |
401 | Missing or invalid IdP or authorization token |
403 | Forbidden (insufficient permissions) |
404 | Resource not found or not in workspace |
409 | Concurrency conflict (retry the request) |
422 | Request body or query parameters fail schema validation |
500 | Internal server error |
Error responses include a JSON body with a detail field:
{
"detail": "Artifact not found or does not belong to this workspace"
}Request Timing
When enabled (ENABLE_REQUEST_TIMING=true), the API logs timing information for every request and flags slow requests exceeding SLOW_REQUEST_THRESHOLD_MS (default 1000ms).
API Sections
| Section | Prefix | Description |
|---|---|---|
| Artifacts | /artifacts | Document CRUD, upload, metadata, workflows |
| Pages | /pages | Page retrieval, extraction triggers, summaries |
| Search | /search | Text, compound, summary, and hierarchical search |
| Chat | /chat | Conversational RAG with SSE streaming |
| Browse | /browse | Tag-based document exploration and discovery |