API Style Guide

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_id values 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/documents and /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 OK for successful reads and updates with response bodies.
  • 201 Created for creates that return a new resource or share/grant record.
  • 202 Accepted for accepted asynchronous work where the operation continues after the response.
  • 204 No Content for idempotent mutations that intentionally return no body, such as marking notifications read.
  • 400 for malformed business input, 401 for missing/invalid auth, 403 for authenticated users lacking permission, 404 when a resource is missing or intentionally hidden, 409 for conflicts, and 422 for 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 with items, total, limit, offset.
    • Cursor pagination: limit, cursor, response envelope with items, next_cursor.
  • Keep default ordering deterministic. If clients need control, use sort and order=asc|desc after defining allowed fields.

Auth And Authorization

  • Authenticated routes should depend on get_current_db_user when local ownership, sharing, or DB filtering is required.
  • Use helpers in backend/py/core/authorization.py for board, action-point, and document access.
  • Return 404 instead of 403 when 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/v1 until 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 orval from frontend.
    • Use generated clients via wrappers in frontend/src/api/*; do not hand-edit frontend/src/api/generated/*.