API Style Guide
Owner: Backend Engineering Last reviewed: 2026-Q2
This page defines the API conventions for FastAPI routes and the frontend OpenAPI/Orval client.
Route Shape
- Public product APIs live under
/api/*; health probes live under/health/*. - Prefer plural nouns for resources:
/boards,/boards/{board_id},/documents/{document_uuid}. - Prefer kebab-case path segments for multi-word concepts:
/action-points,/download-url,/process-query. - Keep route modules grouped by capability in
backend/py/api/routes/*. - Add explicit
operation_idvalues for routes consumed by Orval.
Current mounted route families are:
/api/kanban- boards, columns, action points, board permissions, action-point shares./api/comments- action-point comments./api/users- current user sync and lookup./api/notifications- notification inbox and read state./api/documentsand/api/azure- document sharing and Azure Blob document operations./api/openai,/api/vision,/api/doc-intel,/api/embeddings,/api/query,/api/azuredocs- AI, OCR, embeddings, and query workflows./api/webhooks- provider webhooks.
Status Codes
200 OKfor successful reads and updates with response bodies.201 Createdfor creates that return a new resource or share/grant record.202 Acceptedfor accepted asynchronous work where the operation continues after the response.204 No Contentfor idempotent mutations that intentionally return no body, such as marking notifications read.400for malformed business input,401for missing/invalid auth,403for authenticated users lacking permission,404when a resource is missing or intentionally hidden,409for conflicts, and422for schema validation failures.
Request And Response Models
- Define request and response shapes in
backend/py/schemas/*when the route is part of the product API. - Avoid returning untyped inline dictionaries from stable endpoints; typed response models produce better OpenAPI clients.
- Use explicit enums or constrained fields for user-controlled strings with known values, such as permission level, status, and priority.
- Keep server error responses consistent and avoid leaking provider internals, secrets, or stack traces.
Pagination, Filtering, And Ordering
- Paginate endpoints that can grow without a natural small bound.
- Prefer one of two patterns and document the choice on the endpoint:
- Offset pagination:
limit,offset, response envelope withitems,total,limit,offset. - Cursor pagination:
limit,cursor, response envelope withitems,next_cursor.
- Offset pagination:
- Keep default ordering deterministic. If clients need control, use
sortandorder=asc|descafter defining allowed fields.
Auth And Authorization
- Authenticated routes should depend on
get_current_db_userwhen local ownership, sharing, or DB filtering is required. - Use helpers in
backend/py/core/authorization.pyfor board, action-point, and document access. - Return
404instead of403when revealing resource existence would leak another user’s data.
Deprecation And Versioning
- The API is intentionally unversioned for now even though the FastAPI OpenAPI document has an app version.
- Do not add
/api/v1until there are external consumers or unavoidable breaking changes. - For internal deprecations, keep the old route as a wrapper when practical, mark it deprecated in FastAPI, and document the replacement route in the code and release notes.
OpenAPI And Orval
- FastAPI’s OpenAPI output is the contract used by
frontend/openapi.json. - When changing a route consumed by the frontend:
- Update schemas and route metadata.
- Refresh
frontend/openapi.json. - Run
npm run orvalfromfrontend. - Use generated clients via wrappers in
frontend/src/api/*; do not hand-editfrontend/src/api/generated/*.