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

# Budget Requests

> Let agents request spending budgets with human approval, tracked across all payment types

# Budget Requests

Budget requests let an agent ask for a spending budget that a human reviews and approves in the dashboard. Once approved, spend is tracked against the approved amount across **all payment types** (standard, x402, MPP, card). When the budget is exhausted, further payments are blocked.

<Info>
  Budget requests are **optional**. If no active budget exists for an agent, all payment flows work normally using existing spend limits and policies. When an active budget *does* exist, both the budget and policies must pass for a payment to go through.
</Info>

## How It Works

```
Agent                                    Human (Dashboard)
  │                                          │
  ├─ request_budget ──────────────────────>  │ Sees request in Budgets tab
  │  (amount, purpose)                       │
  │                                          │
  ├─ get_budget_request ◄──────────────────  │ Approves (optionally adjusts
  │  (polls for APPROVED)                    │ amount) or rejects
  │                                          │
  ├─ Makes payments normally:                │
  │  • payments/request ──> budget check     │
  │  • x402/pre-authorize ──> budget check   │
  │  • mpp/pre-authorize ──> budget check    │
  │  • After execution ──> spend decremented │
  │                                          │
  └─ Budget exhausted → payments blocked     │ Sees spend progress bar
```

## Lifecycle

A budget request moves through these states:

| Status      | Description                                                                           |
| ----------- | ------------------------------------------------------------------------------------- |
| `PENDING`   | Awaiting human review. Expires 24h after creation if not acted on.                    |
| `APPROVED`  | Human approved. Spend is tracked. Expires at a set time (default 24h after approval). |
| `REJECTED`  | Human rejected with an optional reason.                                               |
| `EXPIRED`   | Timed out without approval, or approved budget window elapsed.                        |
| `EXHAUSTED` | Approved budget fully spent (`currentSpend >= approvedAmount`).                       |

**Constraints:**

* One active (PENDING or APPROVED) budget request per agent at a time
* Creating a new request while one is active returns `409 BUDGET_REQUEST_EXISTS`

## SDK API

### Create a Budget Request

```bash theme={null}
curl -X POST https://conto.finance/api/sdk/budget-request \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50,
    "purpose": "Research 200 companies via StableEnrich and generate reports",
    "category": "API_PROVIDER"
  }'
```

**Parameters:**

| Parameter  | Type   | Required | Description                                             |
| ---------- | ------ | -------- | ------------------------------------------------------- |
| `amount`   | number | Yes      | Requested budget in USDC                                |
| `purpose`  | string | Yes      | What this budget is for (shown to the reviewer)         |
| `category` | string | No       | Spend category (e.g., `API_PROVIDER`, `INFRASTRUCTURE`) |
| `metadata` | object | No       | Arbitrary context (JSON)                                |

**Response (201):**

```json theme={null}
{
  "budgetRequestId": "cmm59z...",
  "status": "PENDING",
  "requestedAmount": 50.0,
  "purpose": "Research 200 companies via StableEnrich and generate reports",
  "category": "API_PROVIDER",
  "createdAt": "2026-04-07T12:00:00.000Z"
}
```

**Error (409), active request already exists:**

```json theme={null}
{
  "error": "Agent already has an active budget request",
  "code": "BUDGET_REQUEST_EXISTS",
  "existingBudgetRequestId": "cmm58y..."
}
```

### Check Budget Request Status

```bash theme={null}
curl https://conto.finance/api/sdk/budget-request?status=APPROVED \
  -H "Authorization: Bearer $CONTO_API_KEY"
```

**Query Parameters:**

| Parameter | Type   | Required | Description                                                       |
| --------- | ------ | -------- | ----------------------------------------------------------------- |
| `id`      | string | No       | Specific budget request ID                                        |
| `status`  | string | No       | Filter: `PENDING`, `APPROVED`, `REJECTED`, `EXPIRED`, `EXHAUSTED` |

**Response (200):**

```json theme={null}
{
  "budgetRequests": [
    {
      "id": "cmm59z...",
      "status": "APPROVED",
      "requestedAmount": 50.0,
      "approvedAmount": 25.0,
      "currentSpend": 12.5,
      "remainingBudget": 12.5,
      "purpose": "Research 200 companies via StableEnrich and generate reports",
      "category": "API_PROVIDER",
      "expiresAt": "2026-04-08T12:00:00.000Z",
      "createdAt": "2026-04-07T12:00:00.000Z"
    }
  ]
}
```

## MCP Tools

### request\_budget

Request a spending budget for payments. Submits a request for human approval. Only one active budget request per agent at a time. Applies to all payment types.

| Parameter  | Type   | Required | Description                                             |
| ---------- | ------ | -------- | ------------------------------------------------------- |
| `amount`   | number | Yes      | Requested budget in USDC                                |
| `purpose`  | string | Yes      | What this budget is for (shown to reviewer)             |
| `category` | string | No       | Spend category (e.g., `API_PROVIDER`, `INFRASTRUCTURE`) |
| `metadata` | object | No       | Additional context                                      |

### get\_budget\_request

Check status and remaining balance of your budget requests. Use to poll for approval and monitor remaining budget.

| Parameter         | Type   | Required | Description                                                       |
| ----------------- | ------ | -------- | ----------------------------------------------------------------- |
| `budgetRequestId` | string | No       | Specific request ID                                               |
| `status`          | string | No       | Filter: `PENDING`, `APPROVED`, `REJECTED`, `EXPIRED`, `EXHAUSTED` |

## Payment Flow Integration

When an active (approved, non-expired) budget exists, every payment flow checks it automatically:

**Pre-execution (blocking):**

* `payments/request`: checks budget before policy evaluation
* `payments/approve`: checks budget for external wallet payments
* `x402/pre-authorize`: checks budget before authorizing x402 payments
* `mpp/pre-authorize`: checks budget before authorizing MPP payments

**Post-execution (decrement):**

* `payments/execute`: decrements budget after successful execution
* `x402/record`: decrements budget when recording x402 payments
* `mpp/record`: decrements budget when recording MPP payments

If a payment would exceed the remaining budget, it is denied with a `budgetRequest` object in the response:

```json theme={null}
{
  "authorized": false,
  "reasons": ["Payment of $30.00 exceeds remaining budget of $12.50"],
  "budgetRequest": {
    "id": "cmm59z...",
    "approvedAmount": 25.0,
    "currentSpend": 12.5,
    "remainingBudget": 12.5
  }
}
```

## Dashboard

Budget requests appear in the **Budgets** tab on the Alerts & Approvals page.

**Pending requests** show:

* Agent name, purpose, requested amount, category
* Approve / Reject buttons
* Optional amount adjustment field (approve a different amount than requested)

**Approved requests** show:

* Spend progress bar (currentSpend / approvedAmount)
* Remaining balance and expiry countdown
* Whether the amount was adjusted from the original request

**Completed requests** (rejected, expired, exhausted) show their final state.

### Approving a Request

```bash theme={null}
curl -X POST https://conto.finance/api/budget-requests/{id}/decide \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "APPROVED",
    "approvedAmount": 25.00,
    "expiresInHours": 48
  }'
```

| Parameter        | Type   | Required | Description                                    |
| ---------------- | ------ | -------- | ---------------------------------------------- |
| `decision`       | string | Yes      | `APPROVED` or `REJECTED`                       |
| `approvedAmount` | number | No       | Override amount (defaults to requested amount) |
| `expiresInHours` | number | No       | Budget window in hours (default: 24)           |
| `comment`        | string | No       | Optional note                                  |

## Audit Trail

Every state transition creates an audit log entry:

| Transition            | Action    | Actor  |
| --------------------- | --------- | ------ |
| Agent creates request | `CREATE`  | Agent  |
| Human approves        | `APPROVE` | User   |
| Human rejects         | `REJECT`  | User   |
| Spend recorded        | `UPDATE`  | Agent  |
| Budget exhausted      | `UPDATE`  | System |
| Budget expired        | `UPDATE`  | System |

## Example: Agent Workflow

```typescript theme={null}
// 1. Request a budget
const budget = await fetch('/api/sdk/budget-request', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: 50,
    purpose: 'Research 200 companies via paid APIs',
    category: 'API_PROVIDER',
  }),
}).then((r) => r.json());

console.log('Budget request:', budget.budgetRequestId); // PENDING

// 2. Poll for approval
let approved = false;
while (!approved) {
  const status = await fetch(`/api/sdk/budget-request?id=${budget.budgetRequestId}`, {
    headers: { Authorization: `Bearer ${apiKey}` },
  }).then((r) => r.json());

  const req = status.budgetRequests[0];
  if (req.status === 'APPROVED') {
    console.log(`Approved: $${req.approvedAmount} budget`);
    approved = true;
  } else if (req.status === 'REJECTED' || req.status === 'EXPIRED') {
    throw new Error(`Budget ${req.status}`);
  }

  await new Promise((r) => setTimeout(r, 5000));
}

// 3. Make payments normally, budget is enforced automatically
await conto.payments.pay({
  amount: 0.05,
  recipientAddress: '0x...',
  purpose: 'StableEnrich API call',
});
// Budget decremented: $49.95 remaining
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Payments" icon="credit-card" href="/sdk/payments">
    Standard payment request and execution
  </Card>

  <Card title="x402 Payments" icon="globe" href="/sdk/x402-payments">
    HTTP 402 micropayment handling
  </Card>

  <Card title="Spend Limits" icon="gauge" href="/policies/spend-limits">
    Configure wallet spend limits
  </Card>

  <Card title="MCP Tools" icon="wrench" href="/mcp/tools">
    Full MCP tools reference
  </Card>
</CardGroup>
