> ## 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.

# Bill for LLM inference

> Resell OpenAI, Anthropic, and Google models through one OpenAI-compatible URL — metered, marked up, and billed as Merchant of Record.

Ship an AI gateway without building the boring half. Point your customers at a single OpenAI-compatible URL, and Macropay sits in the request path to route to OpenAI, Anthropic, Google, or OpenRouter, count the tokens, enforce per-key budgets, and roll the spend onto an invoice — under your pricing, as Merchant of Record.

The proxy lives at `/ai/v1` and speaks the Chat Completions API verbatim. Your customers swap one `base_url`; everything else — metering, markup, rate limits, tax, and disputes — is handled for you.

<Note>
  Reselling inference is not the same as [metering your own AI app](/guides/ai-billing). In that guide, **you** call the model and report tokens after the fact. Here, **Macropay** sits on the wire — so budgets, allowlists, and usage events happen at the edge with zero metering code in your service.
</Note>

## Why route through the proxy

<CardGroup cols={2}>
  <Card title="One URL, every provider" icon="route">
    Customers learn one API. You fan out to `gpt-*`, `claude-*`, Gemini, or anything on OpenRouter — and swap providers behind the scenes without touching their code.
  </Card>

  <Card title="Markup you keep" icon="chart-line">
    Set a customer-facing price per million tokens. Your cost is the upstream rate; the spread is yours. Your provider key never leaves Macropay.
  </Card>

  <Card title="Hard budgets at the edge" icon="shield-halved">
    Cap a key at "\$50/month" and the proxy returns a clean `403` the instant spend plus reserved cost hits the ceiling — no surprise overages.
  </Card>

  <Card title="Billed as MoR" icon="receipt">
    Token charges roll into a subscription invoice. Macropay is the seller of record, remits sales tax and VAT worldwide, and absorbs disputes.
  </Card>
</CardGroup>

This fits AI gateways, agent platforms, and any product where customers consume models on your account and you want to bill them per token without writing a meter.

## Set it up

<Steps>
  <Step title="Define the models you'll resell">
    In the dashboard, open **Settings → AI Models** and add each model. Per model:

    * **Display name** — what customers pass in `model` (e.g. `nimbus-fast`)
    * **Upstream provider + model** — e.g. `openai` / `gpt-4o-mini`
    * **Input cost / 1M tokens** — your customer-facing input price
    * **Output cost / 1M tokens** — your customer-facing output price

    Macropay charges customers your configured rate and pays the upstream rate — the difference is your margin, calculated automatically.
  </Step>

  <Step title="Connect your upstream keys">
    On the same page, paste your OpenAI / Anthropic / Google / OpenRouter keys. They're encrypted at rest and only ever sent to the matching provider URL.
  </Step>

  <Step title="Mint a proxy key per customer">
    Create a **Proxy API Key** under **Settings → API Keys → New proxy key**. Optional guardrails:

    * **Allowed models** — scope the key to a slice of your catalog.
    * **Rate limit (RPM)** — requests-per-minute cap.
    * **Budget limit (cents)** — hard per-period ceiling; the proxy returns `403 Budget limit exceeded` once spent plus reserved hits it.
    * **Customer link** — attach a Macropay customer so usage rolls up to their invoice.
  </Step>

  <Step title="Hand the key over">
    The customer sets the key and points `base_url` at Macropay. That's the entire integration on their end.
  </Step>
</Steps>

## The endpoint

```
https://app.macropay.ai/ai/v1/chat/completions
```

Fully OpenAI-compatible: send the exact body you'd send to `https://api.openai.com/v1/chat/completions`. The `model` field picks which of your configured models to route to — and which provider it lands on.

<CodeGroup>
  ```bash curl theme={null}
  curl https://app.macropay.ai/ai/v1/chat/completions \
    -H "Authorization: Bearer macropay_proxy_..." \
    -H "Content-Type: application/json" \
    -d '{
      "model": "nimbus-fast",
      "messages": [{"role": "user", "content": "Summarize this support ticket in one line."}]
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="macropay_proxy_...",
      base_url="https://app.macropay.ai/ai/v1",
  )

  response = client.chat.completions.create(
      model="nimbus-fast",
      messages=[{"role": "user", "content": "Summarize this support ticket in one line."}],
  )
  print(response.choices[0].message.content)
  ```

  ```ts TypeScript theme={null}
  import OpenAI from 'openai'

  const client = new OpenAI({
    apiKey: 'macropay_proxy_...',
    baseURL: 'https://app.macropay.ai/ai/v1',
  })

  const response = await client.chat.completions.create({
    model: 'nimbus-fast',
    messages: [{ role: 'user', content: 'Summarize this support ticket in one line.' }],
  })
  ```
</CodeGroup>

### Streaming

Pass `stream: true` and Macropay returns Server-Sent Events in OpenAI delta format — no matter which upstream provider answers. The official SDKs consume it natively.

```python theme={null}
stream = client.chat.completions.create(
    model="nimbus-fast",
    messages=[{"role": "user", "content": "Draft a release note for v2.1."}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
```

## Provider coverage

Every response and stream is normalized into the OpenAI Chat Completions shape, so customers write one client and you keep full freedom over routing.

| Provider       | Models exposed                                        | Streaming                       |
| -------------- | ----------------------------------------------------- | ------------------------------- |
| **OpenAI**     | Any `gpt-*` your account can reach                    | Pass-through                    |
| **Anthropic**  | `claude-*` — Opus, Sonnet, Haiku, and more            | Translated to OpenAI SSE format |
| **Google**     | Gemini family via `generativelanguage.googleapis.com` | Pass-through                    |
| **OpenRouter** | Anything OpenRouter exposes                           | Pass-through                    |

## Real-time usage headers

Successful responses carry per-request usage and budget headers, so a customer dashboard can show live spend without a second API call.

| Header                      | Meaning                                      |
| --------------------------- | -------------------------------------------- |
| `X-Usage-Prompt-Tokens`     | Input tokens consumed                        |
| `X-Usage-Completion-Tokens` | Output tokens generated                      |
| `X-Usage-Total-Tokens`      | Sum of the above                             |
| `X-Budget-Used-Cents`       | Cents spent against this key's budget so far |
| `X-Budget-Limit-Cents`      | Configured budget ceiling, if any            |
| `X-Budget-Remaining-Pct`    | Percent of budget still available            |
| `X-Budget-Warning`          | Present once usage crosses 80% of the budget |

## From tokens to invoice

Every call writes a usage event tagged to the customer (when the proxy key is customer-linked). Those tokens roll up exactly like any [usage-based meter](/features/usage-based-billing/introduction), so the same invoicing, dunning, and reverse-invoice tooling applies. Pick the billing shape that fits your product:

<Tabs>
  <Tab title="Mark up tokens">
    Bill `output_cost_per_million × tokens` per request, accumulated and invoiced monthly. Best for postpaid customers on a subscription — they pay for what they used, you keep the spread.
  </Tab>

  <Tab title="Sell credit packs">
    Front-load credits with a one-time product. The proxy returns `402 Insufficient credits` the moment a customer's balance hits zero, prompting a top-up. Best for prepaid, self-serve usage.
  </Tab>
</Tabs>

<Tip>
  Because this runs on Macropay's meter and product engine, you get the agentic-billing primitives for free: track AI cost as COGS per customer, and pair token spend with **outcome** signals so you can bill — and prove ROI — on results, not just raw usage.
</Tip>

## Guardrails

The proxy enforces limits before a request ever reaches an upstream provider:

| Safeguard              | Behavior                                                                                                                                              | Response                                               |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| **Rate limit**         | Per-key RPM cap, enforced atomically in Redis                                                                                                         | `429 Rate limit exceeded`                              |
| **Budget reservation** | Each request reserves an estimate from the model's output cost-per-million, so concurrent in-flight calls can't race past the ceiling (no TOCTOU gap) | `403 Budget limit exceeded`                            |
| **Model allowlist**    | Per-key catalog restriction                                                                                                                           | `403` on a disallowed model                            |
| **Credit balance**     | For customer-linked keys on credit-pack meters                                                                                                        | `402 Insufficient credits` at zero balance             |
| **Upstream errors**    | Provider 5xx is surfaced cleanly so clients can retry                                                                                                 | `502` with `{ "error": { "type": "upstream_error" } }` |

## FAQ

<AccordionGroup>
  <Accordion title="Can customers ever see my upstream API key?">
    No. Your OpenAI / Anthropic / Google keys are encrypted at rest and only ever sent to the matching provider URL by Macropay. Customers only hold their own proxy key.
  </Accordion>

  <Accordion title="Can I rotate an upstream key without breaking customers?">
    Yes. Update it under **Settings → AI Models** and the next request picks it up. Customer proxy keys are untouched.
  </Accordion>

  <Accordion title="What happens when a provider goes down?">
    The proxy returns `502 upstream_error` with the upstream status embedded, so standard SDK retry logic handles transient failures.
  </Accordion>

  <Accordion title="How does this interact with Macropay fees?">
    The inference markup you charge flows through Macropay like any other transaction and is subject to standard Merchant-of-Record fees. See [fees](/merchant-of-record/fees) for the breakdown.
  </Accordion>
</AccordionGroup>
