Per-customer budgets
Bind each request to one of your customers, gate each customer with a budget, and see what each one costs you against what they pay.
If you sell an AI product, one heavy customer can cost more than they pay. This guide sets up three things: every request is bound to the customer it serves, each customer is gated by a budget checked before the provider is called, and each customer's margin is visible.
Hand this to your developer: step 1 needs the Cova-Customer-Id header on
every request. See Tag your traffic and the
OpenAI or Anthropic
quickstart. Steps 2 and 3 are done in the console.
1. Bind requests to customers
Send the customer's ID with every request in the Cova-Customer-Id header. Use
the ID your own system already has.
client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
extra_headers={"Cova-Customer-Id": customer.id},
)IDs are matched without regard to case, and blank values are ignored.
Make the binding hard to get wrong
The header is whatever your code sends. To stop a key from charging the wrong customer, scope it: on Governance → Keys, click Scopes on the key and add the customers it may act for.
| Key scoped to | Request without the header | Request naming another customer |
|---|---|---|
| No customers (default) | Not bound to any customer | Allowed |
| Exactly one customer | Bound to that customer | Refused, 403 customer_not_allowed |
| Several customers | Refused, 400 customer_header_required | Refused, 403 customer_not_allowed |
A key per customer, each scoped to that one customer, binds every request with no header at all. See Key scopes.
2. Gate each customer with a budget
Go to Budgets & Limits → Customers. Every customer ID seen this month is listed with its spend.
Click Add limit, choose the Customer, and click Continue.
Enter the Monthly budget (USD), set At the budget to Refuse the request, and click Save.
Once the customer's spend reaches the budget, their requests get HTTP 429
before the provider is called, until the month rolls over (UTC):
{
"error": {
"message": "Customer \"acme-corp\" budget of $50.00 exceeded. Current spend: $50.02. …",
"type": "rate_limit_error"
}
}Other customers are unaffected. Catch the 429 and show the customer a message,
offer an upgrade, or queue the work.
To keep a customer working past their budget instead, choose Downgrade the model: their requests move to a cheaper model from your downgrade mappings. Alert, and allow is not enforced on customer budgets yet and lets requests through.
A customer can be picked in Add limit after its first request this month, so you can budget a new customer as soon as they start using your product.
3. See each customer's margin
Record what you charge, and the Customers tab shows revenue and margin next to cost. Click Price on a customer's row, or Default price for everyone without their own:
| Field | What it means |
|---|---|
| Monthly fee (USD) | A fixed amount the customer pays each month. |
| Markup on usage (%) | What you charge on top of their AI cost. |
| Margin floor (%) | The lowest margin you accept. |
| At the floor | Alert me, keep serving, or Refuse this customer's requests. |
Revenue is the monthly fee plus cost marked up; margin is revenue minus cost, as a share of revenue. The margin turns amber within ten points of the floor and red below it. An email alert is sent when a customer comes within ten points of the floor, and again when their margin falls below it, once each per month.
Pricing and margin need the Growth or Enterprise plan. For cost per customer over time, see Unit economics, and for a month's figures by customer, Chargeback grouped by Customer.
Who can do this
Seeing customer budgets and margins needs the reports.read permission;
changing them needs spend_controls.write. Owners and admins have both. See
Roles and permissions.