Your first LLM API call: from key to response
Using the Claude API as the example: keep your API key safe, send a first request from Python, and read the answer, the stop reason and the token usage.
14 minAs of Oct 2026
By the end of this guide
- Pass your API key through an environment variable instead of writing it into code.
- Send a first request with the Python SDK and pick out the text, stop_reason and usage from the response.
- Tell 401, 429 and 529 errors apart, and work out what a request costs from its usage.
Who this is for
- Developers who have used chat assistants but never called an LLM API themselves
- Anyone adding an LLM feature to an internal tool or a product
What you need
- Python 3 (a recent version) and a terminal
- A Claude Console account and an API key (a paid API billed by usage)
- Reading "Tokens and pricing, explained simply" first will make step 5 easier.
Step by step
Create a key and keep it out of your code
To use an LLM through an API you first need an API key. For the Claude API, sign up for the Claude Console and create a new key there. Every request made with that key is billed to your account, so treat it like a password.
Don't write the key into your code. Put it in an environment variable called ANTHROPIC_API_KEY instead: the official SDK reads it automatically, so not a single character of the key ends up in your code.
Where an API key should and shouldn't live Where Verdict Why In code (api_key="…") No Leaks the moment you push the repo or share your screen Chats, messengers, issue threads No Stays in the history, and many people see it Environment variable ANTHROPIC_API_KEY Good for development The SDK reads it automatically and it never touches your code Your cloud's secrets manager Good for servers and deployment Access and key rotation are managed in one place Check it
- In a macOS or Linux terminal, set it with export ANTHROPIC_API_KEY="your-key", then run python3 -c "import os; print('ANTHROPIC_API_KEY' in os.environ)" and check that it prints True. Never print the key itself.
- If you think a key has leaked, delete it in the Console straight away and create a new one.
Install the SDK and send a first request
Create a virtual environment in your project folder and install the official Python SDK, anthropic. Every request needs three things: which model to send it to (model), the longest answer you'll accept (max_tokens) and what you're asking (messages).
If writing it from scratch feels daunting, ask an AI coding assistant, giving it clear conditions as below. Then compare what you get, line by line, with the get-started example in the official docs.
Example prompt I'm calling the Claude API from Python for the first time. My API key is in the ANTHROPIC_API_KEY environment variable. Write the shortest code that uses the official anthropic SDK to ask the claude-opus-5-5 model "List three things every reply to a customer complaint should include." and prints only the text of the answer. Include the install commands, and explain what each part of the code does.
Example AI reply First create and activate a virtual environment and install the SDK: python3 -m venv .venv, then source .venv/bin/activate, then pip install anthropic.
Save the code below as first_call.py and run python first_call.py to print the answer.
Example codeimport anthropic client = anthropic.Anthropic() # reads the ANTHROPIC_API_KEY environment variable message = client.messages.create( model="claude-opus-5-5", max_tokens=1000, messages=[ {"role": "user", "content": "List three things every reply to a customer complaint should include."} ], ) for block in message.content: if block.type == "text": print(block.text)anthropic.Anthropic()- Creates the client. With no key passed in, it reads the ANTHROPIC_API_KEY environment variable.
model="claude-opus-5-5"- The model that handles the request. Models differ in capability, speed and price, so pick one from the model list in the official docs.
max_tokens=1000- The cap on output, in tokens. Tokens the model spends thinking before it answers count toward it too, so don't set it too low.
messages=[{"role": "user", ...}]- The list of messages. The API doesn't remember earlier requests, so to follow up you send the previous question and answer in the list as well.
block.type == "text"- The response content is a list of blocks. Other kinds, such as a thinking block for the model's reasoning, can be mixed in, so it prints only the text blocks.
Check it
- If an answer prints, your first call worked. If you get an error, look up its status code in the table in step 4.
- A variable set with export only lasts in that terminal window. If a new window gives you a 401, rerun the check from step 1.
Read the text, stop reason and usage
Besides the answer itself, the response carries information your product will need. Make a habit of checking stop_reason and usage from the start.
If stop_reason is max_tokens, the answer hit the cap and was cut off midway. Catch that in code so a truncated answer never reaches your users.
Fields to check first in a response (example values) Field Meaning Example content A list of blocks holding the answer; the text is in blocks whose type is text [{type: "text", text: "…"}] stop_reason Why generation stopped end_turn (finished), max_tokens (cut off at the cap), refusal (declined for safety) usage.input_tokens Tokens in what you sent 31 usage.output_tokens Tokens in what came back, including thinking 412 Example prompt Add two things to the previous code: 1) Print a warning if the answer was cut off at max_tokens 2) Print the input and output token counts at the end
Example AI reply Add this below the for loop that prints the answer.
Example codeif message.stop_reason == "max_tokens": print("[Warning] The answer was cut off at max_tokens.") print("Input tokens:", message.usage.input_tokens) print("Output tokens:", message.usage.output_tokens)message.stop_reason == "max_tokens"- Checks whether the answer hit the cap. A normal finish is end_turn.
message.usage.input_tokens- The number of tokens you sent.
message.usage.output_tokens- The number of output tokens. It can be larger than the visible answer (see step 5).
Check it
- Change max_tokens to 50 and run it again. If the warning appears, cut-off answers are being caught. Set it back afterwards.
When it fails, start with the status code
When a request fails, the API returns an HTTP status code along with an error type and a message. The status code alone usually tells you whether to fix your request or simply try again later.
The official SDK automatically retries temporary failures, such as connection errors, 429s and 5xx errors, twice by default. If it still fails, catch the error, tell the user, and log the request_id that comes with it: it makes the cause much easier to trace if you contact support.
Common errors and what to do Status Error type Meaning What to do 400 invalid_request_error Something is wrong with the request's format or content Fix the value the error message points to 401 authentication_error A problem with the API key (malformed, revoked, expired and so on) Check the environment variable and the key's status 429 rate_limit_error You hit a rate limit or a usage limit Retry after a pause; if it persists, check your limits in the Console 500 api_error An unexpected error inside Anthropic's systems Retry after a pause; if it persists, contact support with the request_id 529 overloaded_error The API is temporarily overloaded by heavy traffic Retry after a pause Example prompt I ran my first-call code and got this error. What's the cause, and what should I check, in order? anthropic.AuthenticationError: Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}}Example AI reply A 401 authentication_error means the API didn't accept the key you sent. Check your key setup before the code.
1) Is the variable set in this terminal? If the check command from step 1 prints False, run export again.
2) Is the value intact? Make sure no part of the key went missing when you copied it, and that no spaces or quotes crept in at either end.
3) Is the key still active? In the Console's key list, check that it hasn't been deleted, disabled or expired. If it has, create a new key and set it again.
Check it
- Run ANTHROPIC_API_KEY=wrong python first_call.py to use a bad key for that one command. You'll see how your code behaves on a 401 before it happens for real.
Work out the cost from usage
Cost is the token counts in usage multiplied by the model's prices. claude-opus-5-5 costs $4 per million input tokens and $20 per million output tokens (price list as of October 2026). As a formula: cost in dollars = input tokens × 4 ÷ 1,000,000 + output tokens × 20 ÷ 1,000,000.
This model can think before it answers, and thinking tokens are billed as output tokens. So even a short visible answer can come with a sizeable output_tokens. For simple jobs, output_config={"effort": "low"} cuts down the thinking and saves both money and time.
Cost of one request (claude-opus-5-5; token counts are examples) Request Input tokens Output tokens Cost The short question from step 2 31 412 About $0.0084 A report summary (a long input) 3,000 600 $0.024 Check it
- Run the report summary 1,000 times a day and it's $24 a day, or $720 over 30 days. Estimate a month from your expected call volume before you ship.
- Check real charges on the Console's usage page after a few days of use. Prices can change, so use the current price list every time you calculate.
Common mistakes
- Pushing code to a repository with the API key written in it
- Skipping the stop_reason check and showing cut-off answers to users
- Estimating cost from the input price alone, leaving out output and thinking tokens
References
- Get started with Claude — Claude Platform Docs (Anthropic)
- Claude API errors — Claude Platform Docs (Anthropic)
- Steering thinking — Claude Platform Docs (Anthropic)
- Pricing — Claude Platform Docs (Anthropic)