---
title: "Key budgets: a spend limit per API key"
canonical: https://relayswitch.io/features/key-budgets
generated: 2026-11-02T10:07:26.384Z
source: https://api.relayswitch.io/v1/catalog
base_url: https://api.relayswitch.io/v1
---

Key budgets

# A budget per key, and a limit per day.

Every agent gets its own key with a prepaid budget, a spend limit per period, rate and concurrency caps, an allowed-model list and an expiry. When it reaches its line it gets a 402, nothing is charged, and the rest of your balance is untouched.

[Get an agent key](https://app.relayswitch.io/console)[Code](#example)

Key fields, from the OpenAPI document (2026-10-31)

budget\_usd

a total, out of your balance

spend\_limit\_period

daily, weekly or monthly

rpm

1 to 100,000

tpm

1 to 50,000,000

concurrency

1 to 10,000

allowed\_models

up to 100 ids

user\_budget\_usd

per end user, per period

allowed\_ips

IPv4, IPv6 or CIDR, up to 50

Over the line

402, nothing charged

## What it does for an agent

A prepaid budget

budget\_usd is a hard cap for that key alone, carved out of your balance. Once its charges plus open holds reach it, the key gets 402 key\_budget\_exhausted until it is raised.

A spend limit per period

monthly\_cap\_usd is dollars per spend\_limit\_period: a UTC month unless set, or daily (resets 00:00 UTC) or weekly (Monday 00:00 UTC). The counter restarts each period.

RPM, TPM and concurrency

rpm, tpm and concurrency cap requests a minute, tokens a minute and requests in flight per key. Over any of them: a 429 rate\_limited with retry-after, nothing charged.

Allowed models and expiry

allowed\_models lists up to 100 ids the key may call and nothing else. expires\_at (Unix milliseconds) ends the key on a date you choose.

A budget per end user

user\_budget\_usd with user\_budget\_period (daily, weekly or monthly) caps what one end user of your app can spend on the key: send x-customer-id (or the OpenAI user field) on each request. Over it: 402 user\_budget\_reached for that user only; usage reports group by user.

An IP allowlist and a lifetime cap

allowed\_ips (up to 50 addresses or CIDR ranges) makes the key answer 403 ip\_not\_allowed from anywhere else on the model, endpoint, batch and key-API routes. An owner can set a maximum key lifetime for the organization, and every new key expires within it.

Spend alerts before the line

A key with a budget or a period limit emails the organization at 50, 80 and 100 percent, once per threshold per period; an optional daily spend alert covers the whole account. The same moments can call your webhook (key.budget\_reached, key.limit\_reached, balance.low).

Budget autopilot

Name a cheaper model on the key in the console and it answers near the monthly limit instead of stopping; the response carries x-uplink-autopilot with the model the request asked for.

Session caps and the loop guard

session\_max\_spend\_usd and session\_max\_requests cap one x-session-id run; loop\_guard refuses the same tool call or body sent more than 5 times in 10 minutes.

## Copy, paste, run

Field names from the KeyCreate schema in the [OpenAPI document](https://api.relayswitch.io/openapi.json), read 2026-10-31. The console sets the same fields on a form.

Key API: POST /v1/keys

bash

1`# A key for one agent: its own budget, a daily spend limit, rate caps, two models, gone in 30 days.`

2`curl https://api.relayswitch.io/v1/keys \`

3 `-H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \`

4 `-d '{`

5 `"name": "nightly-agent",`

6 `"budget_usd": 50,`

7 `"monthly_cap_usd": 5, "spend_limit_period": "daily",`

8 `"rpm": 120, "tpm": 2000000, "concurrency": 4,`

9 `"allowed_models": ["claude-sonnet-5-5", "glm-5.3"],`

10 `"fallback_models": ["glm-5.3"],`

11 `"session_max_spend_usd": 1, "loop_guard": true,`

12 `"expires_at": '"$(( $(date +%s) * 1000 + 30 * 86400000 ))"'`

13 `}'`

14`# The secret is returned once; afterwards only its prefix is shown.`

Python: handle the 402

python

1`from openai import OpenAI`

2`import os`

3

4`client = OpenAI(`

5 `base_url="https://api.relayswitch.io/v1",`

6 `api_key=os.environ["RELAYSWITCH_API_KEY"],`

7`)`

8`from openai import APIStatusError`

9

10`try:`

11 `reply = client.chat.completions.create(`

12 `model="claude-sonnet-5-5",`

13 `messages=[{"role": "user", "content": "Run the nightly report."}],`

14 `)`

15 `print(reply.usage.cost) # what this request cost, in dollars`

16`except APIStatusError as e:`

17 `code = e.body["error"]["code"]`

18 `if e.status_code == 402:`

19 `# daily_limit_reached, weekly_limit_reached, monthly_limit_reached:`

20 `# the key's spend limit for its period; it resets on the period.`

21 `# key_budget_exhausted: the key's own budget is used up; raise it.`

22 `# insufficient_balance: the account needs a top-up.`

23 `stop_agent(reason=code)`

24 `elif e.status_code == 429:`

25 `# rate_limited, session_cap or loop_detected; nothing was charged.`

26 `wait(int(e.response.headers.get("retry-after", "5")))`

27 `else:`

28 `raise`

## What a $5 daily limit buys an agent, at today's prices

One agent turn late in a session: 80,000 cached input tokens, 2,000 fresh input tokens and 1,500 output tokens. A day is 150 such turns; a month is 20 working days. Priced from the live catalog at render; cached input at the cached rate where the model has one.

| Model | A turn | Turns under $5 a day | A day (150 turns) | A month (20 days) |
| --- | --- | --- | --- | --- |
| [Claude Opus 5.5](https://relayswitch.io/models/claude-opus-5-5) | $0.0326 | 153 | $4.89 | $97.80 |
| [Claude Sonnet 5.5](https://relayswitch.io/models/claude-sonnet-5-5) | $0.0129 | 387 | $1.94 | $38.70 |
| [GPT-6.1 Sol](https://relayswitch.io/models/gpt-6.1-sol) | $0.0105 | 476 | $1.58 | $31.50 |
| [DeepSeek V4.1 Flash](https://relayswitch.io/models/deepseek-v4.1-flash) | $0.00089 | 5,617 | $0.1335 | $2.67 |
| [GLM 5.3](https://relayswitch.io/models/glm-5.3) | $0.0076 | 654 | $1.15 | $22.92 |

Read the row, set monthly\_cap\_usd to the day you want with spend\_limit\_period "daily", and the agent stops there with a 402. Set budget\_usd to the month and it cannot spend past it whatever the day count. Every request's own charge is in usage.cost and x-uplink-charge.

## The two answers a key over its line gets

From the /v1/chat/completions responses in the OpenAPI document, read 2026-10-31. Neither is charged.

| Status | Code | Means | Clears when |
| --- | --- | --- | --- |
| 402 | key\_budget\_exhausted | The key’s own prepaid budget is used up. | budget\_usd is raised, or another key is used. |
| 402 | daily\_limit\_reached / weekly\_limit\_reached / monthly\_limit\_reached | The key’s spend limit for its period. | The period resets (00:00 UTC, Monday 00:00 UTC, the first of the month) or the limit is raised. |
| 402 | insufficient\_balance | The account balance cannot cover the request. | A top-up lands. |
| 429 | rate\_limited | The key’s rpm, tpm or concurrency, or the account’s concurrency. | retry-after seconds pass. |
| 429 | session\_cap / loop\_detected | A session reached session\_max\_requests or session\_max\_spend\_usd, or repeated one call more than 5 times in 10 minutes. | reset\_at in the error body. |

Agent setup guides

-   [OpenClaw](https://relayswitch.io/guides/openclaw)
-   [Hermes Agent](https://relayswitch.io/guides/hermes-agent)
-   [OpenCode](https://relayswitch.io/guides/opencode)
-   [Claude Code](https://relayswitch.io/guides/claude-code)
-   [n8n](https://relayswitch.io/guides/n8n)

More features

-   [Agent tools](https://relayswitch.io/features/agent-tools)
-   [Files and redaction](https://relayswitch.io/features/files)
-   [Routing](https://relayswitch.io/features/routing)
-   [Caching and compression](https://relayswitch.io/features/caching)
-   [Guardrails and sign-in](https://relayswitch.io/features/guardrails)
-   [MCP gateway](https://relayswitch.io/features/mcp-gateway)
-   [Endpoints](https://relayswitch.io/features/endpoints)
-   [Observability](https://relayswitch.io/features/observability)
-   [Hosted agents](https://relayswitch.io/agents)
-   [Workflows](https://relayswitch.io/workflows)
-   [Docs](https://relayswitch.io/docs)

FAQs

## Questions

For agent builders.

Open the console

A key in under a minute

[Get a key](https://app.relayswitch.io/console)

Or email [hello@relayswitch.io](mailto:hello@relayswitch.io)

### 

### 

### 

### 

### 

### 

### 

### 

## One key per agent, each with its own line

A budget, a daily limit, the models it may call, the day it expires. Card or crypto, no KYC, no subscription.

[All features](https://relayswitch.io/features)[Get an agent key](https://app.relayswitch.io/console)

