Skip to content

DocsOrganizations

Usage per end customer

Requests, tokens and estimated provider cost for each of your own customers, by day or month, project and model — to bill them from in your own billing system.


INFRO is in private early access. Running these examples requires an early-access account, an active trial or subscription entitlement, and your own provider connection. Self-serve purchasing is not generally open. See Early access.

If you charge your own users (your end customers) for the AI features in your product, you need to know what each of them used. INFRO already attributes every request to the end customer your app names in metadata.user_id (or the X-INFRO-User-Id header). This export gives you that usage as rows you can load into your billing system: one row per end customer, period, project and model.

INFRO measures; you bill. The export carries counts, tokens and the estimated cost your own provider will bill you for each row. What you charge your customers, and how, is decided in your billing system at your prices. INFRO never charges your end customers and takes no part in that billing.

Included from the Team plan. The per-customer cost view on the console's End customers screen is on every plan.

From the console

On Budgets → End customers, choose Usage for billing, pick a month and whether you want one row per month or per day, and download the CSV. Leave the end customer empty for all of them, or type one id exactly as your app sends it.

From the API

A billing job should read the same rows from the API with a gateway key whose observability access is organization-wide or limited to one project (a project key reads its project). A key limited to its own requests or to one environment is refused with 403 organization_scope_required, because usage per end customer is kept per organization and project.

Last month, one row per end customer, project and model
curl "https://api.infro.io/v1/usage/end-customers?period=2026-09&granularity=month" \
  -H "Authorization: Bearer $INFRO_API_KEY"
ParameterValuesMeaning
periodYYYY-MMOne calendar month (UTC). Or send from and to instead.
from, toYYYY-MM-DDUTC dates; from is included, to is not. At most 93 days per call, and no earlier than 400 days ago. With neither period nor from/to: this month so far.
granularityday (default), monthOne row per UTC day, or per calendar month.
end_user_idyour idOne end customer, matched exactly.
formatjson (default), csvJSON pages; CSV is one file.
limit1 to 10,000 (default 1,000)JSON rows per page.
starting_aftera next_cursorThe next JSON page. Rows are ordered by period, end customer, project and model.
A JSON page (abridged)
{
  "object": "list",
  "window": { "from": "2026-09-01", "to": "2026-10-01" },
  "granularity": "month",
  "currency": "usd",
  "estimate": true,
  "data": [
    {
      "object": "end_customer_usage",
      "period_start": "2026-09-01",
      "end_user_id": "acme-corp",
      "project_id": "proj_7K2M…",
      "project_name": "Support assistant",
      "model": "anthropic/claude-sonnet-5",
      "requests": 1840,
      "unpriced_requests": 0,
      "cached_responses": 112,
      "failed_requests": 6,
      "prompt_tokens": 2210450,
      "completion_tokens": 388120,
      "cached_prompt_tokens": 905000,
      "units": 0,
      "estimated_provider_cost": "12.874310"
    }
  ],
  "has_more": true,
  "next_cursor": "WyIyMDI2LTA5LTAxIiwi…"
}

format=csv returns the same columns in the same order, with estimated_provider_cost_usd for the cost. A file over 200,000 rows is refused with 400 export_too_large rather than cut short; ask for monthly rows, a shorter window or one end customer, or page through the JSON form. The response carries X-INFRO-Export-Rows, X-INFRO-Window-Start, X-INFRO-Window-End and X-INFRO-Export-Schema-Version (today 1; a column is only ever added at the end without changing it).

What each column counts

ColumnCounts
requestsSuccessful requests (HTTP status below 400) — the same definition as your plan's request allowance.
unpriced_requestsOf those, requests INFRO has no price for. They add nothing to the cost; they are never counted as $0.
cached_responsesOf those, requests answered from INFRO's response cache, with no provider call (a known $0).
failed_requestsRequests that returned an error. Usually nobody bills them; they are here so the file reconciles with your request log.
prompt_tokens, completion_tokens, cached_prompt_tokensToken counts as the provider reported them, summed over every request in the row.
unitsImages, seconds of audio or video, and characters for speech — the modality's own count.
estimated_provider_costWhat your own provider is estimated to bill you for the row, in USD, as a decimal string. Empty (null) when no successful request in the row was priced.

Cost is an estimate, at the rate in force when each request ran — your own rates where you have set them, otherwise the vendor's list rate. Provider cost APIs report organization totals only, so a per-customer figure cannot be reconciled against your provider's bill. Counts and tokens are what the gateway recorded. Days are UTC. Requests without an end-customer id are not in this export; they are in Analytics and the request log.

Each export is written to your organization's audit log (who, which window, which format).

↑ ↓ navigate↵ open/ anywhere in docs