Your first API call, with a spending cap
Set a hard monthly cap on a separate project before you create a key, keep the key in an environment variable, make one call with curl and Python, and turn the usage fields into a cost. Anthropic and OpenAI side by side, Gemini in one line.
- What this is
- How to send a request to an AI model from your own script instead of a chat app, with a firm monthly limit on what it can cost.
- Why it matters
- You avoid a surprise bill or a leaked secret key while you try out calling a model from code.
- The short version
- Create a separate project with a monthly cap that actually stops requests before you create a key for it.
- On OpenAI turn on Enforce a hard limit; on Anthropic use a new workspace, since the Default Workspace takes no limit.
- Keep the key in an environment variable, cap reply length, and check your computed cost against the usage page next day.
On this page
- Short answer
- Step 1. A separate project with a hard cap
- Step 2. A key that only reaches that project
- Step 3. Put the key in an environment variable
- Step 4. One call with curl
- Step 5. The same call in Python, with its cost
- Reading the usage fields
- If a key leaks
- How to tell it worked
- Limits
- Try this next
- Sources
- Changes
Use it when you have used chat apps and now want to call a model from a script, without a surprise bill or a leaked key.
Not when a chat plan already does the job. A script is worth it for repeated or bulk work, such as classifying a few hundred items.
You need a vendor account with billing set up, a terminal, and Python 3 if you want the Python version. About 30 minutes. The order of the steps is our suggestion. The settings, field names and prices are from the vendors' docs, read on 2026-10-10.
Short answer
Make the cap before the key. Create a separate project, set a monthly limit on it that actually stops requests, then create a key that can only reach that project. The trap: on OpenAI a spend limit only sends alerts until you turn on Enforce a hard limit. On Anthropic you cannot set a limit on the Default Workspace, so make a new one.
Step 1. A separate project with a hard cap
| Anthropic (Claude Console) | OpenAI (API Platform) | |
|---|---|---|
| Separate space | Settings > Workspaces > Create workspace. Only organization admins can create one. | Project menu (top left) > Create project. Only organization owners can create one. |
| Cap on that space | Select the workspace under Settings > Workspaces, then Spend limits. You can also set alerts at thresholds. | Project settings > Limits > Spend > Edit spend limit, enter a Monthly spend limit, turn on Enforce a hard limit, Save. |
| Cap on the whole account | Settings > Billing > Spend limits > Set limit (or Adjust limit). It cannot exceed your tier's cap. | Organization limits page > Spend > Edit spend limit, with Enforce a hard limit on. |
| Hard cap or alert? | Hard. At a limit you set, requests fail with HTTP 400 and a message that begins "You have reached your specified ... API usage limits". | Hard only with the toggle on. Alerts alone "do not enforce a cap". At a hard limit, requests fail with HTTP 429 and project_spend_limit_exceeded (or organization_spend_limit_exceeded). |
| Catch | No limits on the Default Workspace. Each tier also has its own monthly cap, for example $500 on Start; at it, requests return HTTP 429 with enforced_spend_limit_reached until the 1st of next month (UTC). | "Enforcement is not instantaneous", so spend can slightly exceed the limit. OpenAI's projects help article still calls the limit a soft threshold in one paragraph; the spend limits guide is newer and describes the toggle. |
On OpenAI you can also pick which models a project may use, under Limits > Model Usage. Allowing only the small model below is a second guard.
Step 2. A key that only reaches that project
| Anthropic | OpenAI | |
|---|---|---|
| Where | Settings > API keys > Create key. Name it, choose an expiration, set Linked account, and choose the workspace from step 1. | Organization settings > your project > API Keys. Permissions can be All, Restricted or Read Only. |
| Expiry | Presets of 3 hours, 1, 7 or 30 days, a custom length, or Never. It cannot be changed later. | Project keys can have an expiration date, after which requests are rejected. |
| Shown once? | Yes. The full key (it starts sk-ant-) is shown only at creation. | Not stated on the pages we read. Copy it at creation to be safe. |
Choose 30 days or less for a first key (our suggestion). Copy it straight into your password manager, as Privacy settings pass says. Never paste a key into a chat, an email, a notes file or a script. Each person should have their own key; OpenAI says sharing keys breaks its terms of use.
Step 3. Put the key in an environment variable
Both SDKs read the key from an environment variable, so it never appears in your code: ANTHROPIC_API_KEY for Anthropic and OPENAI_API_KEY for OpenAI. On macOS or Linux, this asks for the key without showing it and without saving it in your shell history (our suggestion):
read -rs ANTHROPIC_API_KEY && export ANTHROPIC_API_KEY
read -rs OPENAI_API_KEY && export OPENAI_API_KEY
Paste the key when the cursor waits, then press Enter. It lasts until you close the terminal. For anything that runs unattended, both vendors recommend a secrets manager instead.
Step 4. One call with curl
We use each vendor's small, cheap model: claude-haiku-5-5 and gpt-6-luna.
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-d '{"model": "claude-haiku-5-5", "max_tokens": 1000,
"messages": [{"role": "user", "content": "<YOUR_PROMPT>"}]}'
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{"model": "gpt-6-luna", "max_output_tokens": 1000,
"input": "<YOUR_PROMPT>"}'
Replace the following:
<YOUR_PROMPT>: a short test, such asName three uses of a paperclip.Nothing private: see What not to paste.
max_tokens and max_output_tokens cap the length of each reply, and so the cost of each call. The variable name in the command is expanded by your shell, so the key itself is never typed into the command.
Step 5. The same call in Python, with its cost
Install the SDK in a virtual environment: pip install anthropic or pip install openai. The prices below are per million tokens for these two models, for prompts up to 100,000 tokens on Haiku 5.5 and short context on luna.
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-haiku-5-5",
max_tokens=1000,
messages=[{"role": "user", "content": "<YOUR_PROMPT>"}],
)
for block in message.content:
if block.type == "text":
print(block.text)
u = message.usage
cost = (u.input_tokens * 0.10 + u.output_tokens * 0.50) / 1_000_000
print(u.input_tokens, "in,", u.output_tokens, "out, about $" + f"{cost:.7f}")
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-luna",
max_output_tokens=1000,
input="<YOUR_PROMPT>",
)
print(response.output_text)
u = response.usage
cost = (u.input_tokens * 0.10 + u.output_tokens * 0.50) / 1_000_000
print(u.input_tokens, "in,", u.output_tokens, "out, about $" + f"{cost:.7f}")
The curl and Python calls are our suggestion; we could not run them without an API key.
Reading the usage fields
Anthropic usage | OpenAI usage | |
|---|---|---|
| Input | input_tokens: only the tokens after the last cache breakpoint. Total input is input_tokens + cache_creation_input_tokens + cache_read_input_tokens. | input_tokens, with input_tokens_details.cached_tokens for the cached part. OpenAI's caching guide counts the cached part inside input_tokens. |
| Output | output_tokens, with output_tokens_details.thinking_tokens for reasoning, which is never more than output_tokens. | output_tokens, with output_tokens_details.reasoning_tokens. Reasoning tokens are billed as output. |
| Total | Not given; add the parts. | total_tokens. |
Cost = input tokens × input price ÷ 1,000,000 + output tokens × output price ÷ 1,000,000. An example (illustrative): 15 input and 120 output tokens on either model cost 15 × $0.10 / 1M + 120 × $0.50 / 1M = $0.0000615. A thousand such calls cost about 6 cents.
| Model (2026-10-20) | Input per 1M | Output per 1M | Batch |
|---|---|---|---|
claude-haiku-5-5 | $0.10 ($0.50 if the prompt is over 100,000 tokens) | $0.50 ($2.50 over 100,000) | 50% off |
gpt-6-luna | $0.10 short context ($0.20 long) | $0.50 ($0.75 long) | Half price, results within 24 hours |
gemini-3.1-flash-lite | $0.25 (text, image, video) | $1.50 | $0.125 / $0.75 |
Put in your own call to see how far a cap goes. It starts on the example above.
Cheaper later. If you can wait for results, batch pricing is half (the Batch column). Prompt caching pays only when many calls share a long, identical opening; a first test call is far below the minimum.
Gemini. Same pattern: a project cap at Spend > Monthly spend cap in AI Studio (labelled experimental), the key in GEMINI_API_KEY, and the paid tier for anything private, since Google says free-tier use may be used to improve its products.
If a key leaks
- Disable or delete it now. Anthropic: Settings > API keys, where Disable can be undone and Delete cannot. OpenAI: rotate it on the API Keys page. Gemini: create a new key, deploy it, then disable the leaked one.
- Replace it in your environment and any running job.
- Check usage and billing for calls you did not make. OpenAI asks you to contact it through help.openai.com for anything further.
GitHub's secret scanning partner programme scans public repositories and alerts the provider, and Anthropic and OpenAI are both partners. Do not rely on it: a key can be used before anyone revokes it.
How to tell it worked
- The project or workspace shows a monthly limit, and on OpenAI Enforce a hard limit is on.
- The key's page shows it scoped to that project, with an expiry date.
- Searching your project folder for the first ten characters of the key, such as
grep -r "<KEY_START>" ., finds nothing. - Both calls printed a reply and two token counts, and your computed cost matches the usage page the next day.
- You know the error you will see at the cap: HTTP 400 on Anthropic, HTTP 429
project_spend_limit_exceededon OpenAI.
Limits
Try this next
- Run the same ten tasks through the small model and your usual one, and compare: Test any new model on your own tasks.
- Set a calendar reminder for the day your key expires.
Sources
- Anthropic. Rate limits and spend limits. Vendor documentation. Link
- Anthropic. Workspaces. Vendor documentation. Link
- Anthropic. Get an API key, and Authentication. Vendor documentation. Link · Link
- Anthropic. Models overview, Pricing, Create a message, Prompt caching. Vendor documentation. Models · Pricing · API · Caching
- OpenAI. Spend limits, and Production best practices. Vendor documentation. Link · Link
- OpenAI. Managing projects, and Best practices for API key safety. Help centre. Link · Link
- OpenAI. Quickstart, Models, Pricing, Reasoning, Prompt caching, Batch. Vendor documentation. Quickstart · Models · Pricing · Reasoning · Caching · Batch
- Google. Gemini API billing, API keys and pricing. Vendor documentation. Billing · Keys · Pricing
- GitHub. Secret scanning for partners, and supported patterns. Vendor documentation. Link · Link · 2021 changelog
Changes
- v1.010 Oct 2026first version
- Sources
- 13
- Updated
- 10 Oct 2026
- Last checked
- 20 Oct 2026