Other SDKs and OpenAI Compatibility Best Practices
A checklist for choosing between a native Go, Java, C#, PHP, or Ruby SDK and the OpenAI-compatible migration shortcut, and for using each well once you've picked.
Search across all documentation pages
A checklist for choosing between a native Go, Java, C#, PHP, or Ruby SDK and the OpenAI-compatible migration shortcut, and for using each well once you've picked.
anthropic-sdk-go; a Ruby app should use the Ruby SDK, even if the team's favorite language is elsewhere.ANTHROPIC_API_KEY by convention; keep it out of source control.max_tokens for every request. None of the five SDKs supply a sensible implicit default; size it to your expected response length.tool_use stop reason as "waiting," not "done." Run the requested tool, then send a tool_result back in a follow-up call before treating the exchange as complete.tool_result to its originating tool_use ID. This requirement is identical across all five SDKs; a mismatched or missing ID produces a rejected request no matter which language sent it.StreamResponse holds an open HTTP connection; failing to close it leaks connections under sustained load.await foreach inside an async method chain; calling .Result or .Wait() on a streaming call risks deadlocks and defeats the purpose of IAsyncEnumerable.max_tokens looks similar to a complete one if you're only watching for text, so read the terminal event's stop reason explicitly.Work through section A once per new integration, and keep B-D as an ongoing reference while building against whichever SDK the service ends up using.
If more than a couple of items in section A stay unchecked for a service now running in production on the compatibility layer, that's a signal the migration to a native SDK is overdue, not optional.
Start with the compatibility layer only if you already have a working OpenAI integration and want a fast test or migration. If you're building fresh, go straight to the native SDK for your language; there's no compatibility-layer benefit to a greenfield project.
Not automatically wrong, but it's a trade-off: you're limited to the OpenAI-shaped parameter surface and inherit its translation gaps. If the parameters you use all map cleanly and the team has no bandwidth to migrate, it can be an acceptable long-term choice.
Picking a language for the integration based on team preference rather than what the service is actually written in, which then forces an unnecessary cross-language hop just to call Claude.
Because each SDK follows its host language's own convention: Go returns errors as values, while Java and C# throw typed exceptions. This isn't inconsistency in the Claude SDKs; it's each SDK matching the idioms developers in that language already expect.
Java's StreamResponse is the most explicit case since it's an AutoCloseable you must close yourself. Go and C# manage the underlying connection lifecycle more implicitly through their iterator and async-stream patterns, but reusing a single long-lived client (rather than constructing one per request) matters in all of them.
The shape mismatch between OpenAI's function-calling parameters and Claude's tool_use protocol. Test tool-calling flows specifically after migrating, rather than assuming they behave identically just because plain text generation worked.
Yes, temporarily, as a migration strategy: keep the compatibility layer on stable, low-risk call paths while porting higher-value or tool-heavy call paths to the native SDK first.
Strict. Fighting a language's natural conventions (like trying to force strict typed schemas in PHP or Ruby) adds friction without adding safety, since the wire protocol is identical regardless of how idiomatically you write the client-side code.
Any of: you've validated Claude is the right model for production, you need a Claude-specific capability not exposed through the OpenAI-shaped surface, or you've hit a parameter mapping gap that affects a real feature.
Not meaningfully from the SDK itself; both talk over HTTP to Anthropic's infrastructure. The practical benefit of the native SDK is a more complete parameter surface and idiomatic error/streaming handling, not raw speed.
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 current official SDKs for Go, Java, C#, PHP, and Ruby. 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 19, 2026