CCA Study Platformcca.je9.us
๐Ÿ› ๏ธ Developer guide ยท beginner friendly

Build with Claude

From "I've never called an API" to your first working Claude program โ€” in about ten minutes. Plain-English explanations, copy-paste samples in curl, Python and TypeScript, and the current models, errors and gotchas. No prior REST experience assumed.

Everything here uses the live Claude API at api.anthropic.com. Code samples default to claude-opus-4-8, Anthropic's most capable Opus-tier model.

Start here

What is a REST API, really?

An API ("Application Programming Interface") is just a way for your code to ask another computer to do something. A REST API does it over the web, using the same plumbing your browser already uses. Five ideas cover almost everything:

๐Ÿ“ค

Request & response

You send a request to a web address (an endpoint). The server does the work and sends back a response. With Claude: you send a message, Claude sends back a reply. That's the whole loop.

๐Ÿ”€

The method (verb)

Every request has a verb. GET means "read something," POST means "send data and make something happen." Talking to Claude is always a POST โ€” you're sending a message for it to act on.

๐Ÿท๏ธ

Headers

Headers are metadata that ride along with the request โ€” like the envelope around a letter. For Claude they carry your API key (who you are), the API version, and the fact that you're sending JSON.

{ }

JSON โ€” the body

The actual content travels as JSON: a simple text format of "key": value pairs. You send JSON describing your message; Claude replies with JSON containing its answer. Every language can read and write it.

๐Ÿšฆ

Status codes

The response comes with a number. 200 = success. 4xx (like 401, 429) = you need to fix something. 5xx = the server had a problem; retry. We list the ones you'll actually hit below.

๐Ÿ”‘

Authentication

The server needs to know it's really you (and who to bill). You prove it with an API key โ€” a long secret string โ€” sent in a header. Treat it like a password: it never goes in your code or a public repo.

๐Ÿ’ก
That's the entire mental model. A Claude API call is one POST to one endpoint, with three headers and a small JSON body. Everything else โ€” tools, streaming, vision โ€” is just more fields in that same body.
Hands on

Your first Claude program, in three steps

Pick your language with the toggle on each step โ€” the samples stay in sync. Copy, run, done.

1

Get an API key & store it safely

Create a key in the Claude Console, then put it in an environment variable โ€” never in your code.

Sign in at console.anthropic.com โ†’ API keys, create a key (it starts with sk-ant-), and copy it. Then set it as an environment variable so your program can read it without the secret ever appearing in your source:

terminal ยท macOS / Linux
export ANTHROPIC_API_KEY="sk-ant-...your-key..."   # add to ~/.zshrc to persist
โš ๏ธ
Never paste your key into code, a webpage, or a git commit. A leaked key can run up your bill. Read it from the environment (the SDKs do this automatically), and rotate it in the Console immediately if it's ever exposed.
2

Send your first message

One POST to /v1/messages. This is the whole API โ€” learn this and the rest is variations.
Language:
terminal ยท curl
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-4-8",
    "max_tokens": 1024,
    "messages": [
      { "role": "user", "content": "Hello, Claude. In one sentence, what are you?" }
    ]
  }'

No install needed โ€” curl ships with macOS and Linux. This is the rawest form of the call; it shows exactly what every language sends under the hood.

terminal ยท install once
pip install anthropic
first_call.py
import anthropic

# Reads ANTHROPIC_API_KEY from the environment automatically.
client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Hello, Claude. In one sentence, what are you?"}
    ],
)

print(message.content[0].text)

The official SDK handles auth, JSON, retries and timeouts for you. Run it with python first_call.py.

terminal ยท install once
npm install @anthropic-ai/sdk
first-call.ts
import Anthropic from "@anthropic-ai/sdk";

// Reads ANTHROPIC_API_KEY from the environment automatically.
const client = new Anthropic();

const message = await client.messages.create({
  model: "claude-opus-4-8",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Hello, Claude. In one sentence, what are you?" },
  ],
});

const first = message.content[0];
if (first.type === "text") console.log(first.text);

Works with Node.js and TypeScript (plain JavaScript too โ€” same SDK). Run with npx tsx first-call.ts.

What every part means

PartWhat it is
/v1/messagesThe one endpoint you talk to. v1 is the API version path; messages is the "have a conversation" operation.
x-api-keyYour secret key โ€” this is how Anthropic knows it's you and what to bill. (The SDKs read it from the environment so you never type it.)
anthropic-versionPins the API's behavior to a known date so your code doesn't break when the API evolves. Always 2023-06-01.
modelWhich Claude to use. claude-opus-4-8 is the most capable; see Models for cheaper/faster options.
max_tokensThe longest reply you'll allow, in tokens (โ‰ˆยพ of a word each). A safety cap โ€” set it comfortably above what you expect.
messagesThe conversation, as a list. Each entry has a role ("user" or "assistant") and its content. Your first message is always user.
3

Read the response

The reply is JSON. You mostly care about three fields.
response ยท JSON
{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4-8",
  "content": [
    { "type": "text", "text": "I'm Claude, an AI assistant made by Anthropic." }
  ],
  "stop_reason": "end_turn",
  "usage": { "input_tokens": 18, "output_tokens": 12 }
}
FieldWhat to do with it
contentA list of blocks. The text reply is content[0].text. (It's a list because a response can also contain tool calls or thinking โ€” more on that later.)
stop_reasonWhy Claude stopped. "end_turn" = finished normally โœ…. "max_tokens" = ran out of room (raise max_tokens). "tool_use" = it wants to call a tool. Check this before trusting the output.
usageTokens in and out โ€” this is what you're billed on. Handy for tracking cost (see pricing).
๐ŸŽ‰
That's a complete Claude program. You sent a message and read the answer. Everything below makes it more useful โ€” but you already know the core loop.
The everyday toolkit

Four concepts you'll use in almost every app

Samples here are in Python for readability โ€” the shape is identical in every SDK.

System prompt ยท who Claude is

A top-level instruction that sets the role, tone and rules for the whole conversation. It's separate from the user messages and carries the most weight.

system.py
client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system="You are a terse expert. Answer in one sentence, no preamble.",
    messages=[{"role":"user", "content":"What is a REST API?"}],
)

Multi-turn ยท the API has no memory

Each call is independent โ€” Claude remembers nothing between requests. To continue a conversation you resend the whole history every time, appending Claude's last reply.

conversation.py
messages = [
    {"role":"user",      "content":"My name is J."},
    {"role":"assistant", "content":"Nice to meet you, J!"},
    {"role":"user",      "content":"What's my name?"},
]
# Claude only knows "J" because the history is resent.

Streaming ยท tokens as they're written

Instead of waiting for the whole reply, receive it word-by-word โ€” like watching it type. Use it for chat UIs and any long output (it also avoids timeouts).

stream.py
with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role":"user","content":"Write a haiku about APIs."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Choosing a model ยท speed vs. smarts vs. cost

One string swaps the brain. Reach for Opus on hard reasoning, Sonnet for the everyday balance, Haiku when speed and price matter most.

models.py
model="claude-opus-4-8"     # most capable
model="claude-sonnet-4-6"   # balanced workhorse
model="claude-haiku-4-5"    # fastest & cheapest
When you're ready for more

Go further

Each of these is just extra fields on the same /v1/messages call. Tap through to Anthropic's official docs when you need them.

Troubleshooting

When things go wrong

The status code tells you what happened. Here are the ones you'll actually meet, and how to fix each.

CodeMeaningRetry?What to do
400Bad requestnoSomething in your JSON is wrong โ€” a typo, a bad field, messages not starting with user. Read the message in the error; it usually names the field.
401Not authenticatednoYour API key is missing, wrong, or revoked. Check ANTHROPIC_API_KEY is set and current.
403ForbiddennoThe key is valid but lacks access to this model or feature. Check your Console permissions/plan.
404Not foundnoAlmost always a misspelled model ID. Use an exact ID from the table below โ€” e.g. claude-opus-4-8, not claude-opus-4.8.
429Rate limitedyesYou're sending too fast. Wait and retry โ€” the retry-after header says how long. The SDKs back off and retry automatically.
529OverloadedyesAnthropic's side is briefly busy. Retry with a short, increasing delay (the SDKs handle this for you).
๐Ÿ›Ÿ
The official SDKs already retry 429 and 5xx errors with sensible backoff. That's one more reason to use the SDK rather than raw HTTP once you're past your first request.
Reference

Current models & pricing

Swap the model string to change the trade-off. Prices are USD per million tokens (input / output). A token is roughly ยพ of a word.

ModelModel IDContextMax outputInput $/MOutput $/MBest for
Claude Opus 4.8 defaultclaude-opus-4-81M128K$5.00$25.00The hardest reasoning & long agentic work
Claude Sonnet 4.6claude-sonnet-4-61M64K$3.00$15.00The everyday balance of speed & smarts
Claude Haiku 4.5claude-haiku-4-5200K64K$1.00$5.00Fast, cheap, high-volume simple tasks
Claude Opus 4.7claude-opus-4-71M128K$5.00$25.00Previous-gen Opus; pin for reproducibility
Claude Fable 5claude-fable-51M128K$10.00$50.00The most demanding, longest-horizon work

Use the exact ID string โ€” don't add date suffixes. For the always-current list, query the Models overview or call GET /v1/models.

Hints from the field

Gotchas worth knowing on day one

The small things that trip up everyone the first time.

โœ“ Keep your key in the environment

Read it from ANTHROPIC_API_KEY (the SDKs do this for you). A key in source code, a webpage, or a public repo is a compromised key โ€” rotate it instantly if it leaks.

โœ“ The API has no memory

Every request is independent. To continue a conversation, resend the full messages history each time. Forgetting this is the #1 "why doesn't it remember?" question.

โœ“ Set max_tokens generously

Too low and the reply is cut off mid-sentence (stop_reason: "max_tokens"). 1024 is fine for a sentence; use 4096+ for real answers and stream anything large.

โœ“ Parse JSON โ€” don't regex it

Read fields like content[0].text from the parsed object. Never pattern-match the raw response text; escaping and formatting will eventually break it.

โœ“ Check stop_reason before trusting output

end_turn means done; max_tokens means truncated; tool_use means it wants a tool; refusal means it declined. Branch on it instead of assuming success.

โœ“ Prefer the SDK over raw HTTP

Past your first curl, use anthropic (Python) or @anthropic-ai/sdk (TS/JS). You get retries, streaming helpers, and typed responses for free.

๐Ÿ“š
Studying for the CCA-F exam? These same API fundamentals โ€” stop_reason, the agentic loop, tool design, structured output โ€” are exactly what Domains 1, 3 and 4 test. Drill them in the practice quiz and ask the AI coach anything.