SaaS and technology · AI unit economics

AI cost by customer, user and model

How much each customer, plan and user costs in LLM spend, who consumes far more than they pay and whether price covers usage, with a cost that matches the provider's invoice.

UsageSpecific
EffortHigh
ForSaaS with AI inside the product that pays LLM providers per use and charges customers by subscription or credits.
Source

Provider cost, AI gateway and usage events

Rule

One monetary source and allocation that preserves the total

Outcome

Cost by customer, user and model

Activation

Pricing, alerts and AI agent

What it solves

  • AI cost matches the provider's invoice, day by day.
  • Every unit of cost attributed to customer, user and model, or flagged as unattributed.
  • Heavy users and plans with negative margin surface on their own.

Business questions it answers

Ask your agent these questions once the case is live.

How much did we spend on AI yesterday, by model and by product?
Which users spent more than US$ 20 in a day?
What is the average cost per request and how did it change after the model switch?
What is each customer's AI cost against what they pay, by plan?
How much of the cost is the team's internal usage?
Which customers are above the p99 of consumption?

What you need

  • Access to the providers' or AI gateway's cost and usage APIs
  • The user and customer identifier recorded on every call
  • Plans and prices from billing, and the declared exchange rate

What you get

  • A user x model x day consumption table, with tokens, requests and cost
  • Cost by customer and plan against revenue, per month
  • Alerts for users and customers above the limit
  • An AI agent that answers about cost from the right monetary source

Where to activate

Pricing and margin

Cost to serve by plan against MRR, to review limits, credits and price.

Consumption alerts

A daily alert of users and customers above the limit or the p99, with the model that drove the cost.

AI agent via MCP

Answers how much each customer and model cost from the monetary source, and warns when a day hasn't closed yet.

Ready to build?

Cost APIs have limits (they don't group user and model together, close the day in UTC, paginate slowly) and the allocation of shared cost has to be designed. Start with the monetary source and add attribution afterwards. The detailed view has the business rules, the pitfalls and the acceptance test. Or send everything straight to your agent with the Nekt MCP.

The problem

The provider bills by project or key, the analytics tool knows which user made the call, and the two don't match. Analytics prices every token as new and inflates cost; the cost API doesn't return user and model in the same query; the provider's day is UTC. And shared cost, such as model infrastructure, has no owner. The result is a per-customer cost that doesn't tie to the invoice and a price nobody can defend.

How it is usually done, and the rule

Each row is a mistake that already happened in practice.

The common wayThe rule
01
Summing the estimated cost that comes in analytics events.
One source for money, another for attribution

Cost in money comes from the invoice or the cost API of the provider or gateway. Analytics events say who, in which project and with which tool, but don't work as a value: in a real base, analytics sent every token as new, without the prompt cache discount, and inflated cost several times. Use analytics only to attribute, and reconcile both sources by day.

02
Saving whatever day the API returned, without checking the total.
The day's total has to close

Before trusting a day, check that the sum of cost by user rebuilds the model's cost for the day (for example, 99% or more, with an absolute tolerance for models with negligible cost) and that the users collected cover the total reported by the API. A day that doesn't close raises an alarm and is collected again.

03
Spreading the model's cost across the day's users without querying the detail.
User and model need two queries

Report APIs usually group by model or by user, not both. Query cost by model for the day, as the reference, and, for each model, cost by user. Write with a merge on date, product, model and user, so a day can be collected again without duplicating.

04
Leaving shared cost out of per-customer cost, or spreading the remainder without saying so.
Shared cost allocation preserves the total

Cost with no user at the source (infrastructure, batch calls, fixed provider charges) is allocated by a declared usage weight: requests, tokens or events. The allocated sum equals the original cost. Whatever has no traceable usage that day goes to a visible unattributed bucket, never spread silently.

05
Grouping by whatever identifier the API returned.
Canonicalize user and model

The same user shows up as email, login id and app id. Bring them all to one canonical id and sum the fragments. Model names change with versions and dates: normalize to a canonical model with the provider alongside. Flag development users and check, on every load, the map from API key to product: a swapped key and label raise no error.

06
Adding the team's usage to customers' cost.
Internal usage is not cost to serve

The team's own usage (tests, internal agents, development) is a company expense, not product cost. Put it on its own line and take it out of per-customer cost and plan margin.

07
Comparing the provider's daily cost with local daily usage.
Provider day in UTC, business day in São Paulo

The provider closes the day in UTC, which covers parts of two São Paulo days. For daily views, declare which day you are using; monthly, the difference is small. Never mix UTC-day and local-day columns in the same sum.

08
Keeping only the converted amount, or summing USD and BRL.
Source currency kept alongside

Most API cost is billed in dollars. Keep the amount and the source currency, convert at the rate of the accrual day in a single layer, and never sum amounts in different currencies. FX exposure = sum of the source amount in USD.

09
Looking only at average cost per user.
Customer cost against what they pay

Sum the cost of the customer's users in the month and compare it with their MRR and the credits they bought. Show the cost distribution per user in percentiles (p50, p75, p90, p99): the average hides heavy users. A simple alert threshold works, such as a user spending more than US$ 20 in a day.

10
Summing tokens from every event received.
Usage events deduplicated

Usage events sent by the product can arrive twice. Deduplicate by a hash of the event content before summing tokens, and keep call retries as their own metric: a retry consumes tokens and delivers no answer.

Which source answers each question

Money on one side, attribution on the other, reconciled by day.

how much we spent, in moneyProvider or gateway cost APIamount.value (OpenAI costs)
who spent: user, project, toolGateway by user or product events
tokens read from cacheSeparate cached from new tokensinput_cached_tokens (OpenAI usage)
cost with no user at the sourceAllocation by usage weight, total preserved
cost with no traceable usage that dayUnattributed cost, its own line
the team's own usageInternal line, outside cost to serve

Definitions

AI cost
amount charged by LLM providers and the gateway for the day, from the monetary source, in the source currency and converted at the day's rate
Attributed cost
share of cost tied to a user and a customer, directly or by allocation
Unattributed cost
the day's cost with no traceable usage, published on its own line
Cost per request
sum of cost / sum of requests, by model and day
Customer cost to serve
cost attributed to the customer's users in the month, excluding internal usage
Plan AI margin
(plan MRR - cost to serve of the plan's customers) / plan MRR, per month
Cache rate
input tokens read from cache / input tokens, by model and day
Heavy user
user above the p99 of the product's daily cost, or above the declared limit

Pitfalls that already happened

Analytics inflated the cost

Cost from analytics events treated every token as new. In one month, the provider recorded most of a model's tokens as cached, and analytics priced all of them as new input.

Value always from the cost API; analytics only to attribute.

An extraction that lost days without failing

The analytics events load reported success while picking up only a few minutes of data in about a third of runs, and whole days disappeared with no alert.

Reconcile by day with the monetary source and alarm when coverage drops.

Swapped key and label

The product was defined by the API key, and one product's key saved under another's label sent consumption to the wrong product, with no error at all.

Validate the key-to-product map on every load.

Dollars without saying how many

The source-currency amount was removed for looking duplicated, and with most API cost in dollars nobody could state the FX exposure.

Keep amount and source currency paired.

A duplicated event summed tokens

Usage events arrived repeated through the message queue, and token consumption for some flows showed up doubled.

Deduplicate by a hash of the event content.

Acceptance test

The case is done when every item passes.

Agent package

Paste into Claude, ChatGPT or any client with the Nekt MCP connected.

Full Markdown
AI cost by customer
- The money value comes from the provider's or gateway's cost API. Analytics events are only for attributing user and project, never as a value.
- Day cost = attributed + unattributed + internal usage.
- Shared cost is allocated by a declared usage weight (<weight>). The allocated sum equals the original.
- The team's internal usage doesn't go into per-customer cost or plan margin.
- The provider's day is UTC. Say which day you are using.
- Amounts in the source currency are never summed across currencies. Conversion at the accrual day's rate.
- Users and models are in canonical ids.
- Per-customer cost is compared with the customer's MRR and credits. Use percentiles, not only the average.
- If a day hasn't passed the completeness lock, say the day hasn't closed yet.
Per-client exceptions:
- <client>: plan <plan> includes <n> AI credits per month.
- <client>: project <project> is internal usage.

Variations

Cost per delivery

When each send or generated document has its own LLM cost record, sum by delivery and compare with the unit price.

Impact of each change

A daily series of cost and savings attributed to each model or prompt change, to prove the change paid off.

Bot quality next to cost

Human interventions and retries per conversation, to know whether the cheaper model is hurting service.