---
title: "How PipeLLM Converts Between OpenAI, Anthropic, and Gemini Formats — Automatically"
route_path: "/blog/automatic-protocol-conversion"
canonical_url: "https://www.pipellm.ai/blog/automatic-protocol-conversion"
markdown_path: "/llms/blog/automatic-protocol-conversion.md"
markdown_url: "https://www.pipellm.ai/llms/blog/automatic-protocol-conversion.md"
content_type: "blog-post-page"
description: "OpenAI, Anthropic, and Google each have their own API format. PipeLLM translates between them automatically — so you can call Claude with the OpenAI SDK, or use Gemini through the Anthropic format. Here's how it works under the hood."
generated_at: "2026-03-27T06:53:30.752Z"
---
Canonical page: https://www.pipellm.ai/blog/automatic-protocol-conversion
Markdown mirror: https://www.pipellm.ai/llms/blog/automatic-protocol-conversion.md
Content type: blog-post-page
Generated at: 2026-03-27T06:53:30.752Z
# How PipeLLM Converts Between OpenAI, Anthropic, and Gemini Formats — Automatically
## Query Intents
- Read the full PipeLLM article titled "How PipeLLM Converts Between OpenAI, Anthropic, and Gemini Formats — Automatically".
- Understand the category, publish date, and canonical URL for this article.
- Provide an LLM-friendly Markdown mirror of the article body.
## Article Metadata
- Title: How PipeLLM Converts Between OpenAI, Anthropic, and Gemini Formats — Automatically
- Category: Tech
- Published at: 2026-03-20T16:00:00.000Z
- Meta title: How PipeLLM Converts Between OpenAI, Anthropic, and Gemini Formats — Automatically
- Meta description: OpenAI, Anthropic, and Google each have their own API format. PipeLLM translates between them automatically — so you can call Claude with the OpenAI SDK, or use Gemini through the Anthropic format. Here's how it works under the hood.
![Pipellm](https://assets-cdn.pipellm.ai/api/media/file/blog2.png)
## Article Body
### The Format Problem

Every major AI provider has invented its own API format. They look similar at first glance, but the differences run deep:

**OpenAI format:**

```json
{
  "model": "gpt-4.1",
  "messages": [
    {"role": "system", "content": "You are helpful."},
    {"role": "user", "content": "Hello"}
  ]
}
```

**Anthropic format:**

```json
{
  "model": "claude-sonnet-4-20250514",
  "system": "You are helpful.",
  "messages": [
    {"role": "user", "content": "Hello"}
  ]
}
```

`Gemini format:`

```
json
{
  "model": "gemini-2.5-pro",
  "systemInstruction": {"parts": [{"text": "You are helpful."}]},
  "contents": [
    {"role": "user", "parts": [{"text": "Hello"}]}
  ]
}
```

Three providers. Three ways to say the same thing. Notice how `system` is a message role in OpenAI, a top-level field in Anthropic, and a `systemInstruction` object in Gemini. The message structure itself is different too — `content` vs `parts`, `messages` vs `contents`.

This means that switching providers isn't just changing a model name. It's rewriting your entire request and response handling layer.

### What PipeLLM Does

PipeLLM acts as a transparent protocol translator. You send a request in whatever format your SDK uses, and PipeLLM converts it to the target provider's format before forwarding it. The response is converted back before reaching your code.

Your App (OpenAI SDK)

→ PipeLLM (detects OpenAI format)

→ converts to Anthropic format

→ Anthropic API

← converts response back to OpenAI format

← Your app receives a standard OpenAI response

Your code never knows the difference I. It's the same SDK, the same response types, the same error handling.

### Real-World Example: Using Claude with the OpenAI SDK

```python
from openai import OpenAI
client = OpenAI(
    base_url="https://api.pipellm.ai/openai/v1",
    api_key="your-pipellm-key"
)
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-20250514",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain quantum computing in one paragraph."}
    ],
    stream=True
)
```

for chunk in response:

print(chunk.choices[0].delta.content, end="")

Behind the scenes, PipeLLM:

1. **Extracts** the `system` message from the `messages` array
2. **Maps** it to Anthropic's top-level `system` field
3. **Converts** the remaining messages to Anthropic's format
4. **Forwards** the request to `api.anthropic.com`
5. **Streams** the response back, converting each chunk to the OpenAI `delta` format

All in real-time, with no buffering.

### The Hard Parts: Tool Calls and Multimodal

Simple text messages are straightforward to convert. The real complexity lies in **tool calling** (function calling) and **multimodal inputs** (images, PDFs).

#### Tool Calling

Each provider structures function definitions and tool call results differently:

AspectOpenAIAnthropicGemini

Definition field

```
tools[].function
tools[].input_schema
tools[].functionDeclarations
```

Call format

```
tool_calls[].function
content[].type: "tool_use"
parts[].functionCall
```

Result format

`role: "tool"` message

`role: "user"` with `tool_result`

```
parts[].functionResponse
```

PipeLLM handles all of these mappings automatically, including edge cases like parallel tool calls and multi-turn tool conversations.

#### Multimodal Inputs

Sending an image to GPT-4.1 looks different from sending one to Claude or Gemini. PipeLLM normalizes image inputs across formats — whether they're base64-encoded, URL references, or inline binary data.

### Streaming Compatibility

Streaming is where most "API adapters" break down. Each provider uses a different Server-Sent Events (SSE) format:

- **OpenAI**: `data: {"choices": [{"delta": {"content": "..."}}]}`
- **Anthropic**: `event: content_block_delta` + `data: {"delta": {"text": "..."}}`
- **Gemini**: Different chunking with `candidates[].content.parts`

PipeLLM converts streaming events in real time, chunk by chunk. There's no waiting for the full response — each token is translated and forwarded as it arrives.

### What's Not Converted

Transparency matters. Here are the things PipeLLM intentionally does **not** change:

- **Model behavior**: We don't modify prompts or inject system instructions
- **Token counts**: Usage stats reflect the actual provider's tokenization
- **Rate limits**: Provider-side limits are passed through as-is
- **Pricing**: You see the actual cost from each provider

PipeLLM is a translator, not a middleware that modifies your data.

### Try It Yourself

Pick any supported SDK and point it at PipeLLM:

SDKBase URL

OpenAI

[`https://api.pipellm.ai/openai/v1`](https://api.pipellm.ai/openai/v1)

Anthropic

[`https://api.pipellm.ai/anthropic/v1`](https://api.pipellm.ai/anthropic/v1)

Google Gen AI

[`https://api.pipellm.ai/gemini/v1beta`](https://api.pipellm.ai/gemini/v1beta)

Full conversion documentation is available at [docs.pipellm.ai/converter](https://docs.pipellm.ai/converter).

---

_PipeLLM is the unified API gateway for LLMs. Write code once, access every model — protocol translation handled automatically._
