Skip to content
Docs menu

spend

Cloud work an AI agent's key asked for beyond the free allowance, held until a person confirms it. The agent's call answers 202 with a hold. A person approves or denies the hold from the Inbox. Approving creates the job under the agent's recorded request, attributed to its key.

5 operations · 2 schemas

GET /v1/spend/holds

List held cloud spend

listSpendHolds · scope key:read

The holds the caller can see, newest first: those on their own account, on an organization they belong to, and those their keys filed. A key limited to repos sees only the holds it filed itself. status narrows the list. A pending hold past its expires_at reads as expired.

Parameters

listSpendHolds parameters
NameInTypeDescription
statusquerySpendHoldStatus
limitqueryinteger

default 20 · ≥ 1 · ≤ 100

Page size.

cursorquerystring

length ≤ 512

Opaque cursor from the previous page's next_cursor.

Responses

listSpendHolds responses
StatusDescriptionBody
200

Page of holds.

SpendHoldPage
401

Missing or invalid credentials.

Problemapplication/problem+json
422

Request failed validation.

Problemapplication/problem+json

GET /v1/spend/holds/{hold_id}

Get one held request

getSpendHold · scope key:read

One hold, with what was asked, the estimate, what approving would reserve, the free allowance's share, and the account's spend cap as it stands now. An agent polls this after a 202. A hold the caller may not see is 404.

Parameters

getSpendHold parameters
NameInTypeDescription
hold_idrequiredpathId

Held request id (spend_...).

Responses

getSpendHold responses
StatusDescriptionBody
200

The hold.

SpendHold
401

Missing or invalid credentials.

Problemapplication/problem+json
404

Resource not found (or hidden from the caller).

Problemapplication/problem+json

POST /v1/spend/holds/{hold_id}/approve

Approve a held request and create its job (web session only)

approveSpendHold · scope session

A person of the account confirms the spend. session scope: no API key of any scope may approve, so an agent cannot confirm its own hold. The hub then creates the job from the recorded request, as the key that asked, with the agent limit lifted for this one job. The job is attributed to that key for usage. The reservation is taken now, and the account's spend cap is applied now, not when the hold was filed. A 429 leaves the hold pending. A hold that is no longer pending, or whose key no longer works, is 409. Audited as spend.approve.

Parameters

approveSpendHold parameters
NameInTypeDescription
hold_idrequiredpathId

Held request id (spend_...).

Responses

approveSpendHold responses
StatusDescriptionBody
200

Approved, with the job's id in result_id.

SpendHold
401

Missing or invalid credentials.

Problemapplication/problem+json
403

Authenticated but not allowed (visibility, membership or scope).

Problemapplication/problem+json
404

Resource not found (or hidden from the caller).

Problemapplication/problem+json
409

State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...).

Problemapplication/problem+json
422

Request failed validation.

Problemapplication/problem+json
429

The account's spend cap is in stop mode, and this job would carry the month past it. The month counts recorded Lucen cloud spend, what queued and running cloud work could still cost, and this job's own most possible cost. errors[].type is quota.spend_cap. Retry-After counts the seconds until the month ends. Nothing was recorded, and work already running keeps running.

Problemapplication/problem+json
503

A service this endpoint needs is not configured in this deployment. The API boots with zero secrets. An endpoint that needs one says so instead of returning a stack trace.

Problemapplication/problem+json

POST /v1/spend/holds/{hold_id}/deny

Deny a held request with a reason (web session only)

denySpendHold · scope session

A person says no, and says why. The reason goes into the record the agent reads. session scope, like approving. 409 when the hold is no longer pending. Audited as spend.deny.

Parameters

denySpendHold parameters
NameInTypeDescription
hold_idrequiredpathId

Held request id (spend_...).

Request body

application/json · required · SpendHoldDecision

denySpendHold request body
FieldTypeDescription
reasonrequiredstring

length 1–1024

Why it is denied. It goes into the record the agent reads.

Responses

denySpendHold responses
StatusDescriptionBody
200

Denied.

SpendHold
401

Missing or invalid credentials.

Problemapplication/problem+json
403

Authenticated but not allowed (visibility, membership or scope).

Problemapplication/problem+json
404

Resource not found (or hidden from the caller).

Problemapplication/problem+json
409

State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...).

Problemapplication/problem+json
422

Request failed validation.

Problemapplication/problem+json

POST /v1/spend/holds/{hold_id}/cancel

Withdraw a held request

cancelSpendHold · scope key:write

The key that filed the hold, or a person of the account, takes it back. Nothing was started, so nothing is undone. 409 when the hold is no longer pending. Audited as spend.cancel.

Parameters

cancelSpendHold parameters
NameInTypeDescription
hold_idrequiredpathId

Held request id (spend_...).

Responses

cancelSpendHold responses
StatusDescriptionBody
200

Canceled.

SpendHold
401

Missing or invalid credentials.

Problemapplication/problem+json
403

Authenticated but not allowed (visibility, membership or scope).

Problemapplication/problem+json
404

Resource not found (or hidden from the caller).

Problemapplication/problem+json
409

State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...).

Problemapplication/problem+json

Schemas (2)

The schemas these operations reach before any other tag’s do. A type that links elsewhere is rendered on that tag’s page.

SpendHoldPage

object

SpendHoldPage fields
FieldTypeDescription
itemsrequiredarray of SpendHold
next_cursorrequiredstring | null

SpendHoldDecision

object

SpendHoldDecision fields
FieldTypeDescription
reasonrequiredstring

length 1–1024

Why it is denied. It goes into the record the agent reads.