CostGraph pulls it
You supply read-only credentials and we call the provider once a day.
You push it
You send us FOCUS records. Credentials never leave your infrastructure.
We read your telemetry
Your gateway already measures token usage. No credentials at all.
Supported gateways
Each was run and measured rather than read about: every one reports tokens
differently, and two of them do not follow the OpenTelemetry GenAI conventions
at all. CostGraph normalises that for you.
Connect
- Open Settings -> Integrations and pick your gateway.
- Name the connection and pick the tenant this usage belongs to.
- Select the cluster the gateway runs in.
- Select Connect.
A served target always carries a metric-name filter, so it only ever collects
the token metrics it was configured for. A target you set yourself in
operatorPrometheus.scrapeTargets always wins over a served one.Attribute usage to your customers
If you resell access, tell your gateway to label each request with your customer’s id. CostGraph reads that label into the FOCUS sub-account columns, so per-customer usage shows up wherever you already group by sub-account.Envoy AI Gateway
Envoy AI Gateway
Map a request header onto the metrics. This is a controller-wide setting, so
every gateway that controller manages shares the mapping.The attribute
customer.id arrives as the label customer_id - dots become
underscores on the Prometheus side.Solo.io agentgateway
Solo.io agentgateway
Add a metric attribute computed from the request. On Kubernetes this goes in
an AgentgatewayPolicy. The value is a CEL expression, so the identifier can
come from a header, a JWT claim, or anything else in the request.
Apache APISIX
Apache APISIX
Nothing to configure. Give each customer its own APISIX consumer; the
consumer label is already on every LLM metric, because consumers are
APISIX’s own auth identities.APISIX only starts reporting LLM metrics after the first AI request passes
through it, so an empty scrape before any traffic is expected.vLLM
vLLM
Not available per request. vLLM is a model server, not an auth boundary, and
reports only the model name - no configuration changes that.Either front it with a gateway that can attribute per request, or run one
deployment per customer and annotate the workload:
The annotation fills in a customer only where the gateway did not report one
itself. A gateway that labels each request wins, so annotating a shared
gateway does not collapse its customers onto one sub-account. Annotate the
workload only where per-request attribution is not available.
How usage is priced
Rates resolve in order, and the first match wins:- Your own rate, if the workload carries a
costgraph.ai/pricing-id.modellabel. Register the rate once in the pricing marketplace and tag with the id it returns. See Pricing IDs. - A hosted reference rate for the same model, from the model catalog. This answers “what would this have cost on someone else’s API”.
- Your own amortized rate, for a model you serve yourself. CostGraph divides what the serving namespace cost that day by the tokens it served that day, so a self-hosted model prices at what it actually cost you to run rather than at somebody else’s list price.
Only token usage prices today. Images, audio seconds and characters are
captured and stored now, and will price once the catalog carries rates for
them - nothing is lost in the meantime.
Send usage yourself
If your gateway runs outside a CostGraph-managed cluster, send the usage directly instead. The rows are FOCUS 1.2 shaped with the cost columns left empty, because CostGraph prices them:focus:write scope.
Send from anything else
CostGraph reads one metric family. Anything that can write it can be a source - a Prometheus server, an OpenTelemetry Collector, Grafana Alloy - whether or not it runs on Kubernetes:https://tsdb.costgraph.ai/api/v1/write with an API key in
the X-API-Key header. A gateway CostGraph has never heard of works this way
with no changes on our side.