API key spending limits: how to stop a leaked key from draining your account
API key spending limits are the last line of defense when a key leaks. A leaked key can run up a bill while you sleep, and the provider usually bills you, not the thief. Set caps and alerts on every paid provider now, use separate keys per environment, and know the revoke-and-rotate steps before you need them.
QUICK CHECKLIST
- Set a spend cap or budget on every paid provider
- Use one key per environment, with low limits on dev
- Turn on budget alerts to an email you read
- Keep keys out of git and out of NEXT_PUBLIC_ vars
- Know your revoke and rotate steps before a spike
- After a leak, rotate. Deleting the file is not enough
Why API key spending limits matter
A paid API key is a credit card with no PIN. Whoever holds the key can call the API, and the usage lands on your invoice. Leaks happen through a committed .env, a key pasted into frontend code, or a build log nobody checked.
You can't always stop a leak. You can control how much it costs. That is what API key spending limits do: they turn "unlimited bill" into "annoying but survivable."
How a leaked key turns into a bill
Attackers and bots scan public repos and websites for key patterns. Once they have a working key, they run it as hard as the provider allows. For an AI API, that means as many requests as your rate limits permit. For a cloud account, it can mean spinning up resources you never asked for.
Two things decide how bad it gets: how fast the key can spend, and how long before you notice. Rate limits, spend caps and budget alerts attack both. If you already suspect a leak, start with the leaked API key guide.
A few facts from the provider docs:
- Anthropic enforces a monthly spend cap per usage tier, and you can set your own lower limit on the Billing page in the Claude Console. When you hit a limit you set, requests return HTTP 400 with an
invalid_request_error. - If you hit your tier's cap, API requests return HTTP 429 until the next month starts (00:00 UTC on the first day), unless you request a higher limit.
- OpenAI's docs list rate limits (requests and tokens per minute and per day) and a separate section on spend limits. Check the current docs for how to set yours, since the dashboard layout changes.
Provider-by-provider caps and alerts
Each provider calls this something different. Here is what the fetched docs actually say, so you know what to look for in your own dashboard.
| Provider | What the docs say | What to do |
|---|---|---|
| Anthropic | Monthly spend cap per usage tier. You can set your own lower limit on the Billing page. Hitting your own limit returns HTTP 400. | Set your own limit below the tier cap. |
| OpenAI | Rate limits (RPM, TPM, daily) apply. The docs have a Spend limits section. Dashboard labels may change. | Set a spend or usage limit in the platform, and check current docs. |
| Stripe | Restricted keys (rk_) take permissions you choose. Keys can be rolled or expired in the Dashboard. | Use restricted keys per integration. Roll after exposure. |
| AWS | AWS Budgets tracks cost and usage and sends alerts by email or SNS when actual or forecast spend crosses a threshold. | Create a monthly cost budget with alerts. |
| Google Cloud | Budgets track spend against an amount you set and can send alerts. Check the docs for details. | Create a budget and alert thresholds on the billing account. |
Based on the linked provider docs. Check each page for the current setup screens.
Wrong setup vs. safer setup
The common setup is one production key, used everywhere, with no cap and no alert. The safer setup splits keys by environment and puts a ceiling on each.
# .env used by local, preview and production OPENAI_API_KEY=YOUR_KEY # same key everywhere # no cap, no alert, no owner
# .env.local (dev key, low cap) OPENAI_API_KEY=YOUR_DEV_KEY # production: set in host secret store # OPENAI_API_KEY=YOUR_PROD_KEY (own cap and alert)
The code change is small. The real work happens in each provider's dashboard: create a separate key (or project) per environment, then set a low limit on the dev one. For Stripe, prefer restricted keys over full secret keys; Stripe's docs say restricted keys let you limit the damage if someone gets hold of your key.
If your keys might also be exposed in the browser, read NEXT_PUBLIC_ environment variables and hide API key in React.
How to set API key spending limits, step by step
Do this once per paid provider. It takes about 15 minutes in total.
List every paid key you have
Open your
.env, hosting dashboard and CI secrets. Write down each provider and which environment uses which key.Create one key per environment
Production, preview and local dev each get their own key. If the provider supports projects or workspaces, use those too. Anthropic's docs say you can set limits per workspace.
Set a hard cap where the provider offers one
On Anthropic, set your own spend limit on the Billing page in the Claude Console (it can't exceed your tier's cap). For OpenAI, find the spend or usage limit settings in the platform docs section on rate limits and spend. Pick a number you can afford to lose, not a number you expect to use.
Set budget alerts everywhere a hard cap doesn't exist
AWS Budgets and Google Cloud budgets are alerts, not shutoffs by default. AWS Budgets can notify you by email or Amazon SNS when actual or forecasted spend crosses a threshold. Send alerts to an address you check daily.
Lock down Stripe keys
Use restricted keys (rk_...) with only the permissions each integration needs. Store them in your host's secret store, not in source code. Stripe also lets you roll or expire keys from the Dashboard.
Write down your revoke-and-rotate steps
For each provider: where to revoke a key, where to create a new one, and where the key is used in your app. When a spike hits, you want a checklist, not a search.
Pick caps from your real usage. If you spend $20 a month on an API, a $50 cap is plenty of room and a very different outcome from "no cap at all."
After a spend spike: revoke, rotate, then clean up
If a bill jumps or an alert fires, move in this order:
- Revoke the key in the provider dashboard. Do this first.
- Create a new key and put it in your host's secret store.
- Redeploy so the app uses the new key.
- Check usage logs for what the old key did.
- Contact the provider's support if you need to dispute charges.
Only then worry about the code. Deleting the key from a file does not remove it from your git history. Anyone who cloned or forked the repo, or any scraper that grabbed it, still has the old commit. The key is burned the moment it was public, so rotate it. To see what's in your history, use the find secrets in git history guide. If a platform you use was breached, follow rotating API keys after a host breach.
Test it yourself
Only test your own accounts and apps.
- Search your repo for key patterns, including old commits:
git log -p -S "sk-" --allfinds commits that added or removed that string. Swap insk_live_,AKIAor your provider's prefix. - Search your built frontend: open your site, view source or the Network tab, and look for the key. If you can see it, anyone can.
- Check that each environment's key differs. Run
env | grep -i keylocally and compare with the production value in your host's dashboard. They should not match. - Trigger your alert. Set a very low budget temporarily on a test project and confirm the email arrives.
Bad result: the same key everywhere, no cap, no alert, or a key visible in the browser. Good result: separate keys, a cap or alert on each, and nothing secret in the bundle.
Fix prompt you can paste
Give this to Cursor or Claude Code:
Audit this repo for paid API keys and cost risk. 1. Find every place we read API keys (OpenAI, Anthropic, Google, Stripe, AWS, GCP). Report file and line. 2. Flag any key used in client-side code, committed in a file, or prefixed NEXT_PUBLIC_. 3. Check that dev, preview and production use different env var values. List which env var names each environment needs. 4. Add rate limiting and a per-user usage cap on any route that calls a paid AI API. 5. Do not print or invent real keys. Use placeholders like sk_test_xxx. 6. Explain every change and list the provider-dashboard steps I still have to do by hand (spend caps, budgets, key rotation).
The last point matters. Your AI tool can't set a cap in a provider dashboard for you. See also the vibe coding security checklist. If you want a scan of your own repo, Leakcade checks for exposed secrets.
Further reading
- OpenAI: Production best practices
- OpenAI: Rate limits
- OpenAI Help: Troubleshooting API usage and spend limits
- Anthropic: Rate limits and spend limits
- Stripe: API keys
- AWS: Managing your costs with AWS Budgets
- Google Cloud: Budgets and budget alerts
FAQ
How do I set an OpenAI API spending limit?
OpenAI's platform docs cover rate limits and a separate section on spend limits. Dashboard labels change, so open the current docs and the usage and limits pages in your OpenAI account. Use a separate project or key for dev if the platform offers it.
What are the Anthropic usage limits?
Anthropic has spend limits (a monthly cost cap per tier) and rate limits (requests and tokens per minute). You can set your own spend limit below your tier's cap on the Billing page in the Claude Console. Reaching a limit you set returns HTTP 400.
My leaked API key spent money. What do I do first?
Revoke the key at the provider right away, then create and deploy a new one. After that, check usage logs and ask the provider's support about the charges. Deleting the key from your repo does not undo the leak, because git history keeps it.
Are AWS and Google Cloud budgets hard caps?
AWS Budgets is built to track cost and usage and send alerts, and can trigger actions you configure. Treat budgets as early warnings. Read each provider's docs for what happens at the threshold, and don't assume a budget stops spending by itself.
Is deleting the key from my repo enough?
No. Anyone who cloned the repo, or a bot that scraped it, may still have the key, and old commits still contain it. Revoke and rotate the key. Then look at your history with a tool or a git search.
Want a second pair of eyes?
We review your whole repo and write a fix prompt for every finding. $19, report within an hour.
Check my repoLeakcade is an automated check. It can miss vulnerabilities and is not a substitute for a professional security audit or pentest. Provided as is. You stay responsible for your code. Where the law allows, our liability is limited to what you paid ($19). Terms