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

# Set up agent billing

> Bill an AI agent end to end: create it, pick a billing model, meter token and tool cost, then read live margin and a certified ROI receipt.

Agent billing in Macropay means metering everything an AI agent costs and earns — LLM tokens, tool calls, and the actions or outcomes you charge for — then reading the result as live margin and a certified value receipt. This guide wires it up end to end with copy-paste `curl` for every step.

By the end you'll have an agent that:

* **Charges** on usage, activity, or outcomes — whichever fits your product.
* **Captures cost** automatically (tokens via the AI gateway) and explicitly (tools, APIs, human review).
* **Reports** per-agent margin and an ROI value receipt in the dashboard.

## Before you start

You'll need:

* A [Macropay account](https://macropay.ai/signup) with an organization.
* An **Organization Access Token** for API calls. Send it as `Authorization: Bearer <token>` on every request.
* A model provider key if you'll route LLM calls through the gateway.

<Info>
  Build against the Sandbox first. It mirrors production but never moves real
  money, so you can replay signals and cost events freely while you tune pricing.
</Info>

## Set the base URL

All examples use the production API base. Export your token once so the snippets run as-is:

```bash theme={null}
export MACROPAY_TOKEN="<your-organization-access-token>"
export MACROPAY_API="https://api.macropay.ai"
```

<Steps>
  <Step title="Create an agent">
    An agent is the unit cost and revenue attach to. Create one with `POST /v1/agents`. Use `external_id` to map it to the agent in your own system (idempotent reference), and `parent_agent_id` if it's a sub-agent in a larger workflow.

    ```bash theme={null}
    curl -X POST "$MACROPAY_API/v1/agents/" \
      -H "Authorization: Bearer $MACROPAY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "support-copilot",
        "external_id": "agent_support_v3",
        "description": "Resolves tier-1 support tickets"
      }'
    ```

    The response includes the agent `id` (a UUID). Save it — every later call uses it:

    ```bash theme={null}
    export AGENT_ID="<id-from-response>"
    ```
  </Step>

  <Step title="Choose a billing model">
    Pick how the agent earns. The three models compose — many agents use more than one.

    | Model        | Charge on                                                       | How to wire it                                                                               |
    | ------------ | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
    | **Usage**    | LLM tokens consumed                                             | Route calls through the AI gateway (Step 3a). Meter the token event, attach a metered price. |
    | **Activity** | Each action taken (e.g. `message_sent`)                         | Post `activity` signals (Step 3b), bill off a signal meter.                                  |
    | **Outcome**  | Each billable result (e.g. `meeting_booked`, `ticket_resolved`) | Post `outcome` signals (Step 3b), bill off a signal meter.                                   |

    For activity or outcome billing, provision a signal-scoped meter in one call. Pair the returned meter with a `metered_unit` price on a [product](/features/products) to charge per action or per result.

    ```bash theme={null}
    curl -X POST "$MACROPAY_API/v1/agents/billing-models" \
      -H "Authorization: Bearer $MACROPAY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "meetings-booked",
        "kind": "outcome",
        "agent_id": "'"$AGENT_ID"'",
        "signal_name": "meeting_booked"
      }'
    ```

    <Note>
      Omit `signal_name` to count every signal of that `kind` for the agent. Set it
      to bill on one specific signal. Usage (token) billing needs no billing model
      here — it uses a standard token meter (Step 3a).
    </Note>
  </Step>

  <Step title="Instrument cost and revenue">
    Two instrumentation paths feed the agent. Use either or both.

    <Tabs>
      <Tab title="a. Token cost via the AI gateway">
        Point your LLM calls at the Macropay AI gateway (`/ai/v1`) instead of the provider directly. It's OpenAI-compatible: swap the base URL and use your Macropay key. Every call's token usage and upstream cost is captured and attributed to the agent automatically — no manual event payloads.

        ```bash theme={null}
        curl -X POST "$MACROPAY_API/ai/v1/chat/completions" \
          -H "Authorization: Bearer $MACROPAY_TOKEN" \
          -H "Content-Type: application/json" \
          -H "X-Macropay-Agent-Id: $AGENT_ID" \
          -d '{
            "model": "gpt-4o",
            "messages": [{"role": "user", "content": "Summarize ticket #4821"}]
          }'
        ```

        The gateway records token cost as the agent's COGS, so it shows up in margin without any extra call. See [LLM inference](/features/llm-inference) for the full gateway reference.
      </Tab>

      <Tab title="b. Activity / outcome signals">
        Post business signals to `POST /v1/signals` — an action the agent took (`activity`) or a billable result it produced (`outcome`). Each signal must carry a `customer_id` or `external_customer_id` so billing can attribute it. For outcomes, always send a unique `external_id`: it dedupes so you're billed once per result.

        ```bash theme={null}
        curl -X POST "$MACROPAY_API/v1/signals/" \
          -H "Authorization: Bearer $MACROPAY_TOKEN" \
          -H "Content-Type: application/json" \
          -d '{
            "signals": [{
              "event_name": "meeting_booked",
              "kind": "outcome",
              "agent_id": "'"$AGENT_ID"'",
              "external_customer_id": "cust_8842",
              "external_id": "meeting_2026_06_03_001",
              "data": { "value": 1, "calendar": "sales" }
            }]
          }'
        ```

        The `data` object is arbitrary metadata stored on the event — useful for value, units, or quality fields you later report on.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Record non-LLM costs">
    Tokens aren't the only cost. Tool calls, third-party APIs, and human-in-the-loop review all eat margin. Record each as COGS with `POST /v1/agents/{id}/costs`. The amount is in cents and folds into the agent's margin as cost (it adds no revenue). Pass an `external_id` as an idempotency key so retries don't double-count.

    ```bash theme={null}
    curl -X POST "$MACROPAY_API/v1/agents/$AGENT_ID/costs" \
      -H "Authorization: Bearer $MACROPAY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "amount_cents": 4.2,
        "currency": "usd",
        "description": "serp_api",
        "external_customer_id": "cust_8842",
        "external_id": "toolcall_91af"
      }'
    ```

    A `201` with `{ "status": "recorded" }` confirms the cost landed.
  </Step>

  <Step title="Read margin and the value receipt">
    With cost and revenue flowing, two read endpoints close the loop. Both accept optional `since` / `until` query params to scope a period.

    **Margin** — billed revenue vs. AI cost (COGS) for the agent, including a per-model breakdown and a `low_margin` flag when you dip below the floor:

    ```bash theme={null}
    curl "$MACROPAY_API/v1/agents/$AGENT_ID/margin" \
      -H "Authorization: Bearer $MACROPAY_TOKEN"
    ```

    ```json theme={null}
    {
      "agent_id": "…",
      "revenue_cents": 12000.0,
      "cost_cents": 3140.0,
      "margin_cents": 8860.0,
      "margin_pct": 73.8,
      "low_margin": false,
      "margin_floor_pct": 20.0,
      "by_model": [
        { "model": "gpt-4o", "revenue_cents": 12000.0, "cost_cents": 2980.0, "margin_cents": 9020.0, "margin_pct": 75.2, "count": 412 }
      ]
    }
    ```

    **Value receipt** — a certified ROI statement (time saved, cost savings, revenue generated, risk avoided, and total value), split into verified vs. unverified outcome value. Override the ROI assumptions inline, or let it use the agent's stored `roi_assumptions`:

    ```bash theme={null}
    curl "$MACROPAY_API/v1/agents/$AGENT_ID/value-receipt?minutes_per_action=8&hourly_rate_cents=6000" \
      -H "Authorization: Bearer $MACROPAY_TOKEN"
    ```

    Both surfaces render in the dashboard **Agents** page: open an agent to see its live margin chart and value receipt, no API call required.
  </Step>
</Steps>

## Where this shows up in the dashboard

The **Agents** page lists every agent with its current margin and status. Open one to see the margin breakdown by model, the value receipt for the period, and the cost vs. revenue trend. [Cost Insights](/features/cost-insights/introduction) rolls the same numbers up across all agents so you can spot the workflow quietly running you into the red.

## FAQ

**Can one agent use more than one billing model?**

Yes. Usage, activity, and outcome billing compose freely. A copilot can bill tokens on a metered price while also charging per resolved ticket as an outcome — both attribute to the same agent and roll into one margin number.

**Do I have to route LLM calls through the gateway?**

Only if you want automatic token-cost capture. If you call your provider directly, record the spend yourself with `POST /v1/agents/{id}/costs` so it still counts toward margin. The gateway just removes that manual step.

**Why does my signal get rejected?**

Every signal needs a `customer_id` or `external_customer_id` — billing can't attribute a charge without a customer. Outcomes also need a unique `external_id`; it's how Macropay dedupes so you bill once per result.

**What's the difference between margin and the value receipt?**

Margin is your economics: billed revenue minus AI cost. The value receipt is your customer's economics: the human-equivalent value the agent delivered (time saved, cost avoided, revenue generated, risk avoided), which you can show to justify what you charge.

**How do I keep cost records from double-counting on retries?**

Send an `external_id` on each cost. Macropay dedupes on `(organization, external_id)`, so replaying the same call is a no-op.

## Where to go next

<CardGroup cols={2}>
  <Card title="Agents overview" icon="robot" href="/features/agents/introduction">
    The full model behind agents, signals, margin, and value receipts.
  </Card>

  <Card title="AI / LLM billing" icon="microchip" href="/guides/ai-billing">
    Meter tokens and attach a metered price for usage-based charging.
  </Card>

  <Card title="LLM inference gateway" icon="plug" href="/features/llm-inference">
    The OpenAI-compatible gateway that captures token cost per agent.
  </Card>

  <Card title="Cost insights" icon="chart-line" href="/features/cost-insights/introduction">
    Upstream model spend and per-agent margin, rolled up.
  </Card>

  <Card title="Usage-based billing" icon="chart-bar" href="/features/usage-based-billing/introduction">
    Meters, events, and aggregation in depth.
  </Card>

  <Card title="AI agents for SaaS" icon="layer-group" href="/use-cases/ai-saas">
    Patterns for shipping and pricing autonomous agents.
  </Card>
</CardGroup>
