Skip to navigation

Usage

Per-customer spend reports and a per-request usage feed

The usage endpoints report each customer’s spend, split by whose credential served it. Use them to bill customers or reconcile your invoice.

One customer

GET /v1/customers/{customer_id}/usage takes optional inclusive start and end dates (YYYY-MM-DD), defaulting to month to date.

cURL
curl "https://api-gateway.merge.dev/v1/customers/{customer_id}/usage?start=2026-08-01&end=2026-08-31" \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"
FieldDescription
customer_byok_spendUSD billed to the customer’s own vendor keys
organization_byok_spendUSD billed to your organization’s vendor keys
merge_spendUSD billed to Merge-managed credentials
request_countNumber of requests
per_model, per_provider, per_routing_policyLists of {model, spend}, {provider, spend}, and {routing_policy, spend}, highest spend first. per_provider groups by provider, not by the vendor that served the request.

The three spend fields don’t overlap and sum to the customer’s total for the range.

Breakdowns cover whole months

Totals and request_count cover exactly your dates, but the per_* breakdowns use whole calendar months, so a mid-month boundary pulls in the full month and their sum can exceed the totals. Use month-aligned ranges when the two must agree.

A customer API key calling this for its own customer gets only customer_byok_spend and request_count.

All customers

GET /v1/customers/usage (organization-level key only) takes the same dates and returns one row per customer with spend in the range, highest total first. Here byok_spend combines the customer’s and your organization’s keys.

{
"results": [
{
"customer": "9f8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"total_spend": 412.87,
"byok_spend": 310.44,
"merge_spend": 102.43
}
]
}

A range longer than 366 days, an invalid date, or a start after end returns 400 on both endpoints.

Per-request records

GET /v1/customers/usage/records (organization-level key only) returns one record per request served for a customer, oldest first, so you can charge each request in your own billing system. It includes requests whose response never reached you, such as a dropped connection or a stream you closed early, and video jobs: their final cost arrives as its own record, with job_id, when the job completes.

cURL
curl "https://api-gateway.merge.dev/v1/customers/usage/records?limit=500&cursor=$CURSOR" \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"
{
"results": [
{
"id": "1042",
"request_id": "3f9c2b1a-6d7e-4f80-9a1b-2c3d4e5f6a7b",
"job_id": null,
"customer": "9f8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"customer_origin_id": "acme-corp",
"status": "success",
"http_status_code": 200,
"endpoint": "/v1/responses",
"requested_model": "openai/gpt-5.5",
"model": "openai/gpt-5.5",
"provider": "openai",
"vendor": "openai",
"credential_type": "managed",
"is_stream": true,
"usage": { "prompt_tokens": 812, "completion_tokens": 164 },
"cost_usd": 0.004263,
"provider_cost_usd": 0.00406,
"merge_fee_usd": 0.000203,
"occurred_at": "2026-10-05T14:02:11.482Z",
"recorded_at": "2026-10-05T14:02:12.031Z"
}
],
"next": null,
"previous": null,
"cursor": "eyJyIjogMTA0Mn0="
}

next works like every other list: it’s set while pages come back full and null once you’re caught up. To keep billing as new records arrive, store cursor, which every response returns (empty pages included), and pass it as cursor on the next poll. Records appear about 10 seconds after a request finishes. id is unique and never reused, so dedupe on it if you replay a page.

ParameterDescription
cursorThe next or cursor value from a previous call. Omit to start from the oldest record.
limit1 to 1,000, default 100
customerOnly this customer’s records (Customer id)
origin_idOnly records for this origin_id, including ones from before a customer was deleted and re-created

cost_usd is what Gateway charges you for the request. On your own vendor keys (credential_type byok) it’s the Gateway fee only, and provider_cost_usd is what the vendor bills you directly. A failed request appears with its status and usually a cost_usd of 0. Records are kept for at least 90 days.

Next steps