Budgets & categories

All URLs below are relative to your site origin with the /api prefix (e.g. https://your-domain.com/api/v1/...).

All endpoints require Authorization: Bearer <api_key_or_jwt>.


GET /v1/budgets

Query parameters (all optional)

ParameterTypeDescription
limitnumber1–100, default per server
cursorstringPagination cursor
household_iduuidFilter by household
statusstringactive or archived

Request body: none

Response 200

{
  "data": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "name": "March 2025",
      "start_date": "2025-03-01",
      "end_date": "2025-03-31",
      "total_income": 5000,
      "total_spend": 1200.5,
      "household_id": null,
      "created_at": "2025-02-28T10:00:00.000Z"
    }
  ],
  "pagination": {
    "next_cursor": "eyJjcmVhdGVkX2F0IjoiLi4uIn0",
    "has_more": false
  }
}

POST /v1/budgets

Request body

{
  "name": "April 2025",
  "start_date": "2025-04-01",
  "end_date": "2025-04-30",
  "total_income": 5200,
  "household_id": null
}

total_income and household_id are optional (household_id may be null).

Response 201

{
  "data": {
    "id": "770e8400-e29b-41d4-a716-446655440002",
    "name": "April 2025",
    "start_date": "2025-04-01",
    "end_date": "2025-04-30",
    "total_income": 5200,
    "total_spend": 0,
    "household_id": null,
    "created_at": "2025-03-01T09:00:00.000Z"
  }
}

GET /v1/budgets/{budgetId}

Path parameters: budgetId (uuid)

Response 200

{
  "data": {
    "id": "770e8400-e29b-41d4-a716-446655440002",
    "name": "April 2025",
    "start_date": "2025-04-01",
    "end_date": "2025-04-30",
    "total_income": 5200,
    "total_spend": 0,
    "household_id": null,
    "created_at": "2025-03-01T09:00:00.000Z"
  }
}

Response 404

{
  "error": {
    "type": "not_found",
    "code": "resource_not_found",
    "message": "The requested budget was not found.",
    "request_id": "req_01abc..."
  }
}

PATCH /v1/budgets/{budgetId}

Request body (all fields optional)

{
  "name": "April 2025 (updated)",
  "start_date": "2025-04-01",
  "end_date": "2025-04-30",
  "total_income": 5400
}

Response 200 — same shape as GET single budget data object.


DELETE /v1/budgets/{budgetId}

Request body: none

Response 200

{
  "data": {
    "deleted": true
  }
}

GET /v1/budgets/{budgetId}/categories

Response 200

{
  "data": [
    {
      "id": "880e8400-e29b-41d4-a716-446655440003",
      "name": "Groceries",
      "color": "#4A5D4E",
      "icon": "cart",
      "allocation_type": "fixed",
      "allocation_value": 600,
      "total_spend": 120.4,
      "sort_order": 0
    }
  ]
}

POST /v1/budgets/{budgetId}/categories

Request body

{
  "name": "Dining out",
  "color": "#C07A5E",
  "icon": "utensils",
  "allocation_type": "percentage",
  "allocation_value": 15,
  "sort_order": 1
}

allocation_type is fixed or percentage. color, icon, and sort_order are optional.

Response 201

{
  "data": {
    "id": "990e8400-e29b-41d4-a716-446655440004",
    "name": "Dining out",
    "color": "#C07A5E",
    "icon": "utensils",
    "allocation_type": "percentage",
    "allocation_value": 15,
    "total_spend": 0,
    "sort_order": 1
  }
}