# One API Does Not Mean One Protocol: Chat Completions, Responses, Messages, and Gemini

> Source: <https://dev.to/xiuai-lab/one-api-does-not-mean-one-protocol-chat-completions-responses-messages-and-gemini-39kd>
> Published: 2026-08-30 10:40:07+00:00

"OpenAI compatible" is useful shorthand, but it is not a complete integration contract.

Two clients can accept the same API key and base domain while sending different request paths, authentication headers, payload shapes, streaming events, and tool-call formats. That difference matters when you connect coding agents, SDKs, or production applications to a multi-model gateway.

At XiuAI, we expose four text-generation routes through [XiuRouter](https://router.xiu.ai/en/):

The practical rule is simple:

Start with the protocol your client actually sends. Do not choose a protocol from the model name or from an "OpenAI compatible" label.

This article explains how to make that choice and how to verify the integration without turning a small configuration change into a production incident.

A model name does not determine the request protocol.

For example, the same model may be reachable through Chat Completions in one service group but not through Responses or Messages in another. A successful Chat Completions request is not proof that the same model and route will support Responses, Anthropic Messages, or Gemini GenerateContent.

Use the client's native behavior as the starting point:

| Client or application | Preferred route |
|---|---|
| Codex, agents, and new OpenAI-style applications | OpenAI Responses |
| Claude Code, Anthropic SDKs, and Claude-native clients | Anthropic Messages |
| Existing OpenAI-compatible applications that do not support Responses | Chat Completions |
| Gemini SDKs and Gemini-native clients | Gemini GenerateContent |

If the client documentation is unclear, inspect its official configuration guide or request logs. Do not infer the protocol from a generic compatibility badge.

An OpenAI-compatible SDK usually appends paths under `/v1\`

, so its configured base URL is:

`\`

`text`

https://router-api.xiu.ai/v1

\`\`

A Claude client that appends `/v1/messages\`

, or a Gemini client that appends `/v1beta/models/...\`

, should use the API root:

`\`

`text`

https://router-api.xiu.ai

\`\`

This is a common source of duplicated paths such as `/v1/v1/messages\`

, especially when a configuration field is called "API URL" without explaining whether it expects a domain, a base path, or a complete endpoint.

For direct requests, use the complete path:

| Protocol | Method and path |
|---|---|
| Chat Completions | `POST /v1/chat/completions\` |
| Responses | `POST /v1/responses\` |
| Anthropic Messages | `POST /v1/messages\` |
| Gemini GenerateContent | `POST /v1beta/models/{model}:generateContent\` |

OpenAI-compatible requests use a Bearer token:

`\`

`http`

Authorization: Bearer YOUR_XIUROUTER_API_KEY

\`\`

Anthropic Messages can use:

`\`

`http`

x-api-key: YOUR_XIUROUTER_API_KEY

anthropic-version: 2023-06-01

\`\`

XiuRouter also accepts a Bearer token on the Messages route for gateway clients such as Claude Code.

Gemini GenerateContent can use:

`\`

`http`

x-goog-api-key: YOUR_XIUROUTER_API_KEY

\`\`

Gemini's `key\`

query parameter is accepted as well, but headers are easier to keep out of access logs and copied URLs.

Before moving application traffic, test the exact combination of:

First list the models visible to the scoped key:

`\`

`bash`

curl https://router-api.xiu.ai/v1/models \

-H "Authorization: Bearer $XIUROUTER_API_KEY"

\`\`

Then send one small request through the route your client will use. For Responses:

`\`

`bash`

curl https://router-api.xiu.ai/v1/responses \

-H "Authorization: Bearer $XIUROUTER_API_KEY" \

-H "Content-Type: application/json" \

-d '{

"model": "YOUR_MODEL_ID",

"input": "Reply only with: XiuRouter connected"

}'

\`\`

For Anthropic Messages:

`\`

`bash`

curl https://router-api.xiu.ai/v1/messages \

-H "x-api-key: $XIUROUTER_API_KEY" \

-H "anthropic-version: 2023-06-01" \

-H "Content-Type: application/json" \

-d '{

"model": "YOUR_MODEL_ID",

"max_tokens": 64,

"messages": [

{

"role": "user",

"content": "Reply only with: XiuRouter connected"

}

]

}'

\`\`

After the response, verify the same request in usage records: key, model, service group, endpoint, token counts, status, and cost.

The small test is billable. Check the [current model and service-group pricing](https://router.xiu.ai/en/pricing) before sending it.

A gateway route can support the core text request without implementing every provider feature.

Current XiuRouter boundaries include:

`/v1/messages/count_tokens\`

has no dedicated route. Claude Code documents token counting as optional and can fall back through inference, but you still need to verify that the final task completes.`previous_response_id\`

, background mode, and provider-hosted tools are outside the current compatibility scope.These are not edge cases to hide in fine print. They determine whether an agent can finish a task, whether a retry is safe, and whether usage records match the client's expectations.

Create one key per application or environment. Limit models, service groups, quota, expiration, and IP scope where appropriate.

For a migration:

Changing only a base URL is convenient. Treating that change as proof of full protocol compatibility is not.

The current endpoint table and limitations are maintained in the [XiuRouter API compatibility guide](https://docs.xiu.ai/en/router/api-compatibility/). The guide was reviewed on August 22, 2026, and this article was checked against it on August 30, 2026.

XiuAI and its products are operated by XiuLab Inc, a U.S. corporation.
