§15.01

Your First Claude API Request: curl, Python, Node

Get a key, set ANTHROPIC_API_KEY, and make a working Messages API call in curl, Python, and Node — then read the response properly.

published 06 Sept 2026 checked against docs 06 Sept 2026 3 min in Building with the API Markdown

Step 1 of 6 · Build with the Claude API

On this page6 sections
  1. 1. Key and environment variable
  2. 2. curl
  3. 3. Python
  4. 4. Node
  5. 5. Read the response
  6. Picking a model

Everything in the Claude API goes through one endpoint: POST https://api.anthropic.com/v1/messages.

1. Key and environment variable

Create a key in the Claude Console under Settings → API keys, then export it. Never hardcode it in source or commit it:

export ANTHROPIC_API_KEY="your-api-key-here"

That puts the key where every Anthropic SDK looks by default — no api_key= argument needed anywhere below.

2. curl

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1000,
    "messages": [{"role": "user", "content": "Explain HTTP 429 in one sentence."}]
  }'

Sends one user turn and returns a JSON message. anthropic-version and max_tokens are both required — omit either and you get a 400.

3. Python

pip install anthropic
import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY

message = client.messages.create(
    model="claude-opus-5",
    max_tokens=1000,
    messages=[{"role": "user", "content": "Explain HTTP 429 in one sentence."}],
)

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

The same call through the SDK, with retries and timeouts handled for you.

4. Node

npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";

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

const message = await client.messages.create({
  model: "claude-opus-5",
  max_tokens: 1000,
  messages: [{ role: "user", content: "Explain HTTP 429 in one sentence." }],
});

const text = message.content.find((b) => b.type === "text");
console.log(text.text);

Identical request shape — the SDKs are thin wrappers over the same JSON.

5. Read the response

{
  "id": "msg_013mHbppMPd2PrVJzGMZPt2D",
  "model": "claude-opus-5",
  "role": "assistant",
  "content": [{ "type": "text", "text": "..." }],
  "stop_reason": "end_turn",
  "usage": { "input_tokens": 21, "output_tokens": 305 }
}

content is an array of blocks — check type before touching .text, because a reply can also contain thinking or tool_use blocks. stop_reason: "end_turn" means Claude finished; "max_tokens" means you truncated it.

Picking a model

claude-opus-5 is the current general recommendation; claude-sonnet-5 is cheaper and faster, claude-haiku-4-5 cheaper still. Model IDs change — take the exact string from the models page rather than copying an old one.


Next: tool use · streaming responses.

← All Building with the API plates · Search all guides

↑↓ move↵ openalt+↵ copy first command

Keyboard

⌘/ctrl+K or /
Search all guides
alt+↵
In search: copy the guide's first command
j / k
Move through a list of guides
c
On a guide: copy its first command
t
Toggle light / dark
?
This list