Anthropic-Compatible Messages API: Use Claude Without Vendor Lock-In
The Anthropic Messages API has its own design — a content-block model, system-prompt-as-top-level-field, native tool use, prompt caching, extended thinking. Apps built on Claude tend to use Anthropic's SDK directly, and migrating those apps usually means rewriting the call shape. CallMissed avoids that: we expose a Messages-compatible endpoint so your existing Anthropic code keeps working.
Two paths to the same endpoint
CallMissed serves the Messages-compatible surface at two paths:
/v1/messages — top-level for general clients/anthropic/v1/messages — drop-in path for the official Anthropic SDKThe second exists because some SDKs prepend /v1 themselves. Pointing the official anthropic-python or anthropic-typescript clients at https://api.callmissed.com/anthropic works without flag changes:
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.callmissed.com/anthropic",
api_key="cm_live_..."
)
resp = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
messages=[{"role": "user", "content": "hi"}],
)What is supported
The compatible surface preserves the parts of the Messages spec you actually use in production:
system field (string or content-block list)message_start, content_block_delta, message_delta, message_stoptools array and tool_use / tool_result content blocksstop_reasonWhat is different
Three honest differences:
cache_control markers are accepted in the request, but caching behavior depends on the upstream model and routing. Treat it as a hint, not a guarantee.anthropic-beta) for experimental features are passed through where supported. Some experimental Claude features are not yet exposed.If your app depends on a specific beta feature, check the /api/v1/models capability flags before switching.
Why this exists
A lot of production AI code is now written against the Anthropic SDK. The schema is good — content blocks compose better than the OpenAI message format for tool use, vision, and structured outputs. Forcing those teams to rewrite to migrate is a tax on adoption. We want the migration to be a base-URL change.
Tool use, in detail
Tool use on the Messages API works on a request/response loop:
resp = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
tools=[{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}],
messages=[{"role": "user", "content": "weather in Bangalore"}],
)
# resp.stop_reason == "tool_use"
# resp.content[-1].name == "get_weather"
# resp.content[-1].input == {"city": "Bangalore"}You execute the tool, append a tool_result content block, and call messages.create again. The loop continues until stop_reason != "tool_use". CallMissed routes each turn to the chosen model and meters tokens across the conversation.
Streaming tool calls
Streaming with tools works the same way it does on Anthropic's native API: tool_use content blocks stream in content_block_delta events with partial_json deltas. Standard parsers (the official anthropic-python MessageStream helper, or any SSE parser following the spec) work without modification.
Choosing this over the OpenAI-compatible endpoint
If you have:
role: system message…use /anthropic/v1/messages. Otherwise the OpenAI-compatible /v1/chat/completions is fine. They reach the same models; the schema is the only difference.
What you do not get from us
Anthropic-specific commercial agreements (HIPAA BAA with Anthropic specifically, regional data residency commitments only Anthropic can offer, the Claude Console UI, the workbench) are not part of this surface. CallMissed offers its own equivalents for the parts that matter — tenant isolation, audit logs, regional deployment options — but we do not impersonate Anthropic's commercial relationship.
If you need that direct relationship, use Anthropic. If you need flexibility, model choice, and a single bill, use us.