Skip to content

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.

BeginnerDevelopers

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.
Illustration of a key card with a masked value leading through a code window with a run button to a response card with text lines, a finish check and short and long usage bars
Illustration: AI Ping

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

  1. 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
    WhereVerdictWhy
    In code (api_key="…")NoLeaks the moment you push the repo or share your screen
    Chats, messengers, issue threadsNoStays in the history, and many people see it
    Environment variable ANTHROPIC_API_KEYGood for developmentThe SDK reads it automatically and it never touches your code
    Your cloud's secrets managerGood for servers and deploymentAccess 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.
  2. 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 code
    import 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.
  3. 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)
    FieldMeaningExample
    contentA list of blocks holding the answer; the text is in blocks whose type is text[{type: "text", text: "…"}]
    stop_reasonWhy generation stoppedend_turn (finished), max_tokens (cut off at the cap), refusal (declined for safety)
    usage.input_tokensTokens in what you sent31
    usage.output_tokensTokens in what came back, including thinking412
    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 code
    if 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.
  4. 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
    StatusError typeMeaningWhat to do
    400invalid_request_errorSomething is wrong with the request's format or contentFix the value the error message points to
    401authentication_errorA problem with the API key (malformed, revoked, expired and so on)Check the environment variable and the key's status
    429rate_limit_errorYou hit a rate limit or a usage limitRetry after a pause; if it persists, check your limits in the Console
    500api_errorAn unexpected error inside Anthropic's systemsRetry after a pause; if it persists, contact support with the request_id
    529overloaded_errorThe API is temporarily overloaded by heavy trafficRetry 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.
  5. 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)
    RequestInput tokensOutput tokensCost
    The short question from step 231412About $0.0084
    A report summary (a long input)3,000600$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

Keep learning

  • How-to guide15 min

    Get structured (JSON) output from an LLM

    Instead of asking for JSON and hoping, define the shape as a schema and get responses your code can use directly. Worked through with a customer-message classifier.

    PracticalDevelopers