Claude API Fundamentals Best Practices
Twenty-five practices for reliable authentication, requests, and error handling when building on the Claude API with the official Python SDK.
Search across all documentation pages
Twenty-five practices for reliable authentication, requests, and error handling when building on the Claude API with the official Python SDK.
Organized from setup and authentication through request design, error handling, and model selection.
ANTHROPIC_API_KEY environment variable or a secrets manager, and add .env to .gitignore before your first commit.401 surface deep in your call stack later.anthropic.Anthropic() at application startup or module load, not per request or per function call.system keeps the messages history focused on the actual conversation.temperature and top_p at once, which makes behavior harder to predict.429/5xx automatically; don't disable it without a specific reason.anthropic.AuthenticationError, anthropic.RateLimitError, and anthropic.BadRequestError each point to a different fix.anthropic.AsyncAnthropic inside asyncio code and anthropic.Anthropic in sync code; don't mix them in one call path.Setting up the API key correctly via an environment variable (section A) and constructing the client once, reused across your app, matters before anything else.
Yes, anthropic.AuthenticationError, anthropic.RateLimitError, and anthropic.BadRequestError each require a different fix, a bare except Exception hides which one occurred and how to respond.
Only for a throwaway script you'll never commit; an environment variable is just as fast to set up and avoids the risk of an accidental commit exposing the key.
Because the API is stateless, every turn in a growing conversation resends (and is billed on) the entire prior history, so conversation length has a direct, compounding cost impact.
No, match model tier to task difficulty; using a model too weak for a hard reasoning task produces worse results that may cost more in retries and rework than a stronger model would have.
An unpinned anthropic dependency can silently pull in a newer version with breaking changes on a fresh install, causing failures unrelated to your own code changes.
The SDK's built-in retries already include jitter; this practice matters specifically when you write custom retry logic on top of or instead of the built-in behavior.
Whenever cost or latency becomes a concern, and periodically regardless, since new model versions and pricing can shift the best default over time.
Treating all errors the same, retrying 400-class errors that will never succeed on retry, or not retrying 429/5xx errors that would have succeeded with backoff.
No, a wrapper is worth building once you have multiple call sites needing shared configuration; for a single script, a direct client call is simpler and sufficient.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.
Reviewed by Chris St. John·Last updated Jul 18, 2026