Skip to main content
In this guide you meter what each customer’s calls actually cost, plus a markup, and burn it down from the customer’s prepaid credit pool. 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 pool that burns down by the gateway’s real cost times your markup, call by call.
  • A check before each call that denies access when the credit pool is empty, so you can offer the customer more credits with a top-up.
Before you start:
  • A Stigg server API key.
  • An OpenRouter account and API key, or a LiteLLM Proxy, self-hosted or cloud-hosted.
  • A credit type 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

Define your markup

Both gateways report each call’s cost in millionths of a US dollar by default: OpenRouter in millionths of an OpenRouter credit (1 OpenRouter credit is $1), and LiteLLM in millionths of a dollar.With 1 Stigg credit worth $0.01 and a 20% markup, each call burns:
For example, a call that cost the gateway $0.00108 (a cost of 1,080) burns 0.1296 credits.
2

Install and initialize

3

Wrap the gateway client

Wrap an OpenAI client pointed at OpenRouter:
To wrap OpenRouter’s own client instead, see OpenRouter.
What each setting does:
  • entitlement turns on the check before each call, against the credits credit pool.
  • usageMapper applies your markup to the gateway’s cost and reports the result in credits, straight to the credit pool. See Weighted credits.
  • ingestMode: 'sync' updates the credit pool with each call, so the next check already includes it.
4

Make calls and handle an empty credit pool

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 burns its marked-up cost.To compare what was reported with the gateway’s own dashboard, print the wrapped client’s summary, which flush() returns:
To log every report as it is sent instead, pass an onIngest hook to the SDK.

Things to know

  • A call can go past the last few credits. Each check asks only whether any credits are left, and the call’s real cost is burned after it. A customer with almost no credits left can make one more call, which may cost more than what remained. See Enforcing a limit on cost to check against an estimate of the call’s cost instead.
  • Calls with no cost burn no credits. Some calls return no cost, for example on OpenRouter with your own provider key. To burn credits for those too, add token weights to the weightedMetrics table.
  • Calls attributed to agents are rounded up. If you also attribute calls to agents, each call’s credits are rounded up to a whole credit. See Weighted credits.
  • Which model served each call. Credits burned straight from the credit pool carry no dimensions, so this setup does not record the model. To track it, also report the calls as events in async mode. See Routing drift.