Anthropic-Compatible Messages API: Use Claude Without Vendor Lock-In

CallMissed
·5 min readGuide

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 SDK
  • The 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:

    python
    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 prompts as a top-level system field (string or content-block list)
  • Streaming with the standard SSE event shape — message_start, content_block_delta, message_delta, message_stop
  • Tool use with the native tools array and tool_use / tool_result content blocks
  • Vision via image content blocks
  • Stop sequences and stop_reason
  • Token counting with input and output token fields populated on every response
  • What is different

    Three honest differences:

  • Prompt caching is best-effort. Claude's 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.
  • Beta headers (anthropic-beta) for experimental features are passed through where supported. Some experimental Claude features are not yet exposed.
  • Extended thinking blocks are returned as Claude returns them when the chosen model is a Claude variant. Non-Claude models obviously cannot emit them.
  • 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:

    python
    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:

  • An existing app on the Anthropic SDK
  • Tool-heavy workflows (the content-block model is more ergonomic)
  • A preference for system prompts as a separate field rather than a 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.

    Related Posts