Skip to content
CCAR-P Español

Technical Reference

The API surface you don't touch daily · exact names, permitted values and what gets asked about each one

The notes explain the why; this is the what. It is meant for what doesn't stick because you never write it: field names, admitted values and return shapes. The exam doesn't ask you to write code, but it does ask you to recognise the right name among four that sound alike.

Messages API POST /v1/messages

FieldRequiredNotes
modelYesSnapshot ID. IDs without a date are still fixed snapshots, not moving pointers
messagesYesOnly user and assistant roles. Consecutive turns of the same role are merged
max_tokensYes0 is used to warm the cache without generating a response
systemNoTop-level parameter, string or array of blocks. There is no system role
tools, tool_choiceNoSee the tool use section
streamNotrue enables SSE
thinking, output_configNoSee reasoning and structured output
temperature, top_p, top_k, stop_sequencesNoSampling
metadata, service_tier, inference_geoNoinference_geo: "global" by default or "us", at a surcharge
What gets askedThat the system prompt is a separate parameter and that there is no system role inside messages. It is the most cited difference against other chat APIs.

The interaction modes

A developer reaches Claude through a REST API, normally via an SDK. The choice of mode is settled with two questions: is someone waiting? and is it real time or offline volume?

ModeWhen
SynchronousSomeone is waiting and the response is short. The simplest one
StreamingSomeone is waiting and the response is long: buys perceived latency in exchange for assembling the response yourself
Async / awaitNobody is waiting at that instant, but it is still real time: concurrency without blocking
BatchNobody is waiting and it is offline volume: lower cost per token, non-deterministic latency
What gets askedThat firing synchronous calls in parallel is not batch: it gives concurrency, not a discount. And that streaming speeds nothing up — it improves perceived latency.

The context window and its two ways of breaking

It is a fixed token budget that holds the entire request at once: system, history, tools, documents and the generation. It fails in two distinct ways, and the exam may ask you to tell them apart:

SituationWhat happens
The input no longer fitsError before generating. There is no partial response
The ceiling is hit mid-generationTruncated output with stop_reason: model_context_window_exceeded
What gets askedThat managing the history is the application's job, not the API's. Nobody prunes for you: compaction, pruning and subagents are your decisions.

stop_reason values

ValueMeansWhat you do
end_turnFinished naturallyClose the turn
tool_useAsks to run one or more toolsRun them and return tool_result; the loop continues
max_tokensTruncated outputCan break strict JSON. Retry with more budget
stop_sequenceHit a stop sequenceHandle it per your protocol
refusalDeclined to answerReturns 200 and is billed. Takes precedence over the schema
pause_turnPause in a long operationContinue the turn
model_context_window_exceededWent past the windowCompact or reduce context
What gets askedtool_use versus end_turn as the control of the agentic loop, and that refusal and max_tokens are the two cases in which structured output may not satisfy the schema.

Tool use

Defining a tool

{
  "name": "search_order",          // ^[a-zA-Z0-9_-]{1,64}$
  "description": "...",             // 3-4 sentences minimum, include when NOT to use it
  "input_schema": { ... },          // JSON Schema
  "input_examples": [ ... ]         // optional, useful on nested inputs
}

tool_choice values

ValueEffect
autoDefault when tools are present. The model decides
anyForces a call to some tool
toolForces a specific one (carries name)
noneDefault when there are no tools

With any or tool, the API prefills the turn: there will be no text before the tool_use. Parallelism comes enabled; it is turned off with disable_parallel_tool_use: true inside tool_choice.

Returning the result

{
  "role": "user",                   // there is no "tool" role
  "content": [
    { "type": "tool_result",
      "tool_use_id": "toolu_...",   // required
      "content": "...",             // optional
      "is_error": true },           // optional: model-readable failure
    { "type": "text", "text": "..." } // the text goes AFTER
  ]
}
What gets askedThat tool_result blocks go first in content and in the message immediately after the tool_use (otherwise, 400), and that a failure is signalled with is_error, not with an exception nor with an empty result the model would mistake for data.

Streaming stream: true

message_start
  content_block_start   // per block, with its index
  content_block_delta   // N times
  content_block_stop    // HERE the block is closed
message_delta           // cumulative usage
message_stop            // HERE the turn is confirmed
Delta typeContent
text_deltaText fragment
input_json_deltaPartial JSON of a tool's input. Do not parse until content_block_stop
thinking_deltaReasoning fragment
signature_deltaRight before closing a thinking block
What gets askedThree things: errors arrive as event: error after an HTTP 200; tool use and thinking blocks are not recovered partially (you only resume from the last text block); and a tool use error on retry usually traces back to a half-built block, not to the schema.

Message Batches

ConceptValue
Discount50% input and output
Limit per batch100,000 requests or 256 MB
WindowMost under 1 h · results on completion or at 24 h · expire at 24 h
Results downloadable for29 days
processing_statusOnly in_progress and ended
Result per requestsucceeded · errored · canceled · expired (the last three are not billed)
Not supportedstream: true, max_tokens: 0
Available onClaude API and Claude Platform on AWS only
What gets askedThat there are only two batch states, that it does not support streaming, and that firing synchronous calls in parallel is not batching because it does not lower the cost per token.

Prompt caching cache_control

{ "type": "text", "text": "...",
  "cache_control": { "type": "ephemeral", "ttl": "1h" } }
// "ephemeral" is the only type. ttl optional: 5 min by default
ParameterValue
TTL5 min by default · 1 h extended
Maximum breakpoints4 (the automatic one consumes one)
Lookback20 blocks per breakpoint
Write price1.25× (5 min) · 2× (1 h)
Read price0.1×
Prefix hierarchytoolssystemmessages
Minimum cacheableBetween 512 and 4,096 tokens depending on the model
What gets askedThat changing tools invalidates the whole prefix, that changing the effort level also breaks the cache because it is rendered into the prompt, and the silent failure: below the minimum it does not cache and gives no error — you detect it with both cache counters at zero in usage.

Reasoning and effort

ParameterValuesNotes
thinking.typeadaptiveThe model decides. On current models it is always on; disabling it gives 400
thinking.typeenabled + budget_tokensDeprecated. Rejected with 400 on recent models
displaysummarized · omittedBilled the same in both cases
output_config.effortmax · xhigh · high · medium · lowDefaults to high. A behavioural signal, not a budget
The underlying principleChoosing the model and choosing the reasoning mode are two separate and composable levers. The rule works from the floor up: the smallest model and the simplest reasoning and prompting that pass your eval, and add capacity only where the eval says it is needed. Not the other way round.
What gets askedThat reasoning tokens are billed as output and count against max_tokens even when the text is not returned, and that thinking blocks carry a signature and must be returned unmodified or the next request fails.

Structured output

Two mechanisms: JSON outputs (schema in output_config.format, constrains the final response) and strict tool use (strict: true on a tool, validates the arguments). Both by constrained decoding.

Limit per requestValue
Tools with strict20
Optional parameters, total24
Parameters with union types16
Compilation timeout180 s
Grammar cache24 h since last use
SupportsDoes not support (400)
basic types, scalar enum, const, anyOf, internal $ref, default, required, string formatsrecursive schemas, external $ref, minimum/maximum, minLength/maxLength, lookahead in pattern
What gets askedThat prefill no longer works to force JSON, that the casing of enum values is not guaranteed, that required properties come first in the ordering, and that citations plus structured outputs give 400.

Errors and retry strategy

CodeTypeRetryable?
400invalid_request_errorNo — fix the request
401 / 403auth / permissionsNo — credential
413request_too_largeNo — split it up
429rate_limit_errorYes, with backoff and respecting retry-after
500api_errorYes
504timeout_errorYes
529overloaded_errorYes — global overload, not yours

Classifying failures

  • First question on any failure: could waiting and retrying resolve it?
  • If yes → exponential backoff with a cap and a retry budget. Never an immediate loop, which only makes the problem worse.
  • If no → a named fallback. Without it, the unhandled exception becomes the default behaviour, and one bad response takes down the whole flow.
  • Tool failure → back to the model with the error flag set, never hidden behind an empty result the model would mistake for data.

The official SDKs already retry with exponential backoff, 2 retries by default, respecting retry-after.

Evals: grading method by output shape

Output shapeGrader
There is one correct formExact match
Structured outputCode-based check
Open-ended qualityLLM judge, calibrated against human-labelled cases before you trust it

Official order of preference: code → LLM → human. On the human, the docs say literally "avoid it if you can". And the design principle: more cases with somewhat worse signal and automatic grading beats few hand-graded cases.

What gets askedThat the eval is written first: identifying the expected behaviour forces you to define success while the design can still change. An eval turns "it's done" from a feeling into a score over a fixed set of cases.

Test levels and what each one catches

LevelCatches
UnitLogic errors inside a component
FunctionalThat a component meets its specification
IntegrationThe seam: the handoff between two components that pass separately
End-to-endThe whole flow. Tells you something fails, not where
The diagnostic patternUnits and functionals green with the e2e red means the breakage is in a handoff, not inside a component — and by definition that is what an integration test covers. The complete answer has two halves: fix at the seam and add the integration test that was missing. A trace tells you which step produced the bad result, which is what turns a day of investigation into a short fix.

The same instinct governs information retrieval: a single search for single-fact queries, search across several iterations when the question is genuinely multi-step.

Hooks

EventWhat for
PreToolUseValidate or block before execution
PostToolUseAdd context, replace the output, auditing
UserPromptSubmitIntercept the user's input
SubagentStart / SubagentStopSubagent lifecycle
PreCompactBefore compacting (trigger: manual or auto)
SessionStart / SessionEnd / Stop / NotificationLifecycle and notices

PreToolUse return shape

{ "permissionDecision": "deny",        // allow | deny | ask | defer
  "permissionDecisionReason": "...",
  "updatedInput": { ... } }            // optional
  • Exit 2 = blocking error, not overridable even with an allow.
  • Silence is not approval: a hook can deny, but staying quiet lets the normal permission flow continue.
  • Hooks run in your process, outside the context window: they consume no tokens beyond what they return.
What gets askedThat the hook is the mechanism for deterministic enforcement as opposed to an instruction, that PreToolUse is where you put the action boundary that blocks and logs before execution, and that PostToolUse is the place for the audit log for a regulated customer.

Agent SDK

OptionWhat it does
allowedToolsAuto-approval. Must include the spawn tool to use subagents
maxTurnsCounts only turns with tool use
maxBudgetUsdCuts off by cost; includes subagent spend
systemPromptWithout it, a minimal prompt. With the preset, the full CLI prompt. Or your own
settingSourcesControls whether CLAUDE.md is loaded. Empty disables it
resume / forkSessionPick up a specific session / branch it into a new one
permissionModedefault · acceptEdits · plan · auto · dontAsk · bypassPermissions

A subagent's AgentDefinition

{ "description": "...",   // required
  "prompt": "...",        // required - the ONLY thing that crosses from the parent
  "tools": [...],         // if omitted, inherits all
  "model": "inherit",     // or a specific model
  "skills": [...] }       // subagents do NOT preload skills
What gets askedThat maxTurns does not count turns without tools, that the budget includes subagents, and that the subagent does not inherit history: only the prompt string.

MCP

PrimitiveControlled byMethods
ToolsThe modeltools/list · tools/call
ResourcesThe application (read-only)resources/list · resources/read
PromptsThe userprompts/list · prompts/get
DecisionOptions
Transportstdio (local) · Streamable HTTP (remote or multi-developer)
Scope in Claude Codelocal (personal) · project (.mcp.json, versioned) · user (all your projects)
Deferred loadingdefer_loading on the toolset: defers the context, not the payload

Naming in Claude Code: tools mcp__server__tool · prompts /mcp__server__prompt · resources @server:proto://path.

What gets askedWho controls each primitive, that stdio should not use OAuth because it takes credentials from the environment, and that a stdio server in .mcp.json looks shareable and is not.

Limits and counters

ConceptValue
Request sizeMessages 32 MB · Batch 256 MB · Files 500 MB
Non-streaming timeout10 minutes
Counting tokensPOST /v1/messages/count_tokensfree, independent rate limit
ITPMinput plus cache creation. Cache reads do not count
OTPMTokens actually generated. max_tokens has no effect
Headersrequest-id on every response · anthropic-ratelimit-*-{limit,remaining,reset}
Tool selection degradationAbove 30-50 available tools
Cost of an image⌈width/28⌉ × ⌈height/28⌉ visual tokens
Image ceilingHigh resolution 2576 px / 4784 tokens · standard 1568 px / 1568
Cost of multi-agentMultiplies by the number of subagents: ~15× in the published case
What gets askedThat you cannot budget what you do not measure: you have to instrument token cost, latency and error rate on every call and then tune one chosen lever, instead of guessing by looking at the bill. And that the orchestrator-workers pattern only earns that cost on tasks that split into independent parallel parts, not on tightly coupled work a single agent solves for a fraction.