---
title: "Agent Cloud Billing"
description: "Per-agent, per-customer metering across six resource types with credit-based cost calculation and budget management"
canonical: "https://docs.ainative.studio/docs/agent-cloud/billing"
last-updated: "2026-10-13T21:42:35.442Z"
---

# Agent Cloud Billing

Source: https://docs.ainative.studio/docs/agent-cloud/billing

> Per-agent, per-customer metering across six resource types with credit-based cost calculation and budget management

Billing service for cloud agent resource consumption. Extends the EndpointCredits credit system with per-agent, per-customer metering across six resource types.

Refs #1981, #1983

---

## Overview

Agent Cloud Billing tracks every resource an agent consumes on behalf of a customer. Each usage event is recorded in the `agent_resource_usage` table with a calculated credit cost. Credits are deducted from the customer's balance in `credit_transactions`.

```
Agent performs work
        |
        v
  record_usage() called with resource_type + quantity
        |
        v
  Credit cost calculated (quantity * credits_per_unit)
        |
        v
  AgentResourceUsage row inserted
        |
        v
  deduct_credits() removes credits from customer balance
```

---

## Resource Types and Pricing

Six resource types are metered. Each has a fixed credit-per-unit rate.

| Resource Type   | Credits per Unit | Unit        | Description                                |
|-----------------|-----------------|-------------|--------------------------------------------|
| `compute`       | 2               | seconds     | Agent CPU execution time                   |
| `memory_ops`    | 5               | operations  | ZeroMemory read/write operations           |
| `vector_search` | 8               | queries     | Vector similarity search queries           |
| `storage`       | 0.001           | bytes       | Object/file storage consumption            |
| `a2a`           | 3               | messages    | Agent-to-agent communication messages      |
| `postgresql`    | 20              | queries     | Dedicated PostgreSQL queries               |

### Cost Examples

| Operation                        | Quantity | Calculation       | Credit Cost |
|----------------------------------|----------|-------------------|-------------|
| 60 seconds of compute           | 60       | 60 * 2            | 120.000     |
| 10 memory operations            | 10       | 10 * 5            | 50.000      |
| 5 vector searches               | 5        | 5 * 8             | 40.000      |
| 1 MB storage (1,048,576 bytes)  | 1048576  | 1048576 * 0.001   | 1048.576    |
| 25 agent-to-agent messages      | 25       | 25 * 3            | 75.000      |
| 3 PostgreSQL queries            | 3        | 3 * 20            | 60.000      |

All credit costs are calculated as `Decimal` values and quantized to 3 decimal places.

---

## AgentResourceUsage Model

The `agent_resource_usage` table stores every metered event.

| Column        | Type          | Description                                    |
|---------------|---------------|------------------------------------------------|
| id            | UUID          | Primary key                                    |
| agent_id      | VARCHAR(255)  | Agent identifier (indexed)                     |
| customer_id   | UUID          | Foreign key to `users.id` (indexed)            |
| resource_type | VARCHAR(32)   | One of the six resource types                  |
| quantity      | NUMERIC       | Amount of resource consumed                    |
| unit          | VARCHAR(32)   | Unit of measurement (seconds, operations, etc.)|
| credit_cost   | NUMERIC       | Calculated credit cost for this usage          |
| period_start  | DATETIME      | Start of the metering period                   |
| period_end    | DATETIME      | End of the metering period                     |
| metadata      | JSON          | Optional additional context                    |
| created_at    | DATETIME      | Record creation timestamp                      |

---

## Service API

### AgentCloudBillingService

Instantiated with a SQLAlchemy `Session`. All methods operate within the caller's transaction.

```python
from app.services.agent_cloud_billing_service import AgentCloudBillingService

service = AgentCloudBillingService(db=session)
```

### calculate_credit_cost(resource_type, quantity)

Calculate the credit cost for a given resource type and quantity without recording usage.

**Parameters:**
- `resource_type` (str) -- One of: `compute`, `memory_ops`, `vector_search`, `storage`, `a2a`, `postgresql`
- `quantity` (Decimal) -- Amount of resource consumed

**Returns:** `Decimal` -- credit cost quantized to 3 decimal places

**Raises:** `ValueError` if the resource type is unknown

```python
cost = service.calculate_credit_cost("vector_search", Decimal("15"))
## cost = Decimal("120.000")
```

### record_usage(agent_id, customer_id, resource_type, quantity, period_start, period_end, metadata=None)

Record a resource usage event and calculate its credit cost. Inserts a row into `agent_resource_usage` and flushes (but does not commit -- the caller controls the transaction).

**Parameters:**
- `agent_id` (str) -- Agent identifier
- `customer_id` (str) -- Customer UUID as string
- `resource_type` (str) -- One of the six valid resource types
- `quantity` (float) -- Amount consumed (must be positive)
- `period_start` (datetime) -- Start of metering period
- `period_end` (datetime) -- End of metering period (must be after start)
- `metadata` (dict, optional) -- Additional context

**Returns:** Dictionary with the recorded usage details:

```json
{
  "id": "uuid-string",
  "agent_id": "aurora",
  "customer_id": "customer-uuid",
  "resource_type": "compute",
  "quantity": 120.0,
  "unit": "seconds",
  "credit_cost": 240.0,
  "period_start": "2026-06-01T00:00:00",
  "period_end": "2026-06-01T01:00:00"
}
```

**Raises:**
- `ValueError` if resource_type is unknown
- `ValueError` if period_end is not after period_start
- `ValueError` if quantity is not positive

### deduct_credits(customer_id, credits, description)

Deduct credits from a customer's balance via the `credit_transactions` table. Checks the current balance before deducting and returns `False` if insufficient.

**Parameters:**
- `customer_id` (str) -- Customer UUID as string
- `credits` (float) -- Number of credits to deduct (positive value)
- `description` (str) -- Reason for the deduction

**Returns:** `True` if deduction succeeded, `False` if insufficient balance

**Raises:** `ValueError` if credits is not positive

```python
success = service.deduct_credits(
    customer_id="customer-uuid",
    credits=240.0,
    description="Agent aurora compute: 120s execution"
)
```

### get_agent_usage_summary(agent_id, period_start, period_end)

Retrieve aggregated usage for a specific agent over a time period, grouped by resource type.

**Parameters:**
- `agent_id` (str) -- Agent identifier
- `period_start` (datetime) -- Start of query period
- `period_end` (datetime) -- End of query period

**Returns:**

```json
{
  "agent_id": "aurora",
  "period_start": "2026-06-01T00:00:00",
  "period_end": "2026-06-01T23:59:59",
  "total_credit_cost": 510.0,
  "total_records": 42,
  "by_resource_type": {
    "compute": {
      "total_quantity": 300.0,
      "total_credit_cost": 600.0,
      "unit": "seconds",
      "record_count": 15
    },
    "vector_search": {
      "total_quantity": 50.0,
      "total_credit_cost": 400.0,
      "unit": "queries",
      "record_count": 12
    }
  }
}
```

### get_customer_cloud_spend(customer_id, period_start, period_end)

Retrieve total cloud spend for a customer across all agents, grouped by agent and resource type.

**Parameters:**
- `customer_id` (str) -- Customer UUID as string
- `period_start` (datetime) -- Start of query period
- `period_end` (datetime) -- End of query period

**Returns:**

```json
{
  "customer_id": "customer-uuid",
  "period_start": "2026-06-01T00:00:00",
  "period_end": "2026-06-30T23:59:59",
  "total_credit_cost": 1250.0,
  "total_records": 87,
  "by_agent": {
    "aurora": {
      "total_credit_cost": 800.0,
      "record_count": 52,
      "by_resource_type": {
        "compute": {
          "total_quantity": 200.0,
          "total_credit_cost": 400.0,
          "unit": "seconds",
          "record_count": 20
        }
      }
    },
    "sage": {
      "total_credit_cost": 450.0,
      "record_count": 35,
      "by_resource_type": {}
    }
  }
}
```

---

## Budget Alerts and Cost Management

### Monitoring Spend

Use `get_customer_cloud_spend` to monitor a customer's total spend across all agents. Compare against budget thresholds to trigger alerts:

```python
spend = service.get_customer_cloud_spend(
    customer_id="customer-uuid",
    period_start=month_start,
    period_end=month_end,
)

if spend["total_credit_cost"] > budget_threshold:
    # Trigger budget alert notification
    pass
```

### Pre-flight Balance Checks

Before executing expensive operations, check whether the customer has sufficient credits:

```python
estimated_cost = service.calculate_credit_cost("postgresql", Decimal("10"))
## Check balance before proceeding
can_deduct = service.deduct_credits(
    customer_id="customer-uuid",
    credits=float(estimated_cost),
    description="Agent sage: 10 PostgreSQL queries"
)
if not can_deduct:
    # Reject the operation or notify the customer
    pass
```

### Per-Agent Cost Attribution

Use `get_agent_usage_summary` to attribute costs to individual agents. This enables:

- Identifying which agents consume the most resources
- Optimizing expensive agents (e.g., reducing unnecessary vector searches)
- Billing breakdowns for customers running multiple agents

---

## Data Lake Integration

Agent resource usage is exported to the data lake as the `platform/agent_resource_usage` partition. This enables historical analysis and trend detection via the lake query endpoint:

```sql
SELECT agent_id, resource_type, SUM(credit_cost) as total_cost
FROM platform_agent_resource_usage
GROUP BY agent_id, resource_type
ORDER BY total_cost DESC
```

See `docs/api/DATA_LAKE_API.md` for lake query details.

---

## Pydantic Schemas

### AgentResourceUsageCreate

Request schema for creating a usage record.

| Field         | Type     | Required | Constraints                |
|---------------|----------|----------|----------------------------|
| agent_id      | str      | yes      | 1-255 chars                |
| customer_id   | UUID     | yes      |                            |
| resource_type | enum     | yes      | One of the 6 resource types|
| quantity      | Decimal  | yes      | Must be > 0               |
| unit          | enum     | yes      | Matching unit for type     |
| credit_cost   | Decimal  | yes      | Must be >= 0              |
| period_start  | datetime | yes      |                            |
| period_end    | datetime | yes      | Must be after period_start |
| metadata      | dict     | no       | Default: empty dict        |

### AgentResourceUsageResponse

Response schema returned by API endpoints.

Includes all fields from `AgentResourceUsageCreate` plus:

| Field      | Type     | Description          |
|------------|----------|----------------------|
| id         | UUID     | Record primary key   |
| created_at | datetime | Creation timestamp   |

### AgentResourceUsageSummary

Aggregated summary schema.

| Field            | Type     | Description                 |
|------------------|----------|-----------------------------|
| agent_id         | str      | Agent identifier            |
| resource_type    | enum     | Resource type               |
| total_quantity   | Decimal  | Sum of quantity             |
| total_credit_cost| Decimal  | Sum of credit cost          |
| unit             | enum     | Unit of measurement         |
| period_start     | datetime | Summary period start        |
| period_end       | datetime | Summary period end          |
| record_count     | int      | Number of usage records     |

---

## Spending Caps (Budgets)

Separate from credit metering and x402 wallets, agents can have a **USD-denominated spending
cap** that gates real-time operations — including A2A messages (`POST /cloud/a2a/{agent_id}/message`
and `POST /cloud/a2a/route`). If an agent's budget is exceeded, the operation is blocked with
`402 Payment Required` **before** the operation executes, not after.

This is the mechanism to understand if you're building agents that call `/cloud/a2a/*` and get
an unexpected 402 — a budget gate is almost certainly why, not a credit-balance issue.

**Base path:** `/api/v1/billing`

### POST /budgets

Create a spending cap for an agent.

```json
{
  "agent_id": "agent-uuid",
  "limit_usd": 50.00,
  "period": "month",
  "max_task_cost_usd": 2.00,
  "auto_pause": true
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `agent_id` | string | yes | Agent this budget applies to |
| `limit_usd` | float | yes | Total spend allowed per period (> 0, ≤ 1,000,000) |
| `period` | string | yes | `day`, `week`, or `month` |
| `max_task_cost_usd` | float | no | Reject any single operation costing more than this |
| `auto_pause` | bool | no (default `false`) | Automatically pause the agent when the period limit is hit |

**Response (201 Created):** a `BudgetItem` — same fields plus `id`, `current_spend_usd` (starts
at 0), `created_at`, `updated_at`.

### GET /budgets

List budgets, optionally filtered by `agent_id` query param.

### How the gate works

Every budgeted operation checks two things, in order:
1. **Per-task cap**: if `max_task_cost_usd` is set and this operation's estimated cost exceeds it,
   reject immediately regardless of remaining period budget.
2. **Period cap**: if `current_spend_usd + estimated_cost > limit_usd`, reject. If `auto_pause`
   is enabled, the agent is also paused (its registration is suspended) so subsequent calls fail
   fast instead of repeatedly hitting the same budget check.

An agent with no budget row at all has **no spending cap** — budgets are opt-in, not a default
restriction.

## Agent Wallets (x402)

In addition to credit-based billing, agents can hold USDC wallets for x402 micropayments. Wallets provide per-agent spending isolation with configurable limits. Refs #5008

### Wallet Spending Guards

Each wallet enforces three layers of protection:

| Guard | Default | Description |
|-------|---------|-------------|
| Single payment cap | $10.00 | Maximum amount per individual transaction |
| Period spending limit | $100.00/month | Maximum total spend per billing period |
| Balance check | — | Transaction rejected if wallet balance insufficient |

### Wallet Endpoints

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/v1/cloud/x402/wallets` | Create per-agent wallet |
| `GET` | `/api/v1/cloud/x402/wallets/{agent_id}` | Get wallet balance and limits |
| `POST` | `/api/v1/cloud/x402/wallets/{agent_id}/fund` | Add funds to wallet |
| `POST` | `/api/v1/cloud/x402/wallets/{agent_id}/withdraw` | Withdraw from wallet |
| `PUT` | `/api/v1/cloud/x402/wallets/{agent_id}/limits` | Update spending limits |
| `GET` | `/api/v1/cloud/x402/wallets/{agent_id}/transactions` | Transaction history |

### Integration with Credit Billing

There are three independent billing/spend systems, each covering a different concern:

- **Credits** (`AgentCloudBillingService`) meter platform resource consumption (compute, vectors,
  storage, etc.) and deduct from the customer's credit balance.
- **Budgets** (`/billing/budgets`, above) are a real-time USD spending cap that gates operations
  like A2A messages before they execute — independent of credit balance.
- **Wallets** hold USDC for tool marketplace payments via x402.

An agent can consume platform credits for infrastructure, be gated by a USD budget cap on A2A
traffic, AND spend USDC for external tool calls — all at once, as separate concerns. Use
`get_customer_cloud_spend` for credit costs, `GET /billing/budgets` for spending-cap status, and
the wallet transaction history for x402 payment costs.

Full wallet API documentation: [Agent402 API — Agent Wallets](/docs/web3/agent402#agent-wallets-usdc)

---

## Key Source Files

| File | Purpose |
|------|---------|
| `src/backend/app/services/agent_cloud_billing_service.py` | Core billing service with pricing and metering |
| `src/backend/app/models/agent_resource_usage.py` | SQLAlchemy model for `agent_resource_usage` table |
| `src/backend/app/schemas/agent_resource_usage.py` | Pydantic schemas (ResourceType, ResourceUnit, Create/Response/Summary) |
| `src/backend/app/services/agent_wallet_service.py` | Per-agent USDC wallet service with spending guards |
| `src/backend/app/services/x402_revenue_share_service.py` | Marketplace 90/5/5 revenue split service |
