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

# LLM and gateway wrappers

> Meter and gate every LLM call by wrapping the client you already use.

<Note>
  The Stigg Agent SDK is in public beta.
</Note>

## What it is

A wrapper adds Stigg metering and budget checks to the LLM or gateway client you already use. You call `stigg.wrap(client)` once and use the client it returns. From then on, every model call through that client is:

1. **Checked** to make sure the agent has enough credits or metered capacity to perform its task.
2. **Measured** when the response arrives, by reading the usage block the provider returned.
3. **Reported** to Stigg in the background, attributed to the customer (and optionally the agent) that made it.

```mermaid theme={null}
flowchart LR
    App["Your code<br/>chat feature, summarizer, agent loop"]
    subgraph Wrapped["stigg.wrap(client)"]
        Check["1. Check<br/>the agent's credits or capacity"]
        Measure["2. Measure<br/>the usage in the response"]
    end
    P["Provider or gateway<br/>Anthropic, OpenAI, OpenRouter, LiteLLM"]
    S[("Stigg")]
    Out["Plans and invoices<br/>Credit balances<br/>Usage per customer and agent"]

    App -->|"same call"| Check
    Check -->|"allowed"| P
    P -->|"response"| Measure
    Measure -->|"same response"| App
    S -.->|"credits or capacity left"| Check
    Measure -.->|"3. Report in the background"| S
    S --> Out
```

The wrapped client takes the same arguments, returns the same types, and raises the same errors as the original. The only addition is a `stiggContext` field in each call's parameters, which says which customer the call is for and what to check it against. The SDK removes it before the request is sent, so the provider never sees it. The client you passed to `wrap()` is left as it was, so calls through it are not metered or checked.

```bash theme={null}
npm install @stigg/agent-sdk-js
```

```typescript theme={null}
import Anthropic from '@anthropic-ai/sdk';
import { StiggAgentSDK } from '@stigg/agent-sdk-js';

const stigg = new StiggAgentSDK(process.env.STIGG_SERVER_API_KEY);

// Wrap the client once. One wrapped client serves every customer.
const anthropic = stigg.wrap(new Anthropic());

// The same call as before, plus who it is for and what to check it against.
await anthropic.messages.create({
  model: 'claude-opus-5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Summarize this ticket' }],
  stiggContext: {
    customerId: 'customer-acme',
    entitlement: { currencyId: 'credits' },
  },
});
```

Passing the context on each call lets one wrapped client serve every customer, which is what a server handling many tenants needs. In a process that only ever serves one customer, you can set the context once instead, as the default for every call: `stigg.wrap(new Anthropic(), { stiggContext: { customerId, entitlement } })`. A call can still override any field.

You can wrap any code that calls a model, from a single chat feature or background summarizer to a full agent loop. Each one is metered and checked the same way.

## Why use it

<CardGroup cols={2}>
  <Card title="Bill for AI usage from the client you already use" icon="receipt">
    Token counts and gateway costs flow into Stigg as usage events. Price them in a plan, draw them down from a credit balance, or pass them through with a margin.
  </Card>

  <Card title="Stop spend before it happens" icon="hand">
    Most metering tools tell you a budget was exceeded after the fact. Tell the wrapper which credits or metered feature to enforce, and it checks them before each request leaves, so an agent that has run out never reaches the provider.
  </Card>

  <Card title="Bill what each call actually cost" icon="scale-balanced">
    If you route calls through an LLM gateway, the wrapper reports what the gateway actually charged for each call, not an estimate from token counts and a price list. When the gateway falls back to a different model, you see which model served the call and what it cost.
  </Card>

  <Card title="Your AI calls keep working" icon="life-ring">
    Usage is reported in the background, so it adds no delay to the call. If a report fails, your user still gets their response, and the error goes to your `onError` hook.
  </Card>
</CardGroup>

## How it works

```mermaid theme={null}
sequenceDiagram
    participant App as Your code
    participant W as Wrapped client
    participant S as Stigg
    participant P as Provider or gateway

    App->>W: Model call
    W->>S: Enough credits or capacity?
    S-->>W: Yes
    W->>P: Model call
    P-->>W: Response
    W-->>App: Response
    W--)S: Report usage
```

* **Recognizes your provider.** `wrap()` detects which provider or gateway the client talks to. If it does not recognize the client, it throws an error instead of returning a client that meters nothing. See [Supported providers](/documentation/ai-agents/llm-wrappers/supported-providers).
* **Knows who each call is for.** Each call says which customer, and optionally which agent, it belongs to, so one wrapped client can serve them all. You can also set a default on `wrap()`. See [`StiggContext`](/api-and-sdks/references/sdk/backend/rest/agent-sdk#stiggcontext).
* **Checks only when you ask.** Tell the wrapper which credits or metered feature to enforce, and calls without enough left are denied before they reach the provider. Otherwise every call goes through and is only metered. See [Gating calls](/documentation/ai-agents/llm-wrappers/gating).
* **Handles streaming.** Streamed responses are metered when the stream ends, even if your code stops reading early. See [Metering usage](/documentation/ai-agents/llm-wrappers/metering).

## Example use cases

<AccordionGroup>
  <Accordion title="Token pass-through on a usage-based plan" icon="coins">
    A developer platform charges per million input and output tokens. Each wrapped call reports `input_tokens` and `output_tokens` as one event, and two metered features in Stigg sum them for the invoice. Adding a new model changes nothing in your code.
  </Accordion>

  <Accordion title="Credits that drain with real usage" icon="battery-half">
    A writing assistant sells monthly credit packs. The wrapper converts tokens into credits with a weights table, checks the balance before each call, and shows the user a top-up prompt when the balance runs out instead of an error page.
  </Accordion>

  <Accordion title="Cost-plus pricing over a gateway" icon="percent">
    A company routes all traffic through OpenRouter. The OpenRouter recipe reports the credits OpenRouter actually charged for each call, so the customer is billed real cost plus margin, even when OpenRouter falls back to a different model.
  </Accordion>

  <Accordion title="Protecting a free tier" icon="shield">
    A product offers free AI usage up to a cap. With the cap modeled as a metered feature that the wrapper enforces, calls past the cap are denied before they cost anything.
  </Accordion>
</AccordionGroup>


## Related topics

- [Agent orchestration](/documentation/ai-agents/agent-orchestration.md)
- [Bill LLM gateway spend](/guides/ai-agents/bill-llm-gateway-spend.md)
- [Gateways](/documentation/ai-agents/llm-wrappers/gateways.md)
- [Supported providers and gateways](/documentation/ai-agents/llm-wrappers/supported-providers.md)
- [TypeSafe](/documentation/ai-agents/llm-wrappers/providers/typesafe.md)


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