Four LLM APIs, Four Response Shapes: What Changes When You Switch Providers

If you build across providers, the model matters less than the envelope it comes back in. The text is the easy part. The differences that break code are where the answer lives, how a tool call is signaled, how reasoning is carried between turns, and how tokens are counted. This is how the latest flagship APIs compare as of October 2026: OpenAI’s GPT-6 family, Anthropic’s Claude 5.x family, Google’s Gemini 3.x on the Interactions API, and Meta’s Muse Spark 1.1.

The envelope at a glance

ProviderEndpointAnswer lives inTool call signaled by
OpenAI (GPT-6 Astra, 6.1 Sol, 6 Luna)/v1/responsesoutput[] items: message, reasoning, function_callA function_call item in output
Anthropic (Claude 5.x)/v1/messagescontent[] blocks: text, thinking, tool_usestop_reason: "tool_use"
Google (Gemini 3.8 Flash)/v1beta/interactionssteps[]: model_output, function_call, and morestatus: "requires_action"
Meta (Muse Spark 1.1)api.meta.ai/v1OpenAI Responses shape, or Anthropic Messages shapeSame as whichever format you call

Three of the four now return a typed list rather than a single string, and the lists are not interchangeable. OpenAI calls them items, Anthropic calls them blocks, and Google calls them steps. Meta sidesteps the problem by speaking two existing dialects: its API is compatible with OpenAI’s Responses API and also exposes the Anthropic Messages format natively, thinking blocks included.

Gotchas that bite when you switch

1. Never read the first element

A reasoning model can start its reply with a reasoning item, a thinking block, or a thought step. Iterate and filter by type. On OpenAI, an empty output_text usually means every item was a tool call, not that the model said nothing.

2. Reasoning must be carried forward, and each vendor does it differently

Anthropic thinking blocks carry a signature and must be passed back unmodified, or the request fails with a 400. OpenAI’s GPT-5.6 and later reuse prior reasoning across turns by default when you continue with previous_response_id; stateless or zero-retention setups replay encrypted reasoning items instead. Meta’s Muse Spark supports the same stateless encrypted replay. Google’s steps carry thought signatures and optional thought summaries.

3. Token accounting is not apples to apples

Anthropic reports thinking tokens as a breakdown inside output_tokens. Google reports total_thought_tokens as its own field, and in its documented examples total_tokens equals input plus output plus thought, so output excludes thinking. OpenAI adds cache fields, cached_tokens and cache_write_tokens, and since GPT-5.6 cache writes bill at 1.25x the uncached input rate. If you compute cost from output_tokens alone, you will be wrong on at least one of these.

4. State lives in different places

Anthropic’s Messages API is stateless: you resend history. OpenAI offers previous_response_id and a Conversations API. Google offers previous_interaction_id. If your abstraction assumes one model, you will either over-send context or lose it.

5. Stop and failure signals differ

Anthropic uses a stop_reason enum: end_turn, max_tokens, stop_sequence, tool_use, pause_turn, refusal, and model_context_window_exceeded. A refusal can carry a structured category. Google uses a status enum (completed, requires_action, incomplete, failed, cancelled, queued) plus an errors array, and a continuation_token to resume a truncated decode. Legacy Google generateContent can return a 200 with empty parts and a SAFETY finish reason, so check it explicitly.

What to do about it

Write a thin adapter that normalizes every provider into three things: a list of typed parts, a tool-call flag, and a usage object with thinking tokens broken out separately. The migration most teams still face is on Google’s side. Interactions is the recommended path for new projects and generateContent remains fully supported, but moving from candidates and parts to steps and status touches every parser. Meta is the cheapest to add: if you already handle Responses or Messages, you already handle Muse Spark.

These APIs change monthly. Check the current docs before you ship.

Sources

Leave a Reply