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.

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, 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.
2curl 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
1from openai import OpenAI
2import os
3
4client = OpenAI(
5 base_url="https://api.relayswitch.io/v1",
6 api_key=os.environ["RELAYSWITCH_API_KEY"],
7)
8from openai import APIStatusError
9
10try:
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
16except 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.

ModelA turnTurns under $5 a dayA day (150 turns)A month (20 days)
Claude Opus 5.5$0.0326153$4.89$97.80
Claude Sonnet 5.5$0.0129387$1.94$38.70
GPT-6.1 Sol$0.0105476$1.58$31.50
DeepSeek V4.1 Flash$0.000895,617$0.1335$2.67
GLM 5.3$0.0076654$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.

StatusCodeMeansClears when
402key_budget_exhaustedThe key’s own prepaid budget is used up.budget_usd is raised, or another key is used.
402daily_limit_reached / weekly_limit_reached / monthly_limit_reachedThe 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.
402insufficient_balanceThe account balance cannot cover the request.A top-up lands.
429rate_limitedThe key’s rpm, tpm or concurrency, or the account’s concurrency.retry-after seconds pass.
429session_cap / loop_detectedA 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.
FAQs

Questions

For agent builders.

Open the console

A key in under a minute

Get a key

Or email 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.