Tag your traffic
Tell CoreValue which of your users and customers each request was for, so you can see and cap spend per user and customer.
CoreValue already knows which key, team, model and provider each request used. It does not know who in your product the request was for, or what feature made it. Send that with a few Cova-* headers, and every page of the console can split spend by it.
The headers
| Header | Tells CoreValue | Where it shows up |
|---|---|---|
Cova-Customer-Id | Which of your customers the request was for | Requests → Customer column · Spend → Customer · Budgets & Limits → Customers · Reports |
Cova-Feature-Id | Which feature or surface made it, such as checkout | Requests → Feature column · Spend → Feature |
Cova-User-Id | The person using your product | Requests → User column · Spend → End user |
Cova-Session-Id, -Name, -Path | Which run it belongs to, and which step | Requests → Run column · Spend → Run · Runs |
Cova-Property-<Name> | Anything else you want to split by | Requests → a column per property · Spend → Property |
Cova-Actor | Whether a person or a program produced the turn | Requests → Actor column · the run's Actors |
Cova-Team-Id | A team label for your own records | The request's Properties only — see below |
Every header is optional. The Spend by … panel on the Dashboard uses the same tabs as Spend.
Send them
curl https://gateway.corevalue.dev/v1/chat/completions \
-H "Authorization: Bearer $COVA_API_KEY" \
-H "Content-Type: application/json" \
-H "Cova-Customer-Id: acme-corp" \
-H "Cova-Feature-Id: support-bot" \
-H "Cova-User-Id: user_abc123" \
-H "Cova-Property-Environment: production" \
-d '{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hello"}]}'response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
extra_headers={
"Cova-Customer-Id": "acme-corp",
"Cova-Feature-Id": "support-bot",
"Cova-User-Id": "user_abc123",
"Cova-Property-Environment": "production",
},
)const response = await client.chat.completions.create(
{ model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello" }] },
{
headers: {
"Cova-Customer-Id": "acme-corp",
"Cova-Feature-Id": "support-bot",
"Cova-User-Id": "user_abc123",
"Cova-Property-Environment": "production",
},
},
);The client is the one from the Quickstart. To check a tag arrived, open the request on Requests and look under Properties.
Customers and features
Cova-Customer-Id and Cova-Feature-Id are cut at 256 characters; a value of only spaces is ignored. Spend groups customers without regard to case, so Acme-Corp and acme-corp are one customer — the same rule customer budgets use. The Customer column on Requests shows the ID exactly as it was sent.
To cap a customer's spend, see Per-customer budgets.
End users
Cova-User-Id takes letters, digits and _ - : ., up to 256 characters. A value with any other character is dropped. It also lets a rate limit count per user.
An end user is not a member of your organisation, and member budgets never use this header.
Properties
Cova-Property-<Name> attaches any label you choose. Send as many as you need.
- Name: lowercased, hyphens become underscores, then only letters, digits and
_are allowed, up to 64 characters. A name that breaks the rule is dropped.Cova-Property-Deploy-Regionis stored asdeploy_region. - Value: cut at 256 characters.
Each property appears in Requests as a column, off by default — turn it on with Manage columns — and as a field in Filter. On Spend, the Property tab groups spend by the values of the property you pick.
Runs
Send Cova-Session-Id on every request of one agent run or workflow, with Cova-Session-Name and Cova-Session-Path if you want them. See Runs.
Actor
Cova-Actor is human, agent or unknown. Without it, the gateway infers agent when the request feeds a tool result back to the model, and unknown otherwise. Hover the Actor column to see whether a value was declared or inferred; filter on it with Actor and Actor source. The inference misses the first turn of every agent run, so send the header if you need the count to be right. Details are in Headers.
What you can trust
These headers are self-reported: the gateway records what your application sends. Anyone holding a key can send a different customer or user ID.
- To pin a key to particular customers, scope it. A key scoped to one customer fills in
Cova-Customer-Iditself. - Teams come from the key, never from
Cova-Team-Id. The Team tab on Spend, team budgets, chargeback and who can see a request all use the team the key is assigned to.Cova-Team-Idis kept on the request as a property and changes none of them. - A property cannot impersonate these headers.
Cova-Property-Cova-Customer-Idis stored as the propertycova_customer_idand is not a customer ID;Cova-Property-cova_actoris dropped.
Keep IDs stable — an ID that changes splits one customer into two rows. Do not put secrets or personal data in a header value.
Related
- Headers reference — every header and its exact rules
- Spend — spend by each of these tags
- Budgets & Limits — cap a customer
- Unit economics — cost per customer against what you charge