Skip to main content

API Reference Notes

This document summarizes API versioning and error payload conventions for sideBar.

Versioning

  • Base path: /api/v1 for all backend routes.
  • Legacy path: /api/* routes are supported but deprecated.

Deprecation headers

When a legacy /api/* route is used, the backend responds with:
  • X-API-Deprecated: true
  • X-API-Deprecated-Path: /api/...
  • X-API-New-Path: /api/v1/...
  • X-API-Sunset-Date: 2026-06-01

Error responses

All API errors return a consistent JSON payload:
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "query required",
    "details": {
      "field": "query"
    }
  }
}

Error codes

These are the standardized error codes returned by the backend:
CodeHTTPDescription
BAD_REQUEST400Invalid request payload or missing input.
VALIDATION_ERROR400Validation failed for a specific field.
AUTHENTICATION_REQUIRED401Missing authentication credentials.
INVALID_TOKEN401Invalid or expired token.
PERMISSION_DENIED403User lacks permission for the action.
NOT_FOUND404Resource does not exist.
CONFLICT409Resource state conflict (e.g., in-progress processing).
PAYLOAD_TOO_LARGE413Upload exceeded size limits.
RANGE_NOT_SATISFIABLE416Invalid content range requested.
SERVICE_UNAVAILABLE503Required service unavailable.
INTERNAL_ERROR500Unhandled server error.
EXTERNAL_SERVICE_ERROR502Upstream service failed.
HTTP_ERRORvariesLegacy FastAPI HTTPException normalization.

Tasks API

Base path: /api/v1/tasks

GET /lists/{scope}

Scopes: inbox, today, upcoming, someday, search (use /search endpoint), project, area. Response (example):
{
  "scope": "today",
  "generatedAt": "2026-01-22T10:15:00Z",
  "tasks": [
    {
      "id": "uuid",
      "title": "Do the thing",
      "status": "inbox",
      "deadline": "2026-01-22",
      "notes": "Optional",
      "projectId": "uuid",
      "areaId": "uuid",
      "repeating": false,
      "repeatTemplate": false,
      "updatedAt": "2026-01-22T10:14:00Z"
    }
  ],
  "projects": [{ "id": "uuid", "title": "Project", "areaId": "uuid", "status": "active" }],
  "areas": [{ "id": "uuid", "title": "Area" }]
}

GET /search?query=...

Response (example):
{
  "scope": "search",
  "generatedAt": "2026-01-22T10:15:00Z",
  "tasks": [{ "id": "uuid", "title": "Find me", "status": "inbox" }]
}

GET /counts

Response (example):
{
  "generatedAt": "2026-01-22T10:15:00Z",
  "counts": { "inbox": 3, "today": 1, "upcoming": 2 },
  "projects": [{ "id": "uuid", "count": 1 }],
  "areas": [{ "id": "uuid", "count": 2 }]
}

POST /apply

Applies task operations (single or batched) with idempotency. Request (single op example):
{ "op": "add", "title": "New Task", "operation_id": "op-1" }
Request (batch example):
{ "operations": [{ "op": "add", "title": "New Task", "operation_id": "op-1" }] }
Response (example):
{
  "applied": ["op-1"],
  "tasks": [{ "id": "uuid", "title": "New Task", "status": "inbox" }],
  "nextTasks": [],
  "conflicts": [],
  "serverUpdatedSince": "2026-01-22T10:15:00Z"
}

POST /sync

Offline-first sync endpoint. Applies outbox operations and returns deltas since last_sync. Conflicts return the server version without applying the client op. Request (example):
{
  "last_sync": "2026-01-22T09:00:00Z",
  "operations": [
    {
      "operation_id": "op-2",
      "op": "rename",
      "id": "uuid",
      "title": "Updated title",
      "client_updated_at": "2026-01-22T09:01:00Z"
    }
  ]
}
Response (example):
{
  "applied": ["op-2"],
  "tasks": [],
  "nextTasks": [],
  "conflicts": [
    {
      "operationId": "op-2",
      "op": "rename",
      "id": "uuid",
      "clientUpdatedAt": "2026-01-22T09:01:00Z",
      "serverUpdatedAt": "2026-01-22T09:05:00Z",
      "serverTask": {
        "id": "uuid",
        "title": "Server title",
        "status": "inbox",
        "updatedAt": "2026-01-22T09:05:00Z",
        "deletedAt": null
      }
    }
  ],
  "updates": {
    "tasks": [{ "id": "uuid", "title": "Server title", "deletedAt": null }],
    "projects": [{ "id": "uuid", "title": "Project", "deletedAt": null }],
    "areas": [{ "id": "uuid", "title": "Area", "deletedAt": null }]
  },
  "serverUpdatedSince": "2026-01-22T10:15:00Z"
}