OpenAI ↔ Anthropic Translator
Translate API requests between OpenAI and Anthropic formats with per-line mapping.
{
"model": "gpt-5.2",
"system": "You are a concise coding assistant.",
"messages": [
{
"role": "user",
"content": "Write a function that reverses a string."
}
],
"max_tokens": 1024,
"temperature": 0.7,
"stop_sequences": [
"END"
],
"tools": [
{
"name": "run_tests",
"description": "Run the project's test suite and return failures.",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Test file path"
}
},
"required": [
"path"
]
}
}
],
"tool_choice": {
"type": "auto"
}
}Translation warnings (1)
- model "gpt-5.2" is an OpenAI ID — pick the Claude equivalent (Sonnet ≈ GPT mainline, Haiku ≈ mini).
How it works
OpenAI and Anthropic expose the same fundamental capability — chat completion with tool calling — behind two request formats that differ in dozens of small, irritating ways. This translator parses a request body for either API, auto-detects which dialect it is, and emits the equivalent request for the other provider, with an explicit warning for every parameter that has no clean mapping.
Direction detection looks at structural signals rather than guessing: a top-level system string, stop_sequences, top_k or tools with input_schema mark a request as Anthropic-shaped; system-role messages or type: "function" tool wrappers mark it as OpenAI-shaped. The translation then applies the documented field mappings: system prompt placement, max_tokens(required on Anthropic, defaulted to 1024 if your OpenAI request omitted it), temperature clamping from OpenAI's 0–2 range to Anthropic's 0–1, stop-sequence renaming, tool wrapper conversion in both directions, and tool_choice translation across the auto/required/forced-function spectrum.
The warnings list is the part to actually read before shipping. Parameters like presence_penalty, logit_bias, seed and n exist only on OpenAI; top_k and prompt-caching cache_control blocks exist only on Anthropic. The translator drops them rather than inventing fake equivalents, and tells you exactly what was dropped and why — silent lossy conversion is how migration bugs are born.
Model IDs are carried through with a warning rather than auto-substituted, because the right mapping depends on your task: Sonnet-class and GPT-mainline models are rough peers on coding work, but pricing, context windows and tool-use reliability differ enough that the choice deserves a human decision. Everything runs locally in your browser; your system prompts and tool schemas — often the most proprietary text a team owns — never leave the page.
If you find yourself translating requests at runtime rather than as a one-time migration — routing cheap tasks to one provider and hard ones to another, or failing over when a provider sheds load — the maintainable answer is a gateway layer that speaks one format inbound and adapts per provider outbound. The mappings on this page are exactly the ones such a layer implements; use the translator to learn the seams, then automate them.
Frequently asked questions
What are the main parameter differences between OpenAI and Anthropic?
The big four: Anthropic takes the system prompt as a top-level system field while OpenAI puts it inside messages as a system role; Anthropic requires max_tokens on every request while OpenAI makes it optional; Anthropic's temperature range is 0–1 while OpenAI allows 0–2; and stop sequences are called stop_sequences on Anthropic versus stop on OpenAI. Beyond those, OpenAI-only parameters like presence_penalty, frequency_penalty, logit_bias, seed and n simply have no Anthropic equivalent and must be dropped.
How do tool and function-calling schemas differ between the two APIs?
The JSON Schema describing parameters is identical — only the wrapper differs. OpenAI wraps it as {type: "function", function: {name, description, parameters}} while Anthropic flattens it to {name, description, input_schema}. Tool choice also maps cleanly: OpenAI's "auto" becomes Anthropic's {type: "auto"}, "required" becomes {type: "any"}, and forcing a specific function becomes {type: "tool", name}. The translator handles all of these mechanically, so a tool-heavy request migrates without retyping schemas.
How is the system prompt handled when translating?
Going OpenAI to Anthropic, every system-role (and developer-role) message is lifted out of the messages array and joined into Anthropic's top-level system string, because Anthropic rejects system roles inside messages. Going the other way, the top-level system field is converted into a leading system message. If your Anthropic request uses system content blocks with cache_control markers, they are flattened to plain text and the tool warns you — prompt-caching hints have no direct OpenAI representation.
Should I migrate requests by hand or put a gateway in front instead?
Hand-translation is fine for a one-time migration or for testing the same prompt across providers. If you want to route traffic dynamically — say, sending cheap tasks to one provider and hard tasks to another, or failing over during a 529 overload — translating in application code becomes a maintenance burden. That routing-layer problem is what an LLM gateway solves: one request format in, provider-specific formats out, with rules deciding the destination. FORG's gateway takes exactly that approach.
Does this translator send my request JSON to a server?
No. Parsing, direction detection and translation all run as plain JavaScript in your browser tab — there is no API call, and your request body, which often contains proprietary system prompts, never leaves the page. You can verify in the network tab of devtools: typing in the source pane triggers zero requests. The translation logic is deterministic, so the same input always yields the same output and warnings.
Built by FORG — AI cost observability for agentic coding. Free tools, no signup, nothing leaves your browser.
Learn about FORG