Skip to main content

Capabilities

Budgets

Budgets hold the money your organization and its projects spend on AI usage, and the per-user spend limits that apply inside them. These endpoints let you read the budgets you administer, see what each member has spent against their limit, set per-user limits in bulk, and create, fund, and configure project budgets from automation instead of the admin UI.

Every organization has one organization budget. When project budgets are turned on, each project can also have a project budget that draws from the organization budget. The organization budget is funded by its contract, so only its member limits can be changed through the API. Turning project budgets on for the organization is done in the admin UI.

Every change made through these endpoints is recorded in the audit log, the same as a change made in the admin UI.

All paths below are relative to your instance's base URL (https://<your-domain>.nomic.ai/api/v0). See the overview for authentication details.

Scopes​

ScopeGrants
developer:budgets:readRead the budgets you administer and their per-user limits.
developer:budgets:writeCreate and change the budgets you administer, and set their per-user limits.

The broad developer scope implies developer:budgets:write, which in turn implies developer:budgets:read.

Scopes only let a key call these endpoints; access to each budget still follows your role. Organization admins administer the organization budget and every project budget. A project admin administers that project's budget. A budget you do not administer is reported as 404.

Wherever a path takes a budget {id}, you can pass organization in place of a UUID to address the organization budget.


List budgets​

GET /budgets

List the budgets the caller administers: the organization budget first, then project budgets by name. All budgets fit in one page, so nextCursor is always null.

Scope: developer:budgets:read · Rate limit: Standard (300 req / min)

Query parameters​

ParameterTypeDefaultDescription
scopeorganization | project—Only return budgets of this type.
projectIduuid—Only return this project's budget.

Response​

{
"data": [
{
"id": "019abc12-3456-7890-abcd-ef1234567890",
"name": "Acme",
"parentId": null,
"scope": { "type": "organization", "projectBudgetsEnabled": true },
"funding": {
"amountCents": 5000000,
"spentCents": 1234500,
"remainingCents": 3765500,
"renewal": null
},
"onExhausted": "block",
"memberLimits": {
"enabled": true,
"defaultCents": 20000,
"period": "monthly",
"resetsAt": "2026-11-01T00:00:00.000Z"
}
},
{
"id": "019abc12-3456-7890-abcd-ef1234567891",
"name": "Downtown Office Tower",
"parentId": "019abc12-3456-7890-abcd-ef1234567890",
"scope": {
"type": "project",
"projectId": "019c587e-3456-7890-abcd-ef1234567890"
},
"funding": {
"amountCents": 100000,
"spentCents": 42000,
"remainingCents": 58000,
"renewal": { "cadence": "monthly", "amountCents": 100000 }
},
"onExhausted": "use_parent",
"memberLimits": {
"enabled": false,
"defaultCents": null,
"period": null,
"resetsAt": null
}
}
],
"nextCursor": null,
"totalCount": 2
}
FieldTypeDescription
data[].iduuidBudget ID.
data[].namestringProject name for project budgets, else the budget name.
data[].parentIduuid?Budget this one draws from, or null for the organization budget.
data[].scopeobject{ "type": "organization", "projectBudgetsEnabled": boolean } or { "type": "project", "projectId": uuid }.
data[].funding.amountCentsnumberTotal granted to this budget, in US cents. The organization budget is funded by its contract.
data[].funding.spentCentsnumberSpent from this budget, in US cents.
data[].funding.remainingCentsnumberLeft to spend, in US cents. Negative when overspent.
data[].funding.renewalobject?{ "cadence": "weekly" | "monthly", "amountCents": number } — a repeating grant that refills the budget — or null.
data[].onExhaustedblock | use_parentWhen the budget runs out, block stops spend and use_parent keeps spending from the parent budget.
data[].memberLimits.enabledbooleanWhether per-user limits apply on this budget.
data[].memberLimits.defaultCentsnumber?Limit for members without their own, in US cents. null means no default limit.
data[].memberLimits.perioddaily | weekly | monthly | nullWindow each member limit resets on (UTC; weeks start Monday). null means the limit covers the whole contract.
data[].memberLimits.resetsAtstring?ISO-8601 end of the current window, or null when period is null.
nextCursornullAlways null.
totalCountnumberNumber of budgets returned.

Errors​

StatusCause
400Invalid query parameters.
401Missing or invalid API key.
403API key lacks developer:budgets:read scope.
429Standard rate limit exceeded.

Example​

curl "https://<your-domain>.nomic.ai/api/v0/budgets?scope=project" \
-H "Authorization: Bearer $NOMIC_API_KEY"

Get a budget​

GET /budgets/{id}

Fetch a single budget. Pass organization as the ID for the organization budget, which holds the organization-wide per-user limits.

Scope: developer:budgets:read · Rate limit: Standard (300 req / min)

Path parameters​

ParameterTypeDescription
idstring (uuid or literal)Budget ID, or organization for the organization budget.

Response​

Returns 200 OK with the budget under data, in the same shape as an item of List budgets.

Errors​

StatusCause
401Missing or invalid API key.
403API key lacks developer:budgets:read scope.
404No budget with this ID that the caller administers.
429Standard rate limit exceeded.

Example​

curl "https://<your-domain>.nomic.ai/api/v0/budgets/organization" \
-H "Authorization: Bearer $NOMIC_API_KEY"

List budget members​

GET /budgets/{id}/members

List each member's own limit, the limit that applies to them, and their spend in the budget's current window, ordered by email. The organization budget covers every user in the organization; a project budget covers the project's members.

Scope: developer:budgets:read · Rate limit: Standard (300 req / min)

Path parameters​

ParameterTypeDescription
idstring (uuid or literal)Budget ID, or organization for the organization budget.

Query parameters​

ParameterTypeDefaultDescription
limitint50Max results per page (1–100).
cursorstring—Opaque cursor from a previous page's nextCursor.

Response​

{
"data": [
{
"id": "019abc12-3456-7890-abcd-ef1234567890",
"email": "alice@example.com",
"name": "Alice Johnson",
"limitCents": 50000,
"effectiveLimitCents": 50000,
"spentCents": 12340,
"status": "within_limit"
},
{
"id": "019abc12-3456-7890-abcd-ef1234567891",
"email": "bob@example.com",
"name": "Bob Lee",
"limitCents": null,
"effectiveLimitCents": 20000,
"spentCents": 20000,
"status": "limit_reached"
}
],
"nextCursor": null,
"totalCount": 2
}
FieldTypeDescription
data[].iduuidUser ID of the member.
data[].emailstringMember email.
data[].namestring?Member display name, or null if unset.
data[].limitCentsnumber?The member's own limit in US cents, or null when they follow the budget's memberLimits.defaultCents.
data[].effectiveLimitCentsnumber?The limit that applies to the member, in US cents. null when member limits are off or neither an own limit nor a default is set.
data[].spentCentsnumberSpent in the budget's current limit window (see memberLimits.period), in US cents.
data[].statusunlimited | within_limit | limit_reachedunlimited when no limit applies, limit_reached once spend in the current window has reached the limit, else within_limit.
nextCursorstring?Cursor for the next page, or null if none remain.
totalCountnumberTotal members of the budget.

Errors​

StatusCause
401Missing or invalid API key.
403API key lacks developer:budgets:read scope.
404No budget with this ID that the caller administers.
409A project budget while project budgets are turned off (project_budgets_disabled).
429Standard rate limit exceeded.

Example​

curl "https://<your-domain>.nomic.ai/api/v0/budgets/organization/members?limit=100" \
-H "Authorization: Bearer $NOMIC_API_KEY"

Set budget member limits​

POST /budgets/{id}/members

Set or clear per-user limits in one batch of 1–100 changes, applied atomically: nothing is written unless every entry is valid. A limitCents of null clears the member's own limit so the budget's default applies. Sending the same batch twice changes nothing.

Member limits must be turned on for the budget, and every user must already be one of the budget's members; identify each by user ID or email. Changing limits on the organization budget requires the key owner to be an organization admin.

Scope: developer:budgets:write · Rate limit: Write (60 req / min)

Path parameters​

ParameterTypeDescription
idstring (uuid or literal)Budget ID, or organization for the organization budget.

Request body​

FieldTypeRequiredDescription
membersarrayYes1–100 limit changes to apply as one batch.
members[].userstring (uuid or email)YesThe member, by user ID or email address.
members[].limitCentsinteger (≥ 0) | nullYesThe member's own limit in US cents, or null to clear it so the default applies.

Response​

Returns 200 OK with the changed members after the batch, ordered by email, in the same shape as List budget members (without pagination fields).

Errors​

StatusCause
400Validation error, or an unknown, repeated, or non-member user.
401Missing or invalid API key.
403API key lacks developer:budgets:write scope, or the organization budget and the key owner is not an organization admin.
404No budget with this ID that the caller administers.
409Member limits are off for this budget (member_limits_disabled), or project budgets are turned off (project_budgets_disabled).
429Write rate limit exceeded.

Example​

Give Bob a $250 limit and put Carol back on the budget default:

curl -X POST "https://<your-domain>.nomic.ai/api/v0/budgets/organization/members" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"members": [
{ "user": "bob@example.com", "limitCents": 25000 },
{ "user": "carol@example.com", "limitCents": null }
]
}'

Update a budget​

POST /budgets/{id}

Change a budget's funding, overage behavior, renewal, or member limits. Send only the fields you want to change; everything else keeps its current value. Inside memberLimits, an omitted field is also left alone, while an explicit null clears it. Sending the same body twice changes nothing.

The organization budget is funded by its contract, so only its memberLimits can be changed, and only by an organization admin. When a project budget change includes amountCents, the funding change and every other field are applied as one step: if the parent budget can't cover the amount, nothing changes.

Scope: developer:budgets:write · Rate limit: Write (60 req / min)

Path parameters​

ParameterTypeDescription
idstring (uuid or literal)Budget ID, or organization for the organization budget.

Request body​

At least one field is required.

FieldTypeBudgetsDescription
amountCentsinteger (≥ 0)ProjectNew funding level in US cents. Raising it draws from the parent budget; lowering it returns the difference.
onExhaustedblock | use_parentProjectWhat happens when the budget runs out.
renewalobject | nullProject{ "cadence": "weekly" | "monthly", "amountCents": number } to refill the budget each period, or null.
memberLimits.enabledbooleanBothTurn per-user limits on or off.
memberLimits.defaultCentsinteger (≥ 0) | nullBothLimit for members without their own, in US cents. 0 blocks them; null removes the default.
memberLimits.perioddaily | weekly | monthly | nullBothWindow each member limit resets on. null (limits cover the whole contract) is allowed only on the organization budget.

Response​

Returns 200 OK with the budget after the change under data, in the same shape as an item of List budgets.

Errors​

StatusCause
400Validation error, amountCents, onExhausted, or renewal sent to the organization budget (organization_budget_contract_funded), or a project member limit without a period (invalid_budget_change).
401Missing or invalid API key.
403API key lacks developer:budgets:write scope, or the key owner cannot administer the budget or the parent budget it draws from.
404No budget with this ID that the caller administers.
409The parent budget cannot cover the new amount (insufficient_funds), or project budgets are turned off (project_budgets_disabled).
429Write rate limit exceeded.

Example​

Make spend opt-in: block everyone without their own limit, then give Alice one with Set budget member limits.

curl -X POST "https://<your-domain>.nomic.ai/api/v0/budgets/organization" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "memberLimits": { "enabled": true, "defaultCents": 0, "period": "monthly" } }'

curl -X POST "https://<your-domain>.nomic.ai/api/v0/budgets/organization/members" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "members": [{ "user": "alice@example.com", "limitCents": 10000 }] }'

Create a project budget​

POST /budgets

Give a project its own budget, funded from the organization budget. Funding, onExhausted, renewal, and member limits are applied together: if the organization budget can't cover amountCents, nothing is created. A project can have only one budget; change it later with Update a budget.

Project budgets must be turned on for the organization. The key owner needs admin access to the project, and funding it also requires admin access to the organization budget.

Scope: developer:budgets:write · Rate limit: Write (60 req / min)

Request body​

Takes projectId and amountCents, plus any field of Update a budget. A project member limit always needs a daily, weekly, or monthly period.

FieldTypeRequiredDescription
projectIduuidYesProject to fund.
amountCentsinteger (≥ 0)YesAmount to move into the budget from the organization budget, in US cents.

Response​

Returns 201 Created with the new budget under data, in the same shape as an item of List budgets.

Errors​

StatusCause
400Validation error, or a member limit without a period (invalid_budget_change).
401Missing or invalid API key.
403API key lacks developer:budgets:write scope, or the key owner cannot administer the project or the organization budget.
404No project with this ID that the key owner can read.
409The project already has a budget (budget_exists), the organization budget cannot cover the amount (insufficient_funds), or project budgets are turned off (project_budgets_disabled).
429Write rate limit exceeded.

Example​

curl -X POST "https://<your-domain>.nomic.ai/api/v0/budgets" \
-H "Authorization: Bearer $NOMIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "019c587e-3456-7890-abcd-ef1234567890",
"amountCents": 50000,
"onExhausted": "use_parent",
"renewal": { "cadence": "monthly", "amountCents": 50000 },
"memberLimits": { "enabled": true, "defaultCents": 5000, "period": "weekly" }
}'