# Claude API tutorial: your first call in Python and TypeScript

> The Claude API has one core endpoint, Messages. You send a model id, a `max_tokens` limit and a list of messages, and you get back content blocks, a `stop_reason` and token usage. This tutorial creates an API key in the Console, installs the Python or TypeScript SDK, makes the first call, streams it and reads the result.

Mindket editors · Published 2026-11-04 · Updated 2026-11-05 · https://mindket.com/learn/claude-api/claude-api-quickstart

## In short

- Create an API key and keep it in the ANTHROPIC_API_KEY variable.
- Send a Messages API request from Python or TypeScript with a system prompt.
- Read content blocks, usage and stop_reason instead of assuming one text block.
- Stream a long answer and know which errors the SDK already retries.

## Before you start

You need a [Claude Console](https://platform.claude.com/) account and an API key. In the Console, open [the API keys page](https://platform.claude.com/settings/keys), click **Create key**, name it and pick an expiration. The Console shows the full key, which starts with `sk-ant-`, only once, so copy it into a secrets manager. A personal key stops working when you leave the organization, which is why the docs point shared workloads to a service account key. [Anthropic's key page](https://platform.claude.com/docs/en/get-api-key) covers both types.

The SDKs want Python 3.10 or later, or Node.js 20 LTS or later with TypeScript 5.0 or later. Both read `ANTHROPIC_API_KEY` from the environment by default, so the key never appears in your code. The TypeScript SDK refuses to run in a browser until you set `dangerouslyAllowBrowser`, and the name is fair warning: anyone who can open the page can read the key.

## Make the first call in Python

This is the docs' quickstart with a system prompt and a usage line added. The model id comes from the [models page](https://platform.claude.com/docs/en/models/overview), which is also where you check it before you copy it.

````python
import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY

message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1000,
    system="You are a concise assistant. Answer in three bullet points.",
    messages=[
        {
            "role": "user",
            "content": "What should I search for to find the latest developments in renewable energy?",
        }
    ],
)

for block in message.content:
    if block.type == "text":
        print(block.text)

print(message.stop_reason, message.usage)
````

1. Export the key in the shell that will run the script: `export ANTHROPIC_API_KEY="your-api-key-here"`.
2. Create a project folder and a virtual environment, then install the SDK with `python3 -m venv .venv && source .venv/bin/activate` and `pip install anthropic`.
3. Save the code above as `quickstart.py`.
4. Run `python quickstart.py`. You get the answer text, then one line with the stop reason and the token counts.
5. Change `max_tokens` to 20 and run it again. The answer ends mid-sentence and `stop_reason` reads `max_tokens`.

## The same call in TypeScript

Run `npm init -y`, `npm pkg set type=module` and `npm install @anthropic-ai/sdk`, save the code as `quickstart.ts` and start it with `npx tsx quickstart.ts`, as the quickstart does.

TypeScript keeps the HTTP API's field names, so `max_tokens` and `stop_reason` keep their underscores. The [Messages API reference](https://platform.claude.com/docs/en/api/messages/create) marks `model`, `max_tokens` and `messages` as the required fields.

````typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic(); // reads ANTHROPIC_API_KEY

const message = await client.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 1000,
  system: "You are a concise assistant. Answer in three bullet points.",
  messages: [
    {
      role: "user",
      content: "What should I search for to find the latest developments in renewable energy?"
    }
  ]
});

for (const block of message.content) {
  if (block.type === "text") {
    console.log(block.text);
  }
}

console.log(message.stop_reason, message.usage);
````

## Read the response: blocks, usage and stop_reason

`message.content` is a list of blocks, not a string. A plain answer has one `text` block, but the same list can hold `tool_use` and `thinking` blocks, which is why the quickstart loops and picks the text ones. Writing `content[0].text` works until the day it does not.

`usage` holds `input_tokens` and `output_tokens`, the units the API meters. [What are tokens in AI](https://mindket.com/blog/what-are-tokens-in-ai) explains them. The Python SDK can also count before you send: `client.messages.count_tokens(model=..., messages=[...])` returns `input_tokens`.

`stop_reason` says why generation ended. Check it on every response, because code that only reads text returns a cut-off answer without complaint.

| stop_reason | What happened | What to do |
| --- | --- | --- |
| `end_turn` | Claude finished its answer | Use the response |
| `max_tokens` | The reply hit your `max_tokens` limit | Raise the limit or ask Claude to continue |
| `stop_sequence` | Claude emitted one of your `stop_sequences` | Read `stop_sequence` to see which one |
| `tool_use` | Claude is calling a tool | Run the tool and send the result back |
| `pause_turn` | A server-tool loop hit its iteration limit | Send the assistant content back to continue |
| `refusal` | Claude declined to respond | Read `stop_details`, then retry on a fallback model |
| `model_context_window_exceeded` | The reply filled the context window | Treat the reply as truncated |

## Stream long answers

Waiting for a full reply feels slow and, for large outputs, fails on some networks. The SDK helper sends the request as server-sent events and gives you the text as it arrives. `get_final_message()` in Python, or `finalMessage()` in TypeScript, returns the same `Message` object that a plain call returns.

Streaming is not optional at the top of the range. The Python SDK raises a `ValueError` when a non-streaming request is expected to run past about 10 minutes, and both SDKs advise streaming for any large `max_tokens`.

````python
import anthropic

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
    model="claude-opus-5-5",
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    message = stream.get_final_message()

print()
print(message.stop_reason, message.usage)
````

- The event order is `message_start`, then for each block `content_block_start`, one or more `content_block_delta` and `content_block_stop`, then `message_delta` and `message_stop`. Unknown event types can appear, so ignore what you do not handle ([streaming page](https://platform.claude.com/docs/en/build-with-claude/streaming)).
- `stop_reason` is null in `message_start` and arrives in `message_delta`. The token counts in `message_delta` are cumulative.
- An error can arrive after the API has already sent a 200. It shows up as an `error` event, for example `overloaded_error`, so a streaming loop needs its own error branch.

## Pick a model id and expect it to change

On 5 November 2026 the docs list four current models. Each id is a pinned snapshot with no date in it, and Anthropic commits to keeping each one available at least until the date in the table, for the platforms it runs. The [models overview](https://platform.claude.com/docs/en/models/overview) suggests Opus 5.5 as the starting point for most workloads.

The SDK sends the `anthropic-version` header for you, and a new API version arrives with a new SDK major version. Python SDK 2.0.0 is the first to use `2026-10-21`, and for the TypeScript SDK it is 1.0.0.

All four models shipped within about five weeks, and the API version followed two weeks after the last one. A tutorial written in August names none of them, which is why the [release notes](https://platform.claude.com/docs/en/release-notes/overview) are worth a look before you copy an id.

> **Parameters that now return a 400**
>
> Claude 4.7 and later models reject `temperature`, `top_p` and `top_k`, and on API version 2026-10-21 any value fails. Prefill, ending the request with an assistant message for Claude to continue, returns a 400 on 4.6 and later. Old tutorials use both, so strip them before you debug anything else.

**Claude API releases since September 2026**

1. **September 1, 2026** Claude Fable 5.1 launches. The model for demanding reasoning and long-horizon agent work.
2. **September 22, 2026** Claude Opus 5.5 launches. The model the docs suggest trying first.
3. **September 28, 2026** Claude Sonnet 5.5 launches. The middle of the line, between speed and intelligence.
4. **October 7, 2026** Claude Haiku 5.5 launches. For high-volume work such as classification and routing.
5. **October 21, 2026** API version 2026-10-21. Released with Python SDK 2.0.0 and TypeScript SDK 1.0.0, the first SDK versions that use it.
6. **November 2, 2026** Message threads in beta. Later requests can carry only the new messages instead of the whole history.

Source: [Claude Docs: Release notes](https://platform.claude.com/docs/en/release-notes/overview) (read 2026-11-05)

| Model | API id | Context window | Max output | Retirement |
| --- | --- | --- | --- | --- |
| Claude Fable 5.1 | `claude-fable-5-1` | 1M tokens | 128K tokens | Not sooner than 1 September 2027 |
| Claude Opus 5.5 | `claude-opus-5-5` | 1M tokens | 128K tokens | Not sooner than 22 September 2027 |
| Claude Sonnet 5.5 | `claude-sonnet-5-5` | 1M tokens | 128K tokens | Not sooner than 28 September 2027 |
| Claude Haiku 5.5 | `claude-haiku-5-5` | 1M tokens | 128K tokens | Not sooner than 7 October 2027 |

## Errors, retries and timeouts

Both SDKs raise typed errors for 4xx and 5xx responses and retry some of them. The [Python SDK page](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/python) and the [TypeScript SDK page](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/typescript) give the defaults: two retries with a short exponential backoff for connection errors, 408, 409, 429 and 5xx, and a 10-minute timeout. Change them with `max_retries` in Python or `maxRetries` in TypeScript, and log `message._request_id` on every call, since support asks for it.

The [errors page](https://platform.claude.com/docs/en/api/errors) adds a case a retry cannot fix: a rate-limit error that signals a monthly spend cap. It carries no `retry-after` header and keeps failing until access resumes.

| Status | SDK class | API error type |
| --- | --- | --- |
| 400 | `BadRequestError` | `invalid_request_error` |
| 401 | `AuthenticationError` | `authentication_error` |
| 403 | `PermissionDeniedError` | `permission_error` |
| 404 | `NotFoundError` | `not_found_error` |
| 429 | `RateLimitError` | `rate_limit_error` |
| 500 and above | `InternalServerError` | `api_error`, or `overloaded_error` for a 529 |

## What ClaudeDevs posted when API version 2026-10-21 shipped

ClaudeDevs, the account Anthropic runs for developers, [announced the new version on X](https://x.com/ClaudeDevs/status/2113013247209021918) the day it shipped. It was the first official API version since 2023. Versions will now come more often, so you can deal with a breaking change before a new model forces it on you, and `2023-06-01` is not deprecated.

[The next post in the thread](https://x.com/ClaudeDevs/status/2113013248714744208) lists the changes. Top of the list: `temperature`, `top_p` and `top_k` are gone from the Messages API. Documents in assistant turns and citations in user turns now fail as well.

Search your code for those three parameter names before you move to Python SDK 2.0.0 or TypeScript SDK 1.0.0. Until you do, your current SDK keeps sending the old version.

> We plan to release versions more often so you can handle breaking changes before a new model requires them.
>
> ClaudeDevs, Anthropic's account for developers building with Claude, [X](https://x.com/ClaudeDevs/status/2113013247209021918) (read 2026-11-05)

[![ClaudeDevs (@ClaudeDevs) on X, 21 October 2026: API version 2026-10-21 is now available. The Claude API has evolved a lot, but this is our first official version release since 2023. We plan to release versions more often so you can handle breaking changes before a new model requires them. 2023-06-01 is not deprecated.](https://mindket.com/blog/shots/x-claudedevs-api-version-2026-10-21.webp?v=1107e9f1ff91)](https://x.com/ClaudeDevs/status/2113013247209021918)

ClaudeDevs on X, 21 October 2026

[![ClaudeDevs (@ClaudeDevs) on X, 21 October 2026, replying in the same thread: What changes in this version. temperature, top_p, and top_k are removed from the Messages API. Documents in assistant turns and citations in user turns return a 400. A few deprecated Admin and Enterprise Analytics API fields are replaced.](https://mindket.com/blog/shots/x-claudedevs-sampling-removed.webp?v=3e9e4d9e9771)](https://x.com/ClaudeDevs/status/2113013248714744208)

ClaudeDevs on X, 21 October 2026

> Screenshots of X's own embeds of the posts, taken on 5 November 2026, with the time in UTC. Select one to open the post on X.

## Common mistakes

- Reading `content[0].text`, which breaks the day the first block is a thinking or tool_use block.
- Sending only the newest message. The Messages API is stateless, so every request carries the full history, including earlier assistant turns.
- Copying `temperature` from an older tutorial and having a current model reject the request.
- Shipping the key in browser code. Organizations with zero data retention cannot call the API from a browser at all, and their requests fail with a 401.
- Asking for a huge `max_tokens` without streaming, then blaming the network when the request times out.
- Treating `usage.input_tokens` as the whole input once caching is on. Lesson 3 explains why it is smaller.

## Try it yourself

- Add a second turn: append the assistant reply and a follow-up question to `messages`, then call again and watch `input_tokens` grow.
- Set `stop_sequences=["END"]`, ask Claude to count to ten and finish with END, then read `stop_sequence` on the response.
- Export a wrong key and catch the typed error. Which class do you get, and what is the status code?
- Switch the model id to `claude-haiku-5-5` and compare the latency by eye on the same prompt.

## Next

[Lesson 2](https://mindket.com/learn/claude-api/claude-tool-use) lets Claude call functions you write. The system prompt above is one line, and the [system prompt lesson](https://mindket.com/learn/prompt-engineering/system-prompt) shows how to write a real one. Because you resend the whole history on every call, the [context window lesson](https://mindket.com/learn/prompt-engineering/context-window) explains what that costs you.

## Check yourself

1. A response carries stop_reason "max_tokens". What happened?

   A. Claude refused the request
   B. The reply reached your max_tokens limit and was cut off
   C. A stop sequence matched
   D. The API key ran out of credit

   Answer: B. max_tokens means generation stopped at the limit you set, so raise the limit or ask Claude to continue.

2. Where should the API key live in a script that calls the API?

   A. In the ANTHROPIC_API_KEY environment variable
   B. In the first user message
   C. In client-side browser code
   D. In the model id

   Answer: A. Both SDKs read ANTHROPIC_API_KEY by default, so the key stays out of your code and out of the browser.

3. Why loop over message.content instead of reading content[0]?

   A. The first block is always empty
   B. The SDK sorts blocks by length
   C. Content is a list of blocks that can include tool_use or thinking
   D. Python lists start at 1

   Answer: C. The list can hold several block types, so you pick the text blocks as the quickstart does.

4. A request that sets temperature returns a 400 on a current model. What is the fix?

   A. Raise max_tokens
   B. Switch to the TypeScript SDK
   C. Add a beta header
   D. Remove temperature, top_p and top_k and steer through the prompt

   Answer: D. Claude 4.7 and later models reject the sampling parameters, and API version 2026-10-21 rejects any value.

## Frequently asked questions

### Is the Claude API free?

No. Usage is billed by tokens, and the docs publish a base price per million tokens for each model on their pricing page. This lesson leaves the figures out because they change.

### When should I pick Haiku or Fable instead of Opus?

Haiku suits high-volume, latency-sensitive work such as classification, extraction and routing. Fable is for demanding reasoning and long-horizon agent work, or for when your evals on Opus still fall short at higher effort.

### Why does my request return a 400 when I set temperature?

Claude 4.7 and later models reject `temperature`, `top_p` and `top_k`, and API version 2026-10-21 rejects any value. Remove them and steer behavior through the prompt.

### Can I call the Claude API from a browser?

The TypeScript SDK allows it behind `dangerouslyAllowBrowser`, but that exposes your key to every visitor. Organizations with zero data retention or the Compliance API cannot do it at all, so call the API from your own back end.

### Can I avoid resending the whole history?

Only in beta. Anthropic documents message threads, where later requests send just the new messages and a thread expires five minutes after its last request. Outside that beta, you resend everything, and lesson 4 covers keeping it short.

### Do I need the SDK, or can I use curl?

curl works. POST to `https://api.anthropic.com/v1/messages` with the `x-api-key`, `anthropic-version` and `content-type` headers. The SDK adds retries, typed errors and streaming helpers.

## Sources

- [Anthropic Docs: Get started with Claude](https://platform.claude.com/docs/en/get-started) (read 2026-11-04)
- [Anthropic Docs: Get your Claude API key](https://platform.claude.com/docs/en/get-api-key) (read 2026-11-04)
- [Anthropic Docs: Using the Messages API](https://platform.claude.com/docs/en/build-with-claude/working-with-messages) (read 2026-11-04)
- [Anthropic Docs: Messages API reference](https://platform.claude.com/docs/en/api/messages/create) (read 2026-11-04)
- [Anthropic Docs: Streaming messages](https://platform.claude.com/docs/en/build-with-claude/streaming) (read 2026-11-04)
- [Anthropic Docs: Stop reasons and fallback](https://platform.claude.com/docs/en/build-with-claude/handling-stop-reasons) (read 2026-11-04)
- [Anthropic Docs: Models overview](https://platform.claude.com/docs/en/models/overview) (read 2026-11-05)
- [Anthropic Docs: Claude API errors](https://platform.claude.com/docs/en/api/errors) (read 2026-11-04)
- [Anthropic Docs: Python SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/python) (read 2026-11-04)
- [Anthropic Docs: TypeScript SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/typescript) (read 2026-11-04)
- [GitHub: anthropics/anthropic-sdk-python](https://github.com/anthropics/anthropic-sdk-python) (read 2026-11-04)
- [GitHub: anthropics/anthropic-sdk-typescript](https://github.com/anthropics/anthropic-sdk-typescript) (read 2026-11-04)
- [Claude Docs: Release notes](https://platform.claude.com/docs/en/release-notes/overview) (read 2026-11-05)
- [X: ClaudeDevs announces API version 2026-10-21](https://x.com/ClaudeDevs/status/2113013247209021918) (read 2026-11-05)
- [X: ClaudeDevs lists what changes in API version 2026-10-21](https://x.com/ClaudeDevs/status/2113013248714744208) (read 2026-11-05)

[Browse AI agents](https://mindket.com/agents)
