---
title: "Update Budget"
method: POST
path: "/organization/usage-policies/{policy_id}/budget"
tags: ["usage-budgets"]
---

# Update Budget

`POST /organization/usage-policies/{policy_id}/budget`

Change the budget on one of the caller's organization's active policies.

Organization admin only. The named policy is retired and a replacement holding
the new budget is created, so repeating the call refuses: the policy it addresses
is by then out of force, and the replacement has an id of its own.

An increase must leave the organization's active budgets for the resource kind
summing under its ceiling. A change that does not raise the budget is accepted
whatever that sum is, which is what lets an organization whose ceiling was
lowered beneath its allocations reduce its way back under it.

The replacement is charged for the window's history as it is created, which is how
consumption already measured survives the change, and the response says what that
charge wrote. A charge that cannot be computed refuses the call and leaves the
addressed policy in force with the budget it had.

## Path parameters

- `policy_id` string, uuid, required

## Request body

- UpdateUsageBudgetRequest — Body of the budget change; the path addresses the policy being replaced. Rejects unknown fields so a misspelled key fails rather than being read as a request to leave the budget alone.
  - `budget` integer, required — Credits the policy's scope may consume per window. 0 forbids all usage. The organization's active budgets for the resource kind must sum under the ceiling Traversal set, unless the change lowers this one.

## Response `201`

Successful Response

- UsageBudgetChangeResponse — Both rows the change left, and the consumption the new one carries forward. The replacement carries a new id, because the budget moved by retiring a policy rather than by altering one. Reporting only the new row would leave a caller unable to confirm that the budget it replaced actually left force. ``backfill`` is how the consumption already measured against the old budget reaches the new one: each policy's counter stands alone, so the replacement is charged for the window's history as it is created. Without it a raised budget would read as untouched, and a spent one could be cleared by editing it.
  - `retired_policy` UsagePolicyAdminResponse, required — A policy as stored, in force while ``retired_at`` is null. Nulls are serialized rather than dropped: an absent ``retired_at`` would be indistinguishable from a retired policy whose key the reader simply did not find.
    - `id` string, uuid, required
    - `policy_template_id` string, uuid, required
    - `organization_id` string, uuid, required
    - `scope` 'user' | 'organization' | 'automation', required — Whose consumption a policy counts. ``AUTOMATION`` counts the whole organization exactly as ``ORGANIZATION`` does and differs only in which activity it accepts: human and automated work draw on separate budgets, so each of those two scopes counts one of them and refuses the other.
    - `budget` integer, nullable — Credits the scope may consume per window. Null imposes no limit, which is distinct from 0 forbidding all usage.
    - `created_at` string, date-time, required
    - `retired_at` string, date-time, nullable — When the policy left force; null while it is in force.
  - `active_policy` UsagePolicyAdminResponse, required — A policy as stored, in force while ``retired_at`` is null. Nulls are serialized rather than dropped: an absent ``retired_at`` would be indistinguishable from a retired policy whose key the reader simply did not find.
    - `id` string, uuid, required
    - `policy_template_id` string, uuid, required
    - `organization_id` string, uuid, required
    - `scope` 'user' | 'organization' | 'automation', required — Whose consumption a policy counts. ``AUTOMATION`` counts the whole organization exactly as ``ORGANIZATION`` does and differs only in which activity it accepts: human and automated work draw on separate budgets, so each of those two scopes counts one of them and refuses the other.
    - `budget` integer, nullable — Credits the scope may consume per window. Null imposes no limit, which is distinct from 0 forbidding all usage.
    - `created_at` string, date-time, required
    - `retired_at` string, date-time, nullable — When the policy left force; null while it is in force.
  - `backfill` UsagePolicyBackfillResponse, required — What a backfill run examined and what it changed. The counts are what makes a repeat legible. A second run over an unchanged log reports the same events examined and counted, ``attributions_written`` of zero, and the same counters rebuilt to the same totals — so an admin can tell "already done" from "nothing to do", which the policy row itself cannot say. ``refusals`` is listed rather than counted: each entry names an event whose activity may belong in the budget this policy now binds against, and finding out needs the event.
    - `policy_id` string, uuid, required
    - `events_examined` integer, required — Events of the policy's resource kind the run read, from the start of the window the policy was created in onwards.
    - `events_counted` integer, required — Of those, the events this policy counts, by its selector and its scope.
    - `attributions_written` integer, required — Ledger rows this run added; zero when every charge was already recorded.
    - `counters_rebuilt` integer, required — Window counters set to the sum of their window's attributions.
    - `refusals` UsagePolicyBackfillRefusalResponse[], required — Events the run declined to judge, each with its reason.
      - `usage_event_id` string, uuid, required — The event left unjudged.
      - `reason` 'actor_identity_unrecorded', required — Why a backfill would not judge one event.

## Other responses

- `422` — Validation Error

## Changes

> 57 revisions in range; 9 not diffed.

- **2026-09-12** `d5665d7046eb` — 1 info
  - added the required property `backfill` to the response with the `201` status
- **2026-09-11** `c5e1ea955e81` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/traversal/apis/fastapi/changes/organization/usage-policies/:policy_id/budget/post.md)

---

[API](https://skmtc.dev/traversal/apis/fastapi.md) · [All operations](https://skmtc.dev/traversal/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc.dev/traversal/apis/fastapi/revisions/c3bd9dec6c16?raw)
