Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

AAU Billing

What is an AAU?

An Agentic Activity Unit (AAU) is a dimensionless measure of the governance cost of a single LLM tool call. Not every tool call carries equal risk or infrastructure cost — a read-only SELECT against a governed schema deserves a lighter weight than a cross-system data mutation or an admin-level operation. AAU gives operators one number they can reason about, rate-limit, and eventually price.

Weight table

Intent categoryExample operationsAAU weight
Readread_select
Writewrite_insert, write_update, write_delete
Governedadmin, cross-system transactions

The weight is resolved from the intent context key that the SCHEMABOUND middleware attaches to every LlmToolCallAuditRecorded event. When no explicit intent is present the weight is heuristically derived from the tool/function name (see aau_weight_from_tool_name in services/backend/src/billing.rs).


How an AAU is recorded

LLM agent
  └─▶ gRPC tool call  (e.g. execute_query / insert_record)
        └─▶ schemabound interceptor middleware
              └─▶ EventBus::publish(LlmToolCallAuditRecorded { tool_name, context })
                    └─▶ BillingMeterRecorder::handle()
                          └─▶ tokio::spawn  ──▶  INSERT INTO usage_events
  1. Event source — Every tool invocation that passes through the SCHEMABOUND gRPC server emits a LlmToolCallAuditRecorded event on the global EventBus. The event carries tool_name plus a context map that includes org_id, session_id, orm_model, and intent.

  2. HandlerBillingMeterRecorder (registered in src/grpc.rs) subscribes to the bus. Its handle method is synchronous and non-blocking; the actual database write is dispatched as a fire-and-forget tokio::spawn task so the gRPC hot path is never stalled.

  3. Storage — Each event becomes one row in the usage_events table:

    ColumnTypeNotes
    idVARCHAR(36)UUIDv4
    org_idVARCHAR(36)From request context
    session_idVARCHAR(255)Optional — agent session
    tool_nameVARCHAR(255)Raw gRPC/MCP tool name
    intentVARCHAR(64)read_select / write_* / admin
    aau_weightDOUBLE1.0 / 3.0 / 5.0
    orm_modelVARCHAR(64)ORM model name, if known
    cost_usdDOUBLEReserved for future pricing; currently 0.0
    created_atTIMESTAMPServer timestamp

REST API

All billing endpoints require the caller to be authorised as billing admin (see Authorization below).

GET /billing/usage

Returns daily AAU totals for the authenticated organisation.

Query parameters

ParameterFormatDefault
fromYYYY-MM-DD1970-01-01 (all-time)
toYYYY-MM-DD9999-12-31 (all-time)

Response

{
  "data": [
    {
      "date": "2026-04-30",
      "action_count": 42,
      "total_aau": 87.0,
      "total_cost_usd": 0.0
    }
  ]
}

GET /billing/usage/heatmap

Returns AAU totals grouped by ORM model × intent — the matrix consumed by the D3 heat map on the AAU Dashboard.

Response

{
  "data": [
    {
      "orm_model": "Person",
      "intent": "write_insert",
      "aau_weight": 3.0,
      "total_aau": 9.0,
      "action_count": 3
    }
  ]
}

POST /billing/setup-intent

Creates a Stripe SetupIntent so the frontend can securely collect card details. Requires STRIPE_SECRET_KEY in the server environment.

Request body

{ "customer_id": "cus_abc123" }

Response — returns id, client_secret, and customer from Stripe.


GET /billing/payment-methods

Lists saved Stripe payment methods for the authenticated admin session.


DELETE /billing/payment-methods/<pm_id>

Detaches a Stripe payment method by its pm_… identifier.


Authorization

Billing endpoints are protected by the BillingAdmin request guard. A request is accepted when either condition is true:

  • X-User-Role header equals admin (case-insensitive), or
  • X-User-Permissions header contains manage:billing (comma-separated list).

Requests that satisfy neither condition receive 403 Forbidden.


AAU Dashboard

The AAU Dashboard (/aau-dashboard) in the frontend provides a live view of billing activity:

  • Agentic Activity Heat Map — a D3-rendered matrix of ORM model × intent weight category. Cell colour intensity reflects the cumulative AAU total so operators can immediately spot which models and intent types are driving the most governance cost.
  • Daily Usage Table — a chronological breakdown of action_count, total_aau, and total_cost_usd per day.
  • Billing Panel — Stripe card management (add/remove payment methods) wired to the setup-intent and payment-method endpoints above.

Navigate to the dashboard via the AAU Dashboard link in the top navigation bar. The frontend sends X-User-Role: admin and X-User-Permissions: manage:billing automatically for the demo environment.


Extending pricing

The cost_usd column is reserved for future use. To enable per-unit pricing:

  1. Define a pricing schedule (e.g. $0.001 per AAU).
  2. Populate cost_usd inside BillingMeterRecorder::handle before the INSERT.
  3. Surface the total in the Daily Usage Table — the total_cost_usd field is already returned by GET /billing/usage.