> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenRouter

> Wrap the OpenRouter or OpenAI client to bill the credits OpenRouter actually charged and track which model served.

## Set up

The SDK recognizes both ways of calling OpenRouter and selects the OpenRouter recipe automatically:

* **OpenRouter's own client**, `OpenRouter` from `@openrouter/sdk`, which OpenRouter recommends.
* **OpenAI's `openai` client** with its `baseURL` pointing at `openrouter.ai`, since OpenRouter's API follows OpenAI's format. See [Why some vendors use the OpenAI client](/documentation/ai-agents/llm-wrappers/supported-providers#why-some-vendors-use-the-openai-client).

<CodeGroup>
  ```typescript OpenRouter client theme={null}
  import { OpenRouter } from '@openrouter/sdk';

  const router = stigg.wrap(new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }), {
    stiggContext: { customerId: 'customer-acme', entitlement: { currencyId: 'credits' } },
  });

  await router.chat.send({
    chatRequest: {
      model: 'anthropic/claude-opus-5',
      models: ['anthropic/claude-sonnet-5', 'openai/gpt-5'], // fallbacks
      messages,
    },
  });
  ```

  ```typescript OpenAI client theme={null}
  import OpenAI from 'openai';

  const router = stigg.wrap(
    new OpenAI({ baseURL: 'https://openrouter.ai/api/v1', apiKey: process.env.OPENROUTER_API_KEY }),
  );

  await router.chat.completions.create({
    model: 'anthropic/claude-opus-5',
    messages,
    stiggContext: { customerId: 'customer-acme', entitlement: { currencyId: 'credits' } },
  });
  ```
</CodeGroup>

* **With the `OpenRouter` client, set the `stiggContext` in `wrap()`.** Its methods take a request object whose type does not include `stiggContext`. To serve several customers, wrap a client for each, or use the `OpenAI` client, which accepts a `stiggContext` on each call.
* **Ask for usage on streamed calls.** OpenRouter includes usage in a stream only when the request asks for it: `streamOptions: { includeUsage: true }` with the `OpenRouter` client, or `stream_options: { include_usage: true }` with the `OpenAI` client. Without it, the stream reports no usage and the call is not metered.
* **Iterate streams with `for await`.** A stream from the `OpenRouter` client that you read with `getReader()` instead is not metered.

To change how `cost` is counted, pass the recipe yourself with `unitsPerCredit`. See [Gateways](/documentation/ai-agents/llm-wrappers/gateways#openrouter) for the options.

## What is reported

OpenRouter is a gateway: one API in OpenAI's format that routes each call to a model from many providers. Every response includes a `usage` object in OpenAI's format with the token counts, plus the cost of the call in OpenRouter credits. The wrapper reads these and reports them to Stigg as the metrics below. For details, see OpenRouter's [usage accounting docs](https://openrouter.ai/docs/cookbook/administration/usage-accounting).

| Client | Method | Event name |
| - | - | - |
| `OpenRouter` | `chat.send` | `openrouter.chat.send` |
| `OpenRouter` | `responses.send` | `openrouter.responses.send` |
| `OpenAI` | `chat.completions.create` | `openrouter.chat.completions.create` |
| `OpenAI` | `responses.create` | `openrouter.responses.create` |

The `OpenRouter` client returns usage in camelCase, such as `promptTokens`. The SDK reports it under the field names OpenRouter's API uses, such as `prompt_tokens`, so the metrics are the same whichever client you use. The `raw.` fields keep the client's own spelling. To meter both clients with one meter, filter on both event names, or set the same [`eventName`](/documentation/ai-agents/llm-wrappers/metering#configuring-meters-for-async-events) for both.

**Chat Completions** (`chat.send` and `chat.completions.create`)

| Metric | What it counts |
| - | - |
| `prompt_tokens` | Input tokens, **including** cached tokens |
| `completion_tokens` | Output tokens |
| `cached_tokens` | Input tokens served from the cache |
| `total_tokens` | All input and output tokens, as reported by the vendor |
| `cost` | The credits OpenRouter actually charged for the call, in micro-credits by default. Set `unitsPerCredit` to match how your Stigg feature is defined. |

**Responses** (`responses.send` and `responses.create`)

| Metric | What it counts |
| - | - |
| `input_tokens` | Input tokens, **including** cached tokens |
| `output_tokens` | Output tokens |
| `cached_tokens` | Input tokens served from the cache |
| `total_tokens` | All input and output tokens, as reported by the vendor |
| `cost` | The credits OpenRouter actually charged for the call, in micro-credits by default. Set `unitsPerCredit` to match how your Stigg feature is defined. |

Cached tokens are counted **inside** `prompt_tokens` and `input_tokens`. If you price both the input metric and `cached_tokens`, cached tokens are billed twice. `total_tokens` includes all the token counts above, so price the total or the parts, never both.

Each event also carries:

| Reported | What it is |
| - | - |
| `model` dimension | The model that actually served the request. When OpenRouter falls back from the model you asked for, the change is visible in Stigg. |
| Idempotency key | The OpenRouter generation ID, so a retried report is never counted twice. |

When a response carries no cost (for example with bring-your-own-key upstreams), `cost` is omitted and the token metrics are still reported.

Every usage field the vendor returns is also included, with a `raw.` prefix. See [How usage is reported](/documentation/ai-agents/llm-wrappers/supported-providers#how-usage-is-reported).


## Related topics

- [Gateways](/documentation/ai-agents/llm-wrappers/gateways.md)
- [Bill LLM gateway spend](/guides/ai-agents/bill-llm-gateway-spend.md)
- [LLM and gateway wrappers](/documentation/ai-agents/llm-wrappers/overview.md)
- [Supported providers and gateways](/documentation/ai-agents/llm-wrappers/supported-providers.md)
- [JavaScript](/api-and-sdks/changelog/agent-sdk/javascript.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.