# Budget

A budget: a named pot of minutes on a project that tasks are filed under and time is logged against, optionally filed in an organisation-wide budget group. Deleting one is permanent and takes its tasks with it; a budget with logged time cannot be deleted.

## Used by
- GET /api/v2/budgets: List budgets (BudgetList)
- POST /api/v2/budgets: Create a budget (Budget)
- GET /api/v2/budgets/{budget}: Read a budget (Budget)
- PATCH /api/v2/budgets/{budget}: Update a budget (Budget)

## Budget fields
- id (integer, required): Unique identifier.
- project_id (integer, required): Owning project. Settable at create time only; a budget cannot be moved to another project.
- budget_group_id (integer or null, required): Budget group this budget is filed under, `null` when ungrouped.
- order_column (integer, required, server-assigned): Position within the project as arranged in plnnrly. Set on create to the highest existing position plus one, and renumbered 1..n per project whenever the project's budget page is saved in plnnrly. Not writable.
- description (string ≤ 255, required): Budget description as shown in the UI. This is the budget's label and the only field `?q=` searches; a budget has no title.
- start_date (date (YYYY-MM-DD) or null, required): First day the budget covers, `null` when it has no start.
- end_date (date (YYYY-MM-DD) or null, required): Last day the budget covers, `null` when it has no end.
- budget (integer, required): Budgeted amount of work, in minutes.
- spendable (integer, required): The portion of the budget that may be allocated to tasks, in minutes. A stored value, never decremented by logged time.
- status (string, required): Lifecycle status of the budget.
- is_open (boolean, required): Whether the budget is open-ended: when `true` the spendable cap is ignored, plnnrly shows "open" in place of a minute total and the over-budget warning is skipped.
- is_billable (boolean, required): Whether time logged on this budget is billable.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Creation timestamp.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync.
- project (Ref or ProjectSummary, required): The project this budget belongs to.
- budget_group (Ref or BudgetGroupSummary or null, required): The budget group this budget is filed under.
- tasks_count (integer ≥ 0, required): Number of kanban tasks on this budget that the caller may see.
- links (BudgetLinks, required)
  - self (url, required): The canonical URI of this record.
  - tasks (url, required): Kanban tasks filed under this budget.

## Variants

### BudgetList

What a collection returns, and what `?view=summary` returns on a single record.

18 fields.
Identical to the detail object above.

### BudgetSummary

The embedded form: what you get when another resource carries this one and you did not `include` it.

2 fields.
Omits: project_id, budget_group_id, order_column, start_date, end_date, budget, spendable, status, is_open, is_billable, created_at, updated_at, project, budget_group, tasks_count, links

### BudgetLinks

The `links` object on this resource.

Keys: self, tasks

## Example
```json
{
  "id": 1,
  "project_id": 1,
  "budget_group_id": 1,
  "order_column": 1,
  "description": "Front-end development",
  "start_date": "2026-03-04",
  "end_date": "2026-03-04",
  "budget": 4800,
  "spendable": 4200,
  "status": "active",
  "is_open": false,
  "is_billable": true,
  "created_at": "2026-03-04T09:15:00Z",
  "updated_at": "2026-03-04T09:15:00Z",
  "project": {
    "id": 1
  },
  "budget_group": null,
  "tasks_count": 1,
  "links": {
    "self": "https://<your-url>/api/v2/work-items/1",
    "tasks": "https://<your-url>/api/v2/work-items/1"
  }
}
```
