Learning objectives
- Explain that Claude is reached over an HTTP REST API, and what an official SDK adds.
- Choose between synchronous and streaming responses based on whether a user is watching.
- Distinguish async/await concurrency from the Message Batches API, and pick the right one for high-volume work.
Estimated teaching time: 12 min · Prerequisites: M01-L02 (tokens); Basic familiarity with HTTP requests helps
1. How a developer reaches Claude: SDK versus raw REST
- REST API
- In plain English: A web interface you call with ordinary HTTP requests. You send a request to a URL (an endpoint) and get a response back, here with JSON in both directions.
- Analogy: Like sending a form by post and getting a typed letter back: the envelope (HTTP) and form layout (JSON) are standard.
At its core, Claude is reached over an HTTP REST API: your code sends a request to an endpoint with your API key and a JSON body, and reads a JSON response back. You can call that endpoint directly with any HTTP client.
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-sonnet-5-5",
"max_tokens": 300,
"messages": [{"role": "user", "content": "Where is my order #A1042?"}]
}'- SDK (software development kit)
- In plain English: An official library, available for Python and TypeScript among others, that wraps the same REST API so you write less boilerplate.
- Why it matters: It handles authentication, request construction, retries, and response parsing for you.
The SDK and raw REST reach the same API and the same model. The SDK just saves you from assembling requests by hand. Module 2 builds against the SDK and the Messages API, which sits on this same foundation.
2. Synchronous, streaming, and real-time responses
| Pattern | How it behaves | Use it when |
|---|---|---|
| Synchronous | Send the request, wait for the complete response in one piece, then act on it. | Short responses and backend jobs where no one is waiting. |
| Streaming | The response arrives in pieces as the model generates it; your code reassembles the final message. | Long responses, or a user is watching: output appears immediately instead of after a blank-screen wait. |
Claude exposes streaming over the same HTTP connection using server-sent events (SSE): a standard way for a server to push a sequence of small, named events down one open HTTP response.
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain our return policy step by step."}],
) as stream:
for text in stream.text_stream: # pieces arrive as they are generated
print(text, end="", flush=True) # show them to the user immediately
message = stream.get_final_message() # the reassembled, complete Message
print("\nstop reason:", message.stop_reason)3. Asynchronous patterns for high-volume work
Two patterns address high-volume work, and they solve different problems.
- AsyncAnthropic
- In plain English: The async client exposed by the Python SDK. Uses non-blocking async/await to make API calls without tying up your application thread while the request returns in real time.
- Why it matters: Source glossary definition. In the TypeScript SDK the standard Anthropic client is Promise-based, so you await calls directly; there is no separate async class.
import asyncio
import anthropic
client = anthropic.AsyncAnthropic()
limit = asyncio.Semaphore(5) # stay well inside your rate limits
async def summarize(ticket: str) -> str:
async with limit:
response = await client.messages.create(
model="claude-haiku-5-5",
max_tokens=200,
messages=[{"role": "user", "content": f"Summarize in one line: {ticket}"}],
)
return next(b.text for b in response.content if b.type == "text")
async def main(tickets: list[str]) -> list[str]:
# Many requests in flight at once; each still returns in real time.
return await asyncio.gather(*(summarize(t) for t in tickets))
if __name__ == "__main__":
print(asyncio.run(main(["Parcel late", "Wrong size", "Double charge"])))- Message Batches API
- In plain English: A separate pattern for bulk offline workloads: submit a large set of requests in one call, receive an identifier, and poll for completion. Can take up to 24 hours and runs at a lower per-token cost.
- Why it matters: Source glossary definition. It suits offline pipelines, evaluation runs, and bulk jobs where no user is waiting and cost matters more than turnaround time.
import time
import anthropic
client = anthropic.Anthropic()
reviews = {"r-001": "Great boots, fast delivery.", "r-002": "Zip broke in a week."}
batch = client.messages.batches.create(
requests=[
{
"custom_id": review_id,
"params": {
"model": "claude-haiku-5-5",
"max_tokens": 50,
"messages": [{"role": "user", "content": f"Sentiment of: {text}"}],
},
}
for review_id, text in reviews.items()
]
)
print("submitted", batch.id) # keep this identifier
while client.messages.batches.retrieve(batch.id).processing_status != "ended":
time.sleep(60) # nobody is waiting; poll slowly
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
text = next(b.text for b in result.result.message.content if b.type == "text")
print(result.custom_id, text)
else:
print(result.custom_id, result.result.type) # errored / canceled / expired| Situation | Pattern |
|---|---|
| A short answer for a backend job | Synchronous |
| A customer is watching a long answer appear | Streaming |
| Your web server handles many requests at once and must not block | Async/await client |
| 50,000 product reviews to classify overnight, nobody waiting | Message Batches API |
References
- Streaming messages (Claude Platform Docs) · checked 2026-10-20Server-sent events; event order message_start → content blocks (start/delta/stop) → message_delta → message_stop; ping and error events; messages.stream and get_final_message.
- Batch processing (Claude Platform Docs) · checked 2026-10-2050% of standard prices; up to 100,000 requests or 256 MB per batch; most finish within 1 hour, results when all done or after 24 hours; processing_status in_progress → ended; result types succeeded / errored / canceled / expired; results kept 29 days.
- Messages API reference · checked 2026-10-20Endpoint POST /v1/messages; x-api-key and anthropic-version headers.
- anthropic Python SDK 1.15.0 (installed locally) · checked 2026-10-20Confirmed AsyncAnthropic, messages.stream, messages.batches.create/retrieve/results, MessageBatch.processing_status, result.result.type/message.
Source notes
- Primary source: S05 of 'MSO Foundations: Developer Module 1', three tab panels plus two glossary tooltips (AsyncAnthropic, Message Batches API).
- Supplementary from docs (labelled in the lesson): the exact SSE event order, the 50% batch discount, batch size limits, typical completion within 1 hour, result types and retention. The source says only 'lower per-token cost' and 'up to 24 hours'.
- The TypeScript statement (Promise-based client, no separate async class) is source content; it was not re-verified against the TypeScript SDK in this build.