OpenAI to Anthropic API Migration
How hard is it to migrate from OpenAI to Anthropic?
Code change: 12 parameters need attention when moving from OpenAI to Anthropic, 7 with no equivalent at all. The Messages API is not a drop-in swap for Chat Completions: `system` becomes a top-level field instead of a message role, `max_tokens` goes from optional to required with no server-side default, and `n` disappears entirely — any code path that requested multiple completions per call has no equivalent and needs a redesign, not a rename. Blended cost per million tokens rises 344.4% on the default model pair.
Should you?
Teams move from OpenAI to Anthropic chasing Claude's extended-thinking quality on hard reasoning and agentic coding tasks, or because a procurement review picked Anthropic's usage-tier terms and data-handling commitments over OpenAI's for an enterprise contract. It is rarely about price — the two flagships trade blows there — and almost always about a capability gap a team hit in production: a coding agent that got stuck in a loop on OpenAI's model and didn't on Claude's, or a reviewer who wanted Anthropic's training-data commitments in writing before a renewal.
Loses: no documented data residency.
The parameter mapping
Derived from OpenAI's and Anthropic's API surface, sourced 2026-08-09. Breaking rows first.
| Concept | OpenAI | Anthropic | Status | Note |
|---|---|---|---|---|
| reasoningEffort | reasoning_effort | — | No equivalent | No effort enum — extended thinking is a token budget, not a graduated setting. |
| jsonMode | response_format.type="json_object" | — | No equivalent | No dedicated JSON mode — constrain via forced tool use. |
| structuredOutput | response_format.json_schema | — | No equivalent | No native structured-output field — same forced-tool-use workaround as JSON mode. |
| seed | seed | — | No equivalent | No seed parameter — no reproducibility knob. |
| nCompletions | n | — | No equivalent | No n parameter — exactly one completion per request, always. |
| frequencyPenalty | frequency_penalty | — | No equivalent | No frequency or presence penalty knobs. |
| logprobs | logprobs | — | No equivalent | No logprobs support at all. |
| maxOutputTokens | max_completion_tokens | max_tokens | Now required | No server-side default — omit it and the call 400s before the prompt is even sent. |
| systemPrompt | messages[].role="system" | system | Reshaped | Top-level string, not a message role — the single most common porting bug. |
| temperature | temperature | temperature | Constrained | Range is 0-1 on the target vs. 0-2 on the source. |
| stopSequences | stop | stop_sequences | Renamed | |
| toolDefinitions | tools (function.parameters) | tools (input_schema) | Renamed | |
| topK | — | top_k | Gained | Anthropic-only knob with no OpenAI equivalent. |
| reasoningBudget | — | thinking.budget_tokens | Gained | |
| cacheControl | — | cache_control (per content block) | Gained | Explicit cache_control breakpoints required — caching isn't automatic the way OpenAI's is. |
| topP | top_p | top_p | Identical | |
| stream | stream | stream | Identical | |
| toolChoice | tool_choice | tool_choice | Identical |
The diff
− OpenAI (gpt-5.6-luna) · + Anthropic (claude-haiku-4-5)
- const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });+ const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });- const response = await client.chat.completions.create({+ const response = await client.messages.create({model: MODEL,+ max_tokens: 1024, // maxOutputTokens: No server-side default — omit it and the call 400s before the prompt is even sent.messages: [{ role: 'user', content: 'Say hello in one sentence.' }],});- console.log(response.choices[0].message.content);+ const block = response.content[0];+ console.log(block.type === 'text' ? block.text : '');
What doesn't port at all
The Messages API is not a drop-in swap for Chat Completions: `system` becomes a top-level field instead of a message role, `max_tokens` goes from optional to required with no server-side default, and `n` disappears entirely — any code path that requested multiple completions per call has no equivalent and needs a redesign, not a rename.
- reasoningEffort (
reasoning_effort) — No effort enum — extended thinking is a token budget, not a graduated setting. - jsonMode (
response_format.type="json_object") — No dedicated JSON mode — constrain via forced tool use. - structuredOutput (
response_format.json_schema) — No native structured-output field — same forced-tool-use workaround as JSON mode. - seed (
seed) — No seed parameter — no reproducibility knob. - nCompletions (
n) — No n parameter — exactly one completion per request, always. - frequencyPenalty (
frequency_penalty) — No frequency or presence penalty knobs. - logprobs (
logprobs) — No logprobs support at all.
The cost delta
GPT-5.6 Luna ($0.45/M blended) to Claude Haiku 4.5 ($2.00/M blended): blended cost rises 344.4%. Full Claude Haiku 4.5 pricing →
Recompute on your own token shape at the cost calculator.
Which Anthropic model to move to
claude-haiku-4-5 — $2.00/M blended. Pricing → Alternatives →
claude-sonnet-4-6 — $6.00/M blended. Pricing → Alternatives →
claude-opus-4-8 — $10.00/M blended. Pricing → Alternatives →
The cutover checklist
- Dual-run both providers on the same prompts and diff the outputs before cutting traffic over.
- Expect a rate-limit cold start on a brand-new Anthropic key — see Anthropic rate limits.
- Fix every row marked "No equivalent" or "Now required" above before switching a single production call.
- Keep the OpenAI client and key live behind a feature flag until the Anthropic path has run in production for at least a week.
Route it through All AI Ask instead
This is not a base-URL swap — the All AI Ask gateway uses its own request shape (a `prompt` string and a `models` array, not Anthropic's message format), documented in full at /api-docs. In exchange, this one call can also run the prompt across other models side by side.
curl https://allaiask.com/api/v1/prompt \
-H "Authorization: Bearer $ALLAIASK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Say hello in one sentence.", "models": ["claude-haiku-4-5"]}'FAQ
Is OpenAI to Anthropic a drop-in migration?
No — it's a code change. 12 of 18 tracked parameters need attention; see the mapping table above for exactly which ones and why.
What breaks first when I port OpenAI code to Anthropic?
reasoningEffort — OpenAI's `reasoning_effort` has no Anthropic equivalent (No effort enum — extended thinking is a token budget, not a graduated setting.).
