> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Usage

> Read a customer's spend over a date range, split by who supplied the credential and broken down by model, provider, and routing policy, or pull one record per request to bill in your own system.

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`**

```bash title="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"
```

| Field                                             | Description                                                                                                                                                                       |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customer_byok_spend`                             | USD billed to the customer's own vendor keys                                                                                                                                      |
| `organization_byok_spend`                         | USD billed to your organization's vendor keys                                                                                                                                     |
| `merge_spend`                                     | USD billed to Merge-managed credentials                                                                                                                                           |
| `request_count`                                   | Number of requests                                                                                                                                                                |
| `per_model`, `per_provider`, `per_routing_policy` | Lists 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](/merge-gateway/embedded-routing-stack/customer-api-keys) 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.

```json
{
  "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`**

```bash title="cURL"
curl "https://api-gateway.merge.dev/v1/customers/usage/records?limit=500&cursor=$CURSOR" \
  -H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"
```

```json
{
  "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.

| Parameter   | Description                                                                                         |
| ----------- | --------------------------------------------------------------------------------------------------- |
| `cursor`    | The `next` or `cursor` value from a previous call. Omit to start from the oldest record.            |
| `limit`     | 1 to 1,000, default 100                                                                             |
| `customer`  | Only this customer's records (Customer `id`)                                                        |
| `origin_id` | Only 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

#### [Budgets](/merge-gateway/embedded-routing-stack/budgets)

Cap a customer's spend

#### [Projects API usage](/merge-gateway/automation/projects-api/usage)

Usage for your own projects