> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devinenterprise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Budgets

> Learn how enterprise budgets form an ACU limit tree, set monthly windows and per-budget user tiers, and manage budgets with the API.

> [!NOTE]
>
> Budgets are in beta and require the feature to be enabled for your enterprise. To enable this feature, reach out to your account team.

Budgets let you cap ACU usage the way your company is organized: one limit for the account, shared pools for teams or projects, and per-user limits inside each pool.

## Sample use cases

### Departments with delegated admins

Acme Corp has 10 departments. Each department head manages the limits of their orgs. Central IT sets each department's total. This example shows two of them.

Alice, the enterprise admin, creates a budget for each department under the Account budget. She shares each one with its department admin. Each department admin creates a budget for each of their orgs.

![Account budget of 100,000 ACU with Engineering at 30,000 ACU, with Payments and Search, and Marketing at 5,000 ACU.](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/budget-departments.svg?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=bfecc16bdf0286471712d39161e2567c)

Department budgets under the Account budget

* Bob, the Engineering department admin, can set limits and temporary limits on any budget under Engineering. For example, he can give Payments a temporary 6,000 ACU limit for a busy week.
* Bob cannot raise Engineering's 30,000 ACU limit. Only Alice can.
* Usage in every Engineering org counts toward the 30,000 ACU limit, even when the org budgets add up to more.

![Budgets page as a department admin](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/dept-admin-tree.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=cd8d27a58bfeb28446df8597ac4c2dc1)

The Budgets page as a department admin, with the Account budget locked

![Raising a child budget limit](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/dept-admin-edit-child.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=1c1c05e9681f2e62a5b95b344f476a41)

A department admin raising a child budget limit

![Department budget limit is read-only](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/dept-admin-own-limit.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=55c58f67119cb0af4c2f17d1db5d1f0a)

A department admin cannot change the department budget limit

### A project bucket with higher user limits

Every developer gets 200 ACUs a month. For the migration initiative, Acme Corp sets aside 5,000 ACUs and lets people on the project use more.

Keep the Developer tools orgs in a Developer tools budget with a 200 ACU default tier. Create a Migration initiative budget with a 5,000 ACU limit. Put the project's org in it, and give it a 1,000 ACU default tier. Both budgets sit under the Account budget.

![Developer tools at 20,000 ACU with a 200 ACU default tier, and Migration initiative at 5,000 ACU with a 1,000 ACU default tier.](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/budget-project.svg?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=cb189c909fb5c07095bd6d1f2c406cd6)

Developer tools and Migration initiative budgets with their tiers

* Carol, a developer on the project, can use up to 1,000 ACUs in the Migration org. She can use up to 200 ACUs in the Developer tools orgs.
* The whole project can never use more than 5,000 ACUs in a month.

![My Analytics budget picker](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/my-analytics-multi-budget.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=cf5fd4ca8608b542fec5484fb003985c)

My Analytics budget picker with several budgets

## How budgets work

### Budget tree

Each enterprise account has one budget tree. The root is the **Account budget**, and child budgets sit under it. A tree can be up to three levels deep.

A budget can hold one organization or several. Each organization belongs to exactly one budget. New organizations go under the Account budget.

For example, Acme Corp sets a 100,000 ACU limit on its Account budget. Engineering splits its pool into three child budgets.

![Account budget of 100,000 ACU with Engineering at 40,000 ACU, its three child budgets, and Developer tools at 20,000 ACU with three user limit tiers.](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/budget-tree.svg?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=923ef86ef029390214dbdd478d4f9328)

Budget tree with budgets and user limit tiers

Tiers are per-user limits inside one budget, not separate budgets.

![Budget tree with utilization per budget](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/tree.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=70ff5c75cc82a29a77669afc77de160f)

Budget tree with utilization per budget (mock data)

### Budget limits

A budget limit caps the combined ACU usage of the budget's orgs and the orgs in its child budgets, for one monthly window. A `null` limit means unlimited.

* **Usage counts toward every ancestor.** Usage in a child budget also counts toward its parent and the Account budget.
* **An exhausted ancestor blocks its children.** When any budget on the path runs out, usage in that branch stops.
* **Child limits can add up to more than the parent limit.** The parent limit still caps their combined usage.
* **A budget with no limit is still capped by its parents.**

A budget linked to exactly one organization shares its limit with that organization. The deprecated [organization-level ACU limit endpoints](https://docs.devinenterprise.com/admin/billing/org-acu-limits#organization-endpoints) set it too. You can also use the [update endpoint](#update-a-budget) below.

### What happens when a budget runs out

When a budget runs out, usage stops for its orgs. Usage also stops when any parent budget runs out. Usage resumes in the next monthly window, or when an admin raises the limit or sets a temporary limit.

* **Devin sessions:** new sessions cannot start, and running sessions sleep. Users see "Increase your organization's usage limit."
* **Devin CLI and Desktop local agent:** requests are blocked. Users see "Your organization has reached its monthly usage limit. Ask an account admin to raise it, or wait for the limit to reset next month."
* **Devin Review:** new reviews are blocked.

![Composer banner: usage limit reached](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/cloud-limit-reached.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=b4183e12594ad3d8d84eb223dc6d1246)

Composer banner when the budget is used up

### Monthly window

Budget limits, user limits, and temporary limits reset at the start of each monthly window. Each window starts on the start day of your billing phase. It is not always the calendar month.

For example, if the billing phase starts on the 15th, the windows run from October 15 to November 14, then from November 15 to December 14.

A **temporary limit** replaces the budget limit for the rest of the current window. The permanent limit returns in the next window. A temporary user override expires at the end of the current window.

![Marketing budget with a temporary limit](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/limits-temporary.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=8a19713130eef30fae3153e10400f77d)

A temporary limit raises Marketing to 6,000 ACUs for this window only

### User limits in a budget

User limits cap how much one person can use in a monthly window. Each budget has its own user limits, and they apply within that budget only.

* **Tiers.** Each budget has its own tiers and one default tier. A tier sets the monthly ACU limit for its members.
* **IdP group mappings.** Map an identity provider group to a tier. Members of the group get that tier.
* **Overrides.** Set a permanent or a temporary limit for one user.
* **Request policies.** Each tier sets how limit-increase requests are handled. `unconditional` and `conditional` approve requests up to the tier's `max_limit`. `manual` sends requests to an admin for review. The `conditional` policy requires separate enablement; reach out to your account team.
* **Scope.** A user limit counts only the user's usage in that budget's orgs.
* **Copy and clear.** Copy tiers from another budget or the account. You can also copy IdP group mappings, assignments, and overrides. Clear all tiers in a budget to start over.

> [!WARNING]
>
> A user limit on a parent budget does not cover its child budgets. For example, a 300 ACU user limit on Engineering does not cap a user's usage in Payments or Search.

![Copy usage policies dialog](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/copy-policies.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=cc1c5fce8d56e535d8502eab0501729b)

Copy usage policies dialog with Developer tools as the source

### Who can manage a budget

Enterprise admins manage budgets in **Enterprise Settings** under **Budgets**. They manage the whole tree, including the Account budget.

* **Delegation.** An enterprise admin can share a budget with a person or group in the Manage access tab. A delegated admin can create budgets under it, and set limits and temporary limits on those child budgets.
* **A delegated admin cannot raise the shared budget's own limit.** Only an admin who manages the parent budget can change it.
* **Members** see their own usage and limit in My Analytics.

![Manage access tab of the Engineering budget](https://mintcdn.com/cognitionai-enterprise/0zaCf8BmcmvBSHzW/images/admin/budgets/dept-admin-access.png?fit=max\&auto=format\&n=0zaCf8BmcmvBSHzW\&q=85\&s=58dc7d60892a7eba7a56297055dacd8f)

Manage access tab of the Engineering budget, with Bob as a manager

## Frequently asked questions

> [accordion] Can org admins set an org's ACU limit?
>
> No. Enterprise admins set org ACU limits. To let a team manage its own limits, share a budget with the team's admin.

> [accordion] Why does the org-limit endpoint return 409?
>
> The org-limit endpoint returns HTTP `409` when the org shares its budget with other orgs, or when it sits directly in the Account budget. The error reads "This organization has no limit of its own. Set the limit on its budget." For example, if Globex, Initech, and Umbrella share one budget, a limit write for Globex returns `409`.

> [accordion] When do limits reset?
>
> At the start of each monthly window. The window starts on the start day of your billing phase.

> [accordion] Can an org be in two budgets?
>
> No. Each org belongs to exactly one budget. A budget can hold many orgs.

## Manage budgets with the V3 API

All requests authenticate with an enterprise **service user token**. Callers need the **ManageAcuLimits** account permission or [delegated access](#who-can-manage-a-budget) to the budget. Use `https://api.devin.ai` as the base URL. See the [V3 API overview](https://docs.devinenterprise.com/api-reference/v3/overview.md) for authentication and service user guidance.

Budget-scoped collection endpoints take the budget in the path: `/v3beta1/enterprise/usage-policies/budgets/{budget_id}/...`. Endpoints that address a single tier or request (`/tiers/{tier_id}`, `/requests/{request_id}`) resolve the budget from the tier or request, so they share their paths with the account-wide endpoints.

### PATCH semantics

For the `PATCH` endpoints:

* An omitted field is unchanged.
* A field set to `null` is cleared.
* A field set to a value is created or updated.

## Budget endpoints

### List budgets

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets
```

Returns a paginated list of the account's budgets, active and archived. Each budget looks like:

```json theme={null}
{
  "budget_id": "budget-abc123",
  "name": "Engineering",
  "parent_budget_id": "budget-root",
  "org_ids": ["org-xyz789"],
  "status": "active",
  "cycle_acu_limit": 2000,
  "temporary_cycle_acu_limit": null
}
```

* `budget_id`: the identifier to use in budget-scoped paths.
* `parent_budget_id`: the parent budget; `null` for the account's root budget.
* `org_ids`: the organizations linked to this budget. Their usage counts against it. Empty when no organization is linked.
* `status`: `active` or `archived`.
* `cycle_acu_limit`: the budget's limit on the ACU consumption charged to it and its descendants per monthly billing window; `null` means unlimited.
* `temporary_cycle_acu_limit`: a limit that overrides `cycle_acu_limit` until the end of the current monthly billing window; `null` when none is live.

### Update a budget

```http theme={null}
PATCH /v3beta1/enterprise/usage-policies/budgets/{budget_id}
```

Partial update; omitted fields are unchanged and `null` clears a limit. At least one field is required.

* `parent_budget_id`: moves the budget, with its sub-budgets, under another active budget. The root budget cannot be moved, and budgets nest at most three levels deep.
* `cycle_acu_limit`, `temporary_cycle_acu_limit`: the budget's limits, as in the list response.

**Request body — set the limit and a temporary bump for this month**

```json theme={null}
{
  "cycle_acu_limit": 2000,
  "temporary_cycle_acu_limit": 2500
}
```

**Request body — remove the limits**

```json theme={null}
{
  "cycle_acu_limit": null,
  "temporary_cycle_acu_limit": null
}
```

**Request body — move the budget under another budget**

```json theme={null}
{
  "parent_budget_id": "budget-platform"
}
```

Returns the updated budget. Setting `temporary_cycle_acu_limit` again restarts it for the current window. For a budget linked to exactly one organization, `cycle_acu_limit` also becomes the organization's ACU limit.

## Tier endpoints

### List tiers

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets/{budget_id}/tiers
```

Returns a paginated list of the budget's tiers in precedence order: highest `priority` first, newest tier first within a priority. Each tier looks like:

```json theme={null}
{
  "tier_id": "tier-abc123",
  "name": "Engineers",
  "is_default": true,
  "cycle_acu_limit": 500,
  "policy": "manual",
  "max_limit": null,
  "priority": 0,
  "member_count": 42,
  "created_at": 1735689600
}
```

* `is_default`: whether this is the budget's default tier.
* `cycle_acu_limit`: the default per-cycle ACU limit for each member; `null` means uncapped.
* `policy`: how limit-increase requests against the tier are handled — `unconditional` and `conditional` approve up to `max_limit`, `manual` requires admin review.
* `max_limit`: the maximum limit to which increase requests are approved; `null` approves without a ceiling. Always `null` when `cycle_acu_limit` is `null`.
* `priority`: ranks the tier among a user's IdP-group-mapped tiers — the highest value wins, ties broken by newest tier. An explicit user assignment overrides the ranking, and the default tier never ranks.
* `member_count`: the number of users currently in the tier. For the default tier this counts every budget member not in another tier.

### Create a tier

```http theme={null}
POST /v3beta1/enterprise/usage-policies/budgets/{budget_id}/tiers
```

**Request body**

```json theme={null}
{
  "name": "Engineers",
  "cycle_acu_limit": 500,
  "policy": "manual"
}
```

The budget's first tier automatically becomes its default tier. Returns HTTP `201` with the created tier.

### Get a tier

```http theme={null}
GET /v3beta1/enterprise/usage-policies/tiers/{tier_id}
```

### Update a tier

```http theme={null}
PATCH /v3beta1/enterprise/usage-policies/tiers/{tier_id}
```

Partial update; omitted fields are unchanged.

```json theme={null}
{
  "name": "Engineering",
  "cycle_acu_limit": 750
}
```

### Delete a tier

```http theme={null}
DELETE /v3beta1/enterprise/usage-policies/tiers/{tier_id}
```

Returns HTTP `204` on success. The default tier cannot be deleted (promote another tier first). A tier that still has users must have them moved first, and any IdP group mappings to the tier must be removed first.

## Tier user endpoints

### List a tier's users

```http theme={null}
GET /v3beta1/enterprise/usage-policies/tiers/{tier_id}/users
```

Returns a paginated list of the tier's users with their resolved limits. For the default tier, this is every budget member not in another tier:

```json theme={null}
{
  "user_id": "user_abc123",
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "cycle_acu_limit_override": null,
  "temporary_cycle_acu_limit": 800,
  "effective_cycle_acu_limit": 800,
  "limit_source": "temporary_override",
  "membership": "explicit"
}
```

* `cycle_acu_limit_override`: the user's permanent override, if any.
* `temporary_cycle_acu_limit`: the user's temporary override, present only while it is live in the current monthly billing window.
* `effective_cycle_acu_limit`: the limit currently enforced for the user; `null` means uncapped.
* `limit_source`: where the effective limit comes from — `override` (permanent), `temporary_override`, or `tier`.
* `membership`: why the user is in the tier — `explicit` (directly assigned), `idp_group` (via their winning IdP group mapping), or `default` (fallback to the default tier).

### Assign a user to a tier

```http theme={null}
PUT /v3beta1/enterprise/usage-policies/tiers/{tier_id}/users/{user_id}
```

Idempotent. Returns HTTP `204` on success. Moving a user from another tier clears any per-user override, so they start out inheriting the destination tier's limit.

### Remove a user from a tier

```http theme={null}
DELETE /v3beta1/enterprise/usage-policies/tiers/{tier_id}/users/{user_id}
```

Removes the user's explicit tier assignment (and any override). The user then resolves to their IdP-group-mapped tier, if any, else the default tier. Returns HTTP `204` on success.

## User endpoints

### Get a user's limits

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets/{budget_id}/users/{user_id}
```

Returns the user's resolved tier, limits, and pending request within the budget. Includes the [tier user fields](#list-a-tiers-users) above plus:

```json theme={null}
{
  "tier_id": "tier-abc123",
  "tier_name": "Engineers",
  "tier_cycle_acu_limit": 500,
  "pending_request_id": null,
  "pending_request_cycle_acu_limit": null
}
```

* `tier_id` / `tier_name`: the tier the user's limit resolves from (explicit assignment, IdP group mapping, or the default tier); `null` when the budget has no tiers.
* `tier_cycle_acu_limit`: the tier's own limit before any override; `null` means uncapped.
* `pending_request_id` / `pending_request_cycle_acu_limit`: the user's pending limit-increase request and the limit it asks for, if any.

### Set or clear a user's override

```http theme={null}
PATCH /v3beta1/enterprise/usage-policies/budgets/{budget_id}/users/{user_id}
```

User-scoped: the target only needs to be a budget member — no tier is involved, and the user's tier assignment is never changed.

**Request body — set a temporary override**

```json theme={null}
{
  "cycle_acu_limit": 800,
  "kind": "temporary"
}
```

`kind` is required when setting a value: `permanent` never expires; `temporary` expires at the end of the current monthly billing window.

**Request body — clear all overrides**

```json theme={null}
{
  "cycle_acu_limit": null
}
```

The endpoint returns HTTP `204` on success.

## IdP group endpoints

Map an IdP group to a tier so its members inherit that tier automatically. Mappings are resolved live from group membership and never change a user's explicit tier assignment — an explicit assignment always wins. A user in several mapped groups resolves to the highest-ranked mapped tier (highest tier `priority`, ties broken by newest tier).

### List IdP group mappings

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets/{budget_id}/idp-groups
```

Returns a paginated list of the budget's group-to-tier mappings, oldest first. Filter with `?tier_id=` to list only groups mapped to one tier:

```json theme={null}
{
  "idp_group_id": "grp_abc123",
  "idp_group_name": "Engineering",
  "tier_id": "tier-abc123"
}
```

### Get an IdP group's mapping

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets/{budget_id}/idp-groups/{idp_group_name}
```

Returns HTTP `404` if the group has no mapping in the budget.

### Map an IdP group to a tier

```http theme={null}
PUT /v3beta1/enterprise/usage-policies/budgets/{budget_id}/idp-groups/{idp_group_name}
```

**Request body**

```json theme={null}
{
  "tier_id": "tier-abc123"
}
```

Idempotent upsert. The tier must belong to the budget. A group maps to at most one tier per budget, so mapping an already-mapped group moves it to the given tier.

### Unmap an IdP group

```http theme={null}
DELETE /v3beta1/enterprise/usage-policies/budgets/{budget_id}/idp-groups/{idp_group_name}
```

Returns HTTP `204` on success. The mapped tier stops applying to the group's members; users with no explicit assignment and no other mapped tier fall back to the default tier.

## Limit-increase request endpoints

Users can request a higher per-cycle limit. The requester's tier `policy` decides what happens: `unconditional` and `conditional` auto-approve up to the tier's `max_limit`, while `manual` holds the request for admin review through these endpoints.

### List limit-increase requests

```http theme={null}
GET /v3beta1/enterprise/usage-policies/budgets/{budget_id}/requests
```

Returns a paginated list of the budget's requests, filterable with `?status=` (`pending`, `approved`, `denied`, `expired`) and `?user_id=`:

```json theme={null}
{
  "request_id": 42,
  "user_id": "user_abc123",
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "tier_id": "tier-abc123",
  "tier_name": "Engineers",
  "current_cycle_acu_limit": 500,
  "requested_cycle_acu_limit": 800,
  "message": "Wrapping up a large migration this month",
  "status": "pending",
  "created_at": 1735689600,
  "reviewed_at": null,
  "reviewer": null
}
```

* `tier_id` / `tier_name`: the requester's tier within the budget; `null` when the budget has no tiers.
* `current_cycle_acu_limit`: the limit currently enforced for the requester; `null` means uncapped.
* `status`: `expired` means the request was still pending when its billing cycle ended.
* `reviewer`: the admin who reviewed the request; `null` while pending.

### Get a limit-increase request

```http theme={null}
GET /v3beta1/enterprise/usage-policies/requests/{request_id}
```

### Approve a limit-increase request

```http theme={null}
POST /v3beta1/enterprise/usage-policies/requests/{request_id}/approve
```

Grants the requested limit as a **temporary override** that expires at the end of the current monthly billing window. Optionally grant a different limit:

```json theme={null}
{
  "cycle_acu_limit": 700
}
```

Returns the updated request. Returns HTTP `409` if the request was already reviewed or the requester is no longer an account member.

### Deny a limit-increase request

```http theme={null}
POST /v3beta1/enterprise/usage-policies/requests/{request_id}/deny
```

Returns the updated request, or HTTP `409` if it was already reviewed.

## Example workflows

### Set up a budget's tiers

Find the budget, cap it at 2,000 ACUs a month, then create a default tier so every budget member gets a 500 ACU monthly cap:

```bash theme={null}
curl "https://api.devin.ai/v3beta1/enterprise/usage-policies/budgets" \
  -H "Authorization: Bearer <token>"

curl -X PATCH "https://api.devin.ai/v3beta1/enterprise/usage-policies/budgets/budget-abc123" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"cycle_acu_limit": 2000}'

curl -X POST "https://api.devin.ai/v3beta1/enterprise/usage-policies/budgets/budget-abc123/tiers" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "Standard", "cycle_acu_limit": 500, "policy": "manual"}'
```

Map an IdP group to the tier and give one user a temporary bump for the rest of the month:

```bash theme={null}
curl -X PUT "https://api.devin.ai/v3beta1/enterprise/usage-policies/budgets/budget-abc123/idp-groups/Engineering" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"tier_id": "tier-abc123"}'

curl -X PATCH "https://api.devin.ai/v3beta1/enterprise/usage-policies/budgets/budget-abc123/users/user_abc123" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"cycle_acu_limit": 800, "kind": "temporary"}'
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.