Skip to main content
In this guide you bill customers for what their calls actually cost, plus a margin, by drawing down a prepaid credit balance. The cost comes from the gateway itself, so it reflects caching, routing and fallbacks rather than a price list you maintain by hand. What you will build:
  • A credit balance that drains by the gateway’s real cost times your markup, call by call.
  • A pre-call check that denies access when the balance is empty and offers to buy more credits with a top-up.
  • A model dimension on every report, so you can see when routing changes your costs.
Before you start:
  • A Stigg server API key.
  • An OpenRouter account and key, or a LiteLLM Proxy you run.
  • A credit currency in Stigg (this guide uses credits, where 1 credit is worth 1 US cent) and a customer with a credit grant. See Set up credits.
1

Decide your conversion

OpenRouter reports cost in micro-credits by default (1 OpenRouter credit is 1 US dollar, so 1,000,000 micro-credits is 1).LiteLLMreportsmicro−dollarsbydefault.Eitherway,oneunitis1). LiteLLM reports micro-dollars by default. Either way, one unit is 0.000001.With 1 Stigg credit = $0.01 and a 20% markup:
A call that cost the gateway $0.00108 (1,080 micro-units) draws 0.1296 credits. Credit currencies accept fractional amounts, so the SDK does not round. The exception is a call attributed to an agent, which is rounded up to a whole credit because Governance counts agent usage in whole units. If you attribute calls to agents, choose a credit unit small enough that this rounding does not matter for your prices.
2

Install and initialize

3

Wrap the gateway client

This example uses the OpenAI client, which accepts a different customer on each call. You can also wrap OpenRouter’s own client, OpenRouter from @openrouter/sdk, with the same recipe options. Its calls do not accept a stiggContext, so set the customer in wrap(). See OpenRouter.
  • entitlement turns on the pre-call balance check.
  • usageMapper converts the gateway’s cost into credits. Because the metric is named after the currency being checked, it draws the balance directly.
  • ingestMode: 'sync' updates the balance with each call, so the next check sees it right away.
4

Make calls and handle an empty balance

Denied access is never cached, so a customer who buys more credits can continue on their very next call.
5

Verify

Make a few calls and open the customer’s credit balance in the Stigg app. Each call draws its marked-up cost. Check onIngest or the wrapped client’s stigg.summary() to compare what was reported with the gateway’s own dashboard.
6

Watch for routing drift (optional)

Each report carries the model that actually served as a model dimension. When the gateway falls back from the model you requested, your cost changes and the dimension shows it. To analyze it over time, meter a second client or feature in async mode and add a raw-events meter that filters on model.

Things to know

  • The check asks for one unit by default. A customer with almost no credits left can make one more call, which can cost more than one unit. If that matters, give the recipe an estimate that returns an upper bound. See Gating on cost.
  • Responses with no cost (bring-your-own-key on OpenRouter, some upstreams) report no cost and therefore draw no credits. Add token weights to the table if you need a fallback.
  • Do not meter the same traffic twice. If you also run a proxy that reports with ingestFromHeaders(), exclude the traffic you already wrap.