1. Sending Images
An image is sent as another content block inside the same messages
array — base64-encoded, alongside text in the same turn. Common formats (JPEG, PNG,
GIF, WebP) are supported, and it works well for screenshots, charts, diagrams, and
photos of things like whiteboards or documents.
import base64
with open("chart.png", "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_data,
},
},
{"type": "text", "text": "Extract the exact values shown in this chart as JSON."},
],
}],
)
Week 3's structured-output and grounding techniques apply unchanged: ask for exact JSON with a defined schema, and for anything precision-sensitive (reading small text, exact numbers off a chart), ask Claude to note its confidence rather than silently guess.
Larger and higher-resolution images use more tokens to process. If precision on fine detail doesn't matter for your use case, resizing images down before sending them saves cost and latency without hurting results.
2. Native PDF Support
Claude can take a PDF directly as a document content block and understand its actual visual layout — tables, embedded charts, multi-column text — not just a plain-text extraction that would lose that structure. This matters a lot for scanned documents, financial statements, and anything where layout carries meaning.
with open("contract.pdf", "rb") as f:
pdf_data = base64.standard_b64encode(f.read()).decode("utf-8")
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": pdf_data,
},
},
{
"type": "text",
"text": (
"Using only this document, list the termination conditions. "
"Quote the exact supporting sentence for each."
),
},
],
}],
)
This is the exact same grounded-citation pattern from Week 4's document work in claude.ai — now driven from code, which is what makes it usable inside an automated pipeline (a document-processing service, a batch of contracts, an intake form) rather than one document at a time in a chat window.
A PDF still counts against the context window from Week 1 — a genuinely huge document may need to be chunked, or you may need a strategy (summarize per section, then synthesize) rather than sending it whole.
3. Extended Thinking for Harder Problems
Week 3's "think step by step" prompting nudges the model toward showing reasoning in its normal response. Extended thinking is a distinct, more powerful mode where Claude reasons through a problem in a visible thinking block before producing its final answer — meant for genuinely hard problems: tricky math, complex debugging, or multi-step planning where a quick answer is much more likely to be wrong.
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
thinking={"type": "enabled", "budget_tokens": 2048},
messages=[{"role": "user", "content": "Here's a bug report and this 200-line function: ..."}],
)
# response.content will include a thinking block AND the final answer block
The budget_tokens caps how much reasoning Claude is allowed to spend
before answering — more budget for harder problems, less for ones that don't need
it. This costs more tokens and more latency than a normal call, which is exactly why
it's reserved for problems that actually benefit from deeper reasoning rather than
turned on everywhere by default.
Week 9 covers token economics properly — for now, the rule of thumb is the same one from Week 1's model-tier decision: reserve extra reasoning budget (like reserving Opus) for problems genuinely hard enough to need it.
4. Combining Modalities in One Request
A single message's content array can mix multiple images, a document, and text together — letting Claude reason across all of them at once, like comparing a design screenshot against a written spec.
content = [
{"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": spec_pdf}},
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": screenshot_png}},
{
"type": "text",
"text": (
"The document above is the design spec. The image above is a "
"screenshot of the current implementation. List every place "
"the screenshot doesn't match the spec."
),
},
]
Put the reference material (the document, the images) before the instruction that refers to them — the same ordering principle behind Week 2's XML-tag structuring, just applied across content types instead of only text blocks.
If you're sending three images, reference them explicitly in your text ("the first image," "the second image," or better, name them) so it's unambiguous which one your instruction is about — vague references across multiple similar inputs are a common source of mixed-up answers.
5. Hands-on Exercise
Extract structured data from an image and a PDF, in code
Take Week 4's document work and reproduce it programmatically.
Part 1 — Structured extraction from an image:
- Find or take a screenshot of a table, receipt, or chart with real data in it.
- Send it to the API with a request for exact JSON extraction, with a defined schema (Week 3's technique).
- Verify the extracted values against the source image manually.
Part 2 — Grounded PDF question in code:
- Send a real PDF (a resume, a short report, a public document) as a document block.
- Ask a specific question requiring a quoted, grounded answer.
- Confirm the quote is real by checking it against the document.
If you don't have a real PDF handy, export any document (a Google Doc, a webpage) to PDF for this exercise — the point is practicing the document content-block mechanics, not the specific file.
Part 3 — Try extended thinking on a hard problem:
- Pick a genuinely tricky problem (a multi-step math word problem, or a subtle bug in a real function).
- Run it once without extended thinking, once with it enabled.
- Compare correctness and read through the visible thinking block to see how Claude actually approached it.
6. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
How is an image included in a Messages API request?
How is an image included in a Messages API request?
As a base64-encoded content block alongside text content blocks, all inside the same message's content array — not as a separate API call or upload step.
Q2
What's the advantage of native PDF support over extracting the PDF's text yourself first and sending plain text?
What's the advantage of native PDF support over extracting the PDF's text yourself first and sending plain text?
Claude can understand the document's actual visual layout — tables, columns, embedded charts and images — which plain-text extraction loses entirely. This matters most for scanned documents and anything where layout carries meaning.
Q3
Why isn't extended thinking turned on for every request by default?
Why isn't extended thinking turned on for every request by default?
It costs more tokens and adds latency compared to a normal response. It's worth that cost for genuinely hard problems where deeper reasoning materially improves accuracy, but wasteful for simple requests that don't need it.
Q4
When combining multiple images and a document in one request, what ordering habit reduces mixed-up answers?
When combining multiple images and a document in one request, what ordering habit reduces mixed-up answers?
Put reference material (documents, images) before the instruction referring to them, and explicitly label or distinguish multiple similar items ("the first image," "the screenshot" vs. "the spec") so the instruction unambiguously points at the right one.