Attribution cuts
How a month of your spend is cut by key, project, route, tag and customer: one row per value, and every request in one row of each cut.
On this page
Attribution cuts a calendar month of your organization's spend by one label at a time: the key each request used, the project it named, the route it called, or the team, feature, customer or end user its tags declared. A cut is the priced record Meter keeps, the token counts your provider reported priced at the reference price list, added up per label. On the platform, the Attribution page cuts your spend by key, project and tag (Meter).
The seven cuts
Cut, as dim |
One row per | Plan |
|---|---|---|
key |
gateway key, named by its key_ id |
Team and above |
project |
project named in x-recovea-project |
Team and above |
route |
route the request called | Team and above |
team |
value of a team: tag |
Growth and above |
feature |
value of a feature: tag |
Growth and above |
customer |
value of a customer: tag |
Team and above |
enduser |
value of an enduser: tag |
Growth and above |
- A key is named by its record id, never by its secret (Organization and keys).
- A route is one of a fixed set of names, such as
/v1/chat/completionsor/v1/embeddings. A call with no name of its own in that set is grouped under anotherroute, such as/v1/other. - A tag cut reads the first tag of its namespace with a value after the
prefix, in the order the request sent its tags, and keeps that value
(The four namespaces). A request that carried
two
team:tags is in the first one's row only. - A project or a tag value is opaque. It is stored as Tags describes and returned byte for byte, never resolved to a person, a team or a company.
Every request is in one row of every cut
When a request is recorded, it is added to one row of each of the seven cuts for its month: one request, and its cost when it was priced. So every cut adds up to the same month, the same number of requests and the same spend, whichever label it is cut by.
That holds because a request that says nothing about a label still lands in a row of that cut. Two values are reserved for those rows:
unassigned, in the project cut, holds every request that named no project;untagged, in each of the four tag cuts, holds every request that carried no tag of that namespace with a value after its prefix.
A request that sends the reserved word itself, unassigned as its project or
untagged as a tag's value, lands in the same row. The untagged row of the
customer cut is not a customer: no customer spending cap can refuse that
traffic, so no cap, remainder or refusal is ever shown on it
(the per-customer figures).
A request that was never recorded is in no cut: a call that never reached the gateway, a request refused before your provider was called, and a request passed through while the gateway failed open (What fails open).
What a row holds
| Field | What it is |
|---|---|
dim |
the cut |
value |
the key_ id, the project, the route or the tag's value, or a reserved value |
requests |
every request recorded in the row that month, priced or not, whatever its status |
spendMicroUsd |
what the priced ones cost at the reference price list, in integer microdollars; 1000000 is one dollar |
spend |
the same figure as a display string |
share |
the row's part of the cut's spend, from 0 to 1, rounded down to four decimal places; null when the cut's spend is zero |
Rows come spend-descending, and rows with equal spend in the order of their value.
- An unpriced request counts and adds nothing. A request on a model the
price list has no price for, or one whose token counts your provider did not
report, is in
requestsand adds nothing tospendMicroUsd(Meter). shareis a part of the cut. It is the row'sspendMicroUsddivided by the sum ofspendMicroUsdover every row the cut returned. With every request in one row, that sum is the month's spend, and a cut's shares add up to 1 or a little under it, since each is rounded down:0.8809is 88.09%.
The customer cut
The customer cut carries more on each row than the other six: which price lists priced that customer's requests in the month, how many could not be priced, the monthly cap that applies and what is left of it, and the last time a cap stopped that customer. The other six carry none of those keys, rather than a zero nobody counted. Every field is in the per-customer figures; the two about price lists, in short:
priceListsis"one"when one price list priced every priced request in the month,"more_than_one"when the month spans two lists, and"none"when no request was priced. It isnullwhen the record holds no request under that row's value in the month, which is usually theuntaggedrow.priceListVersionnames the one list whenpriceListsis"one", and isnullotherwise.
Those keys come from each request's own record, because the monthly rows the cuts read know neither which list priced a request nor whether it went unpriced.
The customer cut is read to 10,001 rows: the
10,000-customer bound and
the untagged row. Past that, the rows with the least spend are left off, and
share is then a part of the rows returned. The customer cut is Team and above;
on every plan, Free included,
the count says how many customers
were tagged in the month and what they cost in total.
The month
Every cut is one calendar month in UTC, asked for as period=YYYY-MM. A request
belongs to the month in which it started. A missing or malformed period is
refused with 400 and "The period query parameter must be a calendar month in
YYYY-MM form."
On the wire
The cuts are platform routes. Owners, Admins, Members and Viewers can read them; the Billing role cannot.
GET /platform/v1/attribution/cuts?dim=project&period=2026-10[
{
"dim": "project",
"value": "checkout",
"requests": 1840,
"spendMicroUsd": 7400000,
"spend": "$7.40",
"share": 0.8809
},
{
"dim": "project",
"value": "unassigned",
"requests": 212,
"spendMicroUsd": 1000000,
"spend": "$1.00",
"share": 0.119
}
]A cut above your plan answers 403, and the body carries nothing from the cut:
{ "locked": true, "requiredPlan": "Growth", "requestsMetered": 2052 }requiredPlan is the cheapest plan that opens the cut, and requestsMetered is
your organization's count of requests for the month. A dim that is not one of
the seven is refused with 400.
Two more reads take the same period:
GET /platform/v1/attribution/export.csvwrites cuts as CSV, with the columnsdim,value,requests,spendMicroUsd,spend, wherespendcarries no currency sign. Withdim, it is that one cut, on the plan that opens it. Without it, on Growth and above, it is all seven cuts in the order of the table above.GET /platform/v1/attribution/analyzed, on Growth and above, is every cut at once. Each row carries itsshareanddeltaPct: the change from the previous calendar month's spend under the same value, in whole percent with the fraction dropped, andnullwhere the previous month holds no spend under that value or could not be read.
What a cut is, and what it is not
- It is the record, not the bill. A cut adds up priced requests at the reference price list; the bill is your provider's invoice.
- It groups by your labels. A request you did not label for the project cut or a tag cut sits in that cut's reserved row; nothing assigns it a label for you.