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

# Set budgets for AI agents

> Give each AI agent its own credit budget under a shared team limit, and handle denied access by the agent or the team.

In this guide two agents, a drafter and a reviewer, share one team budget while each has a cap of its own. You will watch the drafter get stopped by its own cap while the reviewer keeps working, and then watch the team's cap stop the reviewer even though it still has budget of its own.

```mermaid theme={null}
flowchart TB
    C["customer-acme<br/>credit pool"] --> T["team-research<br/>8 credits / month"]
    T --> D["agent-drafter<br/>3 credits / month"]
    T --> R["agent-reviewer<br/>10 credits / month"]
```

**Before you start:**

* A Stigg server API key.
* A [LiteLLM Proxy](https://docs.litellm.ai/docs/simple_proxy), self-hosted or cloud-hosted. Any other [supported provider or gateway](/documentation/ai-agents/usage-metering#supported-providers-and-gateways) works the same way.
* [Governance](/documentation/governance/overview) enabled on your account.
* A credit type `credits` and a customer `customer-acme` with a credit grant much larger than the team budget, so the denials come from the budgets and not from an empty credit pool. See [Set up credits](/guides/i-want-to/set-up-credits).

**1. Create the entity types**

Create two [entity types](/documentation/governance/core-concepts#entity-types) in your environment, once:

| ID | Attribution key |
| - | - |
| `team` | `teamId` |
| `agent` | `agentId` |

Do this in the Stigg app or through the API. See [Setting up governance](/documentation/governance/setting-up#define-entity-types).

**2. Create the team and its budget**

Add the `team-research` entity to `customer-acme`, with a budget of 8 `credits` per month. In the Stigg app, open the customer and add the entity from its governance tree. See [Add an entity to a customer](/documentation/governance/setting-up#add-an-entity-to-a-customer).

In a real product, your customer's admin usually sets the team budget through an interface you build.

**3. Register the agents**

Register each agent when it is created in your product. [`register()`](/api-and-sdks/references/sdk/backend/rest/agent-sdk#register) creates the agent's entity, places it under the team, and sets its budget. `cadence: 'P1M'` resets the budget every month.

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

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

const credits = { currencyId: 'credits' };

for (const [agentId, limit] of [['agent-drafter', 3], ['agent-reviewer', 10]] as const) {
  await stigg.register({
    customerId: 'customer-acme',
    agentId,
    entityTypeId: 'agent',
    budget: {
      entitlement: credits,
      parentId: 'team-research',
      limit,
      cadence: 'P1M',
    },
  });
}
```

> [!TIP]
>
> By default, `register()` sets `limit` every time it runs, so a limit an admin changed in the Stigg app is overwritten the next time your code registers the agent. If admins manage agent budgets in the Stigg app, add `apply: 'on-create'` to the `budget`: your code then sets the limit only when the agent has no budget yet. Leave it out when your code owns the limit, so that changing `limit` in code updates the budget.

**4. Wrap the client**

Wrap the client you use to call your LiteLLM Proxy:

```typescript theme={null}
import OpenAI from 'openai';
import { litellmRecipe, unitsPerTokens } from '@stigg/agent-sdk-js';

// One wrapped client for every agent. Each call sets its customer and agent.
const llm = stigg.wrap(new OpenAI({ baseURL: process.env.LITELLM_URL, apiKey: process.env.LITELLM_KEY }), {
  recipe: litellmRecipe({ baseUrl: process.env.LITELLM_URL }),
  stiggContext: {
    entitlement: credits,
    // 1 credit per 1,000 tokens, reported straight to the credit balance.
    usageMapper: unitsPerTokens('credits', 1_000),
    ingestMode: 'sync',
  },
});
```

* The usage mapper reports to `credits`, the same currency the budgets are written against. Reporting raw token names here would not count against a credit budget.
* `ingestMode: 'sync'` updates the budgets with each call, so the next check sees the spend.
* Governance counts agent usage in whole units, so the amount of each call made as an agent is rounded up to a whole credit. A call of 400 tokens costs 1 credit.

**5. Run the agents and handle denied access**

```typescript theme={null}
async function turn(agentId: string) {
  try {
    await llm.chat.completions.create({
      model: 'gpt-5', // a model group from your LiteLLM Proxy's config
      messages,
      stiggContext: { customerId: 'customer-acme', agentId, attributionKey: 'agentId' },
    });
    console.log(agentId, 'ok', llm.stigg.lastDecision?.remaining);
  } catch (err) {
    const decision = stigg.denial(err);
    if (!decision) throw err;
    console.log(agentId, 'DENIED by', decision.deniedBy, decision.reason);
    console.log('  ', decision.message);
  }
}

for (let i = 0; i < 12; i++) {
  await turn('agent-drafter');
  await turn('agent-reviewer');
}
```

`agentId` with `attributionKey` attributes each check and report to that agent, so Governance checks the agent, the team and the customer together. `llm.stigg.lastDecision` is the wrapped client's most recent [decision](/api-and-sdks/references/sdk/backend/rest/agent-sdk#accessdecision), and `remaining` is the budget left in the tightest level.

Expected output, abbreviated:

```text theme={null}
agent-drafter DENIED by agent-drafter BudgetExceeded
   Budget exhausted for agent-drafter. Ask whoever set this budget to raise it, or wait for the next reset.
agent-reviewer ok 5
...
agent-reviewer DENIED by team-research BudgetExceeded
   Budget exhausted for team-research. Ask whoever set this budget to raise it, or wait for the next reset.
```

The drafter is stopped by its own cap and the reviewer is not affected. Later the reviewer is stopped by the team, with budget of its own still unspent, because the binding constraint is whichever level runs out first.

**6. Respond to the right person**

Use `deniedBy` and `remedy` to decide how to respond:

| Decision | Meaning | Response |
| - | - | - |
| `deniedBy` is the agent, `remedy: 'raise-budget'` | The agent's own cap | Notify the agent's owner, or pause just this agent |
| `deniedBy` is the team, `remedy: 'raise-budget'` | The team's cap | Notify the team admin |
| `reason: 'InsufficientCredits'`, `remedy: 'top-up'` | The customer's credit pool is empty | Offer the account owner to buy more credits with a [top-up](/documentation/modeling-your-pricing-in-stigg/credits/self-service-top-up) |

Raise a budget by calling `register()` again with a new `budget.limit`, or in the Stigg app (see [Edit an entitlement value inline](/documentation/governance/setting-up#edit-an-entitlement-value-inline)). Denied access is never cached, so the next call goes through.

**7. See it in Stigg**

Open `customer-acme` in the Stigg app to see current usage and limits for the team and for each agent. To build the same view in your product, use the [governance query API](/documentation/governance/query).

## Going to production

* Checks for an agent are never cached: each one asks Stigg, so a cap is enforced on the first call that exceeds it, even across several servers. See [Caching and accuracy](/documentation/ai-agents/access-enforcement#caching-and-accuracy).
* Decide what a call should do when a check cannot complete, with `checkErrorAction`. See [Fallback strategy](/documentation/ai-agents/access-enforcement#fallback-strategy).
* Start with `budget: { entitlement, limit: null }` to observe usage per agent before you enforce. See [Observe-only rollout](/documentation/ai-agents/usage-governance#observe-only-rollout).


## Related topics

- [Meter LLM token usage](/guides/ai-agents/meter-llm-token-usage.md)
- [AI agents](/documentation/ai-agents/overview.md)
- [Usage governance](/documentation/ai-agents/usage-governance.md)
- [Access enforcement](/documentation/ai-agents/access-enforcement.md)
- [Agent SDK](/api-and-sdks/references/sdk/backend/rest/agent-sdk.md)


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