Skip to main content

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.
  • 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.

Counting cost

OpenRouter charges in credits, and a single call usually costs a small fraction of one credit. The recipe reports cost as a whole number, so by default it counts in millionths of a credit: a call that cost 0.0003 credits is reported as 300. If the feature or credit type you meter in Stigg uses a different unit, pass the recipe yourself with unitsPerCredit. For example, to report in hundredths of a credit:
A larger unit rounds each call up to a whole unit, so cheap calls are overcharged. Keep the default unless your pricing requires otherwise.

openrouterRecipe 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. 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 for both. Chat Completions (chat.send and chat.completions.create) Responses (responses.send and responses.create) Cached tokens are counted inside prompt_tokens and input_tokens. If you price both the input metric and cached_tokens, cached tokens are charged twice. total_tokens includes all the token counts above, so price the total or the parts, never both. Each event also carries: 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.