Skip to lesson

AnthropicClaude Certified Architect – Foundations2026-100 Prerequisites

Tell async calls and batches from retries

Completed by the knowledge check

Learning objective

Distinguish synchronous calls, asynchronous execution, failures, and retries

Core idea

How a caller waits and what happens when a call fails are separate decisions. A synchronous call keeps the caller waiting for its response. An asynchronous client lets the program wait without blocking its event loop. A deferred batch returns an identifier for work you inspect later. None of them decides whether repeating a failed call is useful.

Ask of any call what the caller receives — a response, an awaitable, or an identifier for unfinished work — and which layer owns retries when it fails.

How it works

Synchronous and asynchronous clients

In the Python SDK, Anthropic exposes blocking calls such as client.messages.create(...); the caller proceeds once the response or an exception arrives. AsyncAnthropic exposes the same call as await client.messages.create(...), so other coroutines run while this one waits. The async client changes scheduling, not durability: it is not a background queue.

Deferred work: Message Batches

The Message Batches API is service-side asynchronous execution. You submit many Messages requests under client.messages.batches, keep the returned batch id, and poll it. Its processing_status starts as in_progress and becomes ended once every request has finished, but ended is not success: each entry has its own result. Results are available when all requests complete or after 24 hours, whichever comes first, so a batch suits work that can wait, never a live request. Choosing batches over synchronous calls is taught in 4.5.1, expiry and the discount in 4.5.2, and recovering failed entries by custom_id in 4.5.4.

Retries

The Python SDK raises APIConnectionError for connectivity problems and an APIStatusError subclass for a non-success HTTP status — BadRequestError for 400, AuthenticationError for 401, PermissionDeniedError for 403, RateLimitError for 429. A malformed request or a bad credential needs repair; resending either unchanged changes nothing. A rate limit or a dropped connection can be retried.

The SDK already retries. Connection errors, 408, 409, 429 and 500-or-greater responses are retried 2 times by default with short exponential backoff, which is up to three attempts. Requests time out after 10 minutes by default, and timed-out requests are retried twice too. max_retries on the client, or client.with_options(max_retries=...) per request, changes the count; max_retries=0 hands retries to another layer. An outer loop of three around a default client can make nine attempts. Keeping recovery bounded across a handler, a subagent and a coordinator is taught in 2.2.5.

Each attempt of an outer loop runs the SDK’s own retries, so the attempts multiply.

Each attempt of an outer loop runs the SDK's own retries, so the attempts multiplyAn outer loop of three calls a default client. On each call the client sends the request up to three times, retrying a 429 twice, and then raises RateLimitError to the loop. Three outer attempts of up to three attempts each can make nine attempts.APIDefault clientOuter looploop[Up to threeattempts]loop[Outer loop of three]Can make nine attemptsclient.messages.create(...)Request429RateLimitError

A tool failure is a third channel: the inference call succeeded, the tool did not, and the application reports it in a tool_result with is_error: true. It is not an HTTP error and triggers no SDK retry.

Key distinctions and trade-offs

PairDifference
Async client vs batchAsyncAnthropic changes how your program waits; a batch is deferred work held by the service.
Retry vs pollingA retry repeats failed work; polling reads the state of existing work. A second batch submitted because the first is in_progress is new work.

Architecture / decision scenario

A support service answers live questions in an event-loop web handler with AsyncAnthropic, awaiting each response. Yesterday’s conversations go into a Message Batch whose id is polled until processing_status is ended, after which each entry’s result is read on its own. A live 429 is left to the SDK’s default retries with no second loop around it, a 400 goes back to the integration owner, and a failed customer-record lookup returns is_error: true in its tool_result.

Common exam traps

  • Treating await as submission to a durable queue.
  • Reading processing_status: "ended" as proof that every entry succeeded.
  • Submitting another batch instead of polling the first.
  • Counting two SDK retries as two total attempts.
  • Retrying authentication, permission or input errors unchanged.
  • Treating is_error: true as an HTTP failure of the Messages call.

What to remember

Know what you are waiting for and what proves its outcome. Use the async client for scheduling, batch identifiers for deferred work, and per-entry results for success. Classify the failure and count the SDK’s retries before adding another recovery layer.

Knowledge check

References