n4nAI

Comparing OpenAI and Anthropic request bodies with curl

A practical head-to-head of curl OpenAI vs Anthropic request bodies: auth, message shape, streaming, cost model, limits, and ergonomics, with a comparison table and verdict.

n4n Team3 min read742 words

Audio narration

Coming soon — every post will get a voice note here.

When you wire LLM calls into a shell script or CI job, the difference between a curl openai vs anthropic request body is more than auth headers. The two providers shape messages, system prompts, and streaming flags differently, and those differences leak into your error handling and retry logic.

Authentication and endpoint basics

OpenAI expects a bearer token in Authorization and posts to /v1/chat/completions. Anthropic uses x-api-key and anthropic-version headers, posting to /v1/messages. Neither accepts the other’s shape.

# OpenAI
curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role":"user","content":"Say hi."}],
    "max_tokens": 50
  }'
# Anthropic
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet-20241022",
    "max_tokens": 50,
    "messages": [{"role":"user","content":"Say hi."}]
  }'

The curl openai vs anthropic request body contrast starts with required fields: Anthropic mandates max_tokens at the top level; OpenAI treats it as optional but you should set it.

System prompts

OpenAI nests system inside messages with role:"system". Anthropic pulls it out to a top-level system string (or array). That means you cannot copy a messages array verbatim between the two.

// OpenAI
{"messages":[{"role":"system","content":"You are terse."},{"role":"user","content":"Hi"}]}
// Anthropic
{"system":"You are terse","messages":[{"role":"user","content":"Hi"}]}

Message content and multimodal

OpenAI accepts content as either a string or an array of parts. A vision request looks like:

{
  "messages": [{
    "role": "user",
    "content": [
      {"type":"text","text":"Describe"},
      {"type":"image_url","image_url":{"url":"https://example.com/cat.jpg"}}
    ]
  }]
}

Anthropic always uses a content array of typed blocks:

{
  "messages": [{
    "role": "user",
    "content": [
      {"type":"text","text":"Describe"},
      {"type":"image","source":{"type":"url","url":"https://example.com/cat.jpg"}}
    ]
  }]
}

If you build bodies programmatically, you need separate serializers.

Capabilities

Both support tool/function calling, vision, and streaming, but the wire format diverges. OpenAI attaches tools and tool_calls inside message objects. Anthropic uses tools at top level and returns tool_use blocks inside content arrays.

// OpenAI tool def
{"tools":[{"type":"function","function":{"name":"get_weather","parameters":{"type":"object"}}}]}
// Anthropic tool def
{"tools":[{"name":"get_weather","input_schema":{"type":"object"}}]}

Streaming: OpenAI sends SSE with data: {json} lines ending with data: [DONE]. Anthropic streams SSE with event types message_start, content_block_delta, and message_stop. Your parser must branch on provider.

# OpenAI stream
curl -N https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hi"}],"stream":true}'
# Anthropic stream
curl -N https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-3-5-sonnet-20241022","max_tokens":50,"messages":[{"role":"user","content":"Hi"}],"stream":true}'

Price and cost model

Both meter by token: separate input and output rates, billed per 1K or 1M tokens. Anthropic introduces prompt caching via cache_control on content blocks, giving discounted reuse of long system prompts. OpenAI offers cached token pricing on supported models with prompt_cache semantics in the response. Without quoting numbers, expect similar order-of-magnitude costs; the caching discount can matter for repetitive long contexts.

A minimal Anthropic cache hint:

{"system":[{"type":"text","text":"Long context..."},{"type":"text","text":"More","cache_control":{"type":"ephemeral"}}]}

OpenAI echoes prompt_tokens_details.cached_tokens when a hit occurs.

Latency and throughput

Empirically, both return first token in hundreds of milliseconds to seconds depending on model and load. Streaming helps perceived latency equally. Anthropic’s requirement to specify max_tokens prevents unbounded generation; OpenAI’s default (if omitted) may cap at a low server limit, causing silent truncation. For bulk curl jobs, set max_tokens explicitly on both.

Throughput on long generations is model-bound, not API-bound. Use stream to avoid client timeouts in shell scripts.

Ergonomics

The curl openai vs anthropic request body ergonomics favor OpenAI if you already speak chat-completions: one schema, many models, widespread examples. Anthropic’s split system field and version header add friction but make the system prompt explicit. A gateway like n4n.ai exposes one OpenAI-compatible endpoint that addresses 240+ models and handles fallback when a provider is degraded, letting you keep the OpenAI body shape while routing to either backend.

Error shapes

OpenAI returns {error:{message,type,code}} with HTTP status. Anthropic returns {type:"error",error:{type,message}}. Your shell script’s jq paths differ slightly.

# OpenAI error check
jq -e '.error' && echo "fail"

# Anthropic error check
jq -e '.type=="error"' && echo "fail"

Ecosystem

OpenAI’s API has years of community curl snippets, SDKs in every language, and middleware expecting its schema. Anthropic’s SDKs are official and clean but less ubiquitous. If you script with curl directly, ecosystem shows up as how many StackOverflow answers match your typo. Both publish OpenAPI specs; Anthropic’s includes the version header as a required parameter.

Limits

Context windows are model-specific; both enforce per-org rate limits returned in response headers (x-ratelimit-* for OpenAI, anthropic-ratelimit-* for Anthropic). Anthropic requires max_tokens <= model limit; OpenAI may reject if exceeds. Neither allows missing model. Anthropic rejects requests without anthropic-version; OpenAI ignores unknown headers.

Comparison table

Dimension OpenAI Anthropic
Auth Authorization: Bearer x-api-key + anthropic-version
System prompt In messages as role:system Top-level system field
Required fields model, messages model, messages, max_tokens
Streaming SSE data: JSON, [DONE] Named events message_start etc.
Tool use tools in body, tool_calls in msg tools top-level, tool_use blocks
Cost model Per-token in/out, cached discounts Per-token in/out, prompt caching
Latency Similar, streaming recommended Similar, max_tokens mandatory
Error body {error:{message,type}} {type:"error",error:{...}}
Ecosystem Larger community Smaller but official SDKs

Which to choose

Use OpenAI-shaped requests when: You maintain existing chat-completion code, need maximum community examples, or want one body to hit many model variants. The curl openai vs anthropic request body conversion cost is low if you stay in OpenAI land.

Use Anthropic-shaped requests when: You rely on long context with prompt caching, prefer explicit system separation, or target Claude-specific features like extended thinking (where supported). Write a small wrapper to inject anthropic-version and hoist system.

Use a unified gateway when: You want fallback across providers without maintaining two curl templates. Keeping the OpenAI body and routing via a compatible endpoint reduces surface area; the gateway forwards cache-control hints and meters per-token usage.

Pick based on where your code lives today. If it’s a throwaway shell script, OpenAI’s schema is less typing. If it’s a production pipeline with tight cost control, Anthropic’s caching and explicit limits earn their verbosity.

Tagscurlopenai-apianthropic-apicomparison

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All curl llm api cookbook posts →