induwara.lk
induwara.lkDeveloper · AI

Anthropic (Claude) to OpenAI API Converter

Paste an Anthropic Messages API request or response and get the equivalent OpenAI Chat Completions JSON — system, tool_use, tool_result, stop_reason and usage remapped field by field. Runs entirely in your browser: no key, no upload, no signup.

By Induwara AshinsanaUpdated Jul 11, 2026
Convert a Claude requestto OpenAI Chat Completions
What are you converting?

Paste an Anthropic Messages API request body. It is parsed in your browser — nothing is uploaded.

o-series and GPT-5 models use max_completion_tokens; older chat models use max_tokens.

Output format
Target
/v1/chat/completions
Fields mapped
6
Restructured
3
Messages out
4

Where to send it

POST https://api.openai.com/v1/chat/completions
Authorization: Bearer $OPENAI_API_KEY
content-type: application/json
Converted OpenAI request body
{
  "model": "claude-opus-4-8",
  "messages": [
    {
      "role": "system",
      "content": "You are terse."
    },
    {
      "role": "user",
      "content": "Weather in Colombo?"
    },
    {
      "role": "assistant",
      "tool_calls": [
        {
          "id": "toolu_1",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"city\":\"Colombo\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "toolu_1",
      "content": "31C"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get weather",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            }
          },
          "required": [
            "city"
          ]
        }
      }
    }
  ],
  "max_tokens": 1024
}

What changed, field by field

AnthropicOpenAIStatusDetail
model: claude-opus-4-8modelMappedPassed through untouched — model strings are not validated.
system (top-level string)messages[0] (role:system)RestructuredAnthropic's top-level system field becomes a leading system message.
content: tool_usemessage.tool_calls[]RestructuredEach tool_use block became a tool_call; its input object was JSON.stringify()'d into arguments.
content: tool_resultmessage (role:tool)RestructuredEach tool_result became a separate {role:"tool"} message keyed by tool_use_id.
tools[].input_schematools[].function.parametersRenamedname + description nest under function; input_schema copied verbatim to parameters.
max_tokens: 1024max_tokens: 1024MappedCarried over unchanged.

Mapping follows the official Anthropic Messages and OpenAI Chat Completions references. Model strings pass through untouched — this is a format converter, not a proxy. Sources are listed below the tool.

How it works

The converter is a deterministic restructuring of a published schema — there is no model call. It reads your Anthropic Messages payload, applies a fixed set of mapping rules transcribed from the official Anthropic and OpenAI API references, and emits the equivalent OpenAI Chat Completions body. Every rule is a static table entry, so the same input always produces the same output, and the result is testable. Two directions are supported: a whole request body, and a whole response body.

Request: Anthropic → OpenAI

  1. System prompt. Anthropic's top-level system (a string or an array of text blocks) becomes a leading {role:"system"} message, because OpenAI has no top-level system field.
  2. Messages & content blocks. Roles pass through. A text block collapses to a string (or a text content part when mixed with images); an image block becomes an image_url part (base64 sources become data: URLs).
  3. Tool calls. An assistant tool_use block becomes a tool_calls entry. Anthropic's input is a JSON object; OpenAI's arguments is a JSON string, so the converter runs JSON.stringify(input).
  4. Tool results. A user tool_result block becomes its own {role:"tool", tool_call_id, content} message, placed after the assistant message that made the matching call so the turn order stays valid.
  5. Tools & tool_choice. tools[].input_schema becomes function.parameters (copied verbatim); {type:auto}→"auto", {type:any}→"required", {type:tool,name}→{type:function,function:{name}}.
  6. Scalars. max_tokens is carried over (rename to max_completion_tokens for o-series / GPT-5 targets via the toggle); stop_sequencesstop; temperature, top_p and stream pass through.

Response: Anthropic → OpenAI

  1. The message is wrapped as {id, object:"chat.completion", model, choices:[{index:0, message, finish_reason}], usage}.
  2. stop_reason → finish_reason: end_turn→stop, max_tokens→length, stop_sequence→stop, tool_use→tool_calls, refusal→content_filter, and pause_turn→stop (flagged approximate).
  3. usage: input_tokens→prompt_tokens, output_tokens→completion_tokens, and total_tokens = input_tokens + output_tokens (OpenAI reports the total; Anthropic does not).

As a credibility check, two worked conversions ship as fixtures and are reconciled against the references on every load, and the response direction carries an independent arithmetic invariant — total_tokens must equal prompt_tokens + completion_tokens, recomputed on a separate code path. Anthropic-only features that have no faithful OpenAI target (thinking, cache_control, service_tier) are listed in the notes rather than silently dropped.

Worked examples

A — request with a tool and a tool result (Anthropic → OpenAI)

  1. In: system: "You are terse."
  2. tools:[{name:"get_weather", input_schema:{...}}]
  3. messages:[ user "Weather in Colombo?",
  4. assistant [tool_use toolu_1 get_weather {city:"Colombo"}],
  5. user [tool_result toolu_1 "31C"] ]
  6. Out: messages:[ system "You are terse.",
  7. user "Weather in Colombo?",
  8. assistant {tool_calls:[{id:"toolu_1",type:"function",
  9. function:{name:"get_weather",arguments:"{\"city\":\"Colombo\"}"}}]},
  10. tool {tool_call_id:"toolu_1", content:"31C"} ]
  11. tools:[{type:"function",function:{...,parameters:<input_schema>}}]
  12. input_schema → parameters (verbatim); input object → arguments JSON string

B — response mapping (Anthropic → OpenAI)

  1. In: {id:"msg_1", content:[{type:"text",text:"It is 31C."}],
  2. stop_reason:"end_turn", usage:{input_tokens:42, output_tokens:6}}
  3. Out: {id:"msg_1", object:"chat.completion",
  4. choices:[{index:0, message:{role:"assistant",content:"It is 31C."},
  5. finish_reason:"stop"}],
  6. usage:{prompt_tokens:42, completion_tokens:6, total_tokens:48}}
  7. end_turn → stop; 42 + 6 = 48 = total_tokens

C — edge cases

  1. Empty textarea → friendly 'Paste an Anthropic …' message, no crash
  2. JSON array instead of {} → 'must be a JSON object' error
  3. Request with no messages → converts, warns the messages array is empty
  4. Response stop_reason "refusal" → finish_reason "content_filter"
  5. Response stop_reason "pause_turn" → finish_reason "stop", flagged approximate
  6. cache_control / thinking blocks → stripped and listed in the notes panel

Frequently asked questions

Sources & references

The mapping rules were last cross-checked against the official references on 2026-07-11. This page is reviewed whenever either provider ships a breaking request- or response-schema change.

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a field that maps wrong, or want another provider added?

Email me at [email protected] — most fixes ship within 24 hours.