Anthropic Messages API ("Anthropic Skin")

For Claude Code / Anthropic SDK users: see the step-by-step Claude Code Setup guide.

Surplus speaks Anthropic's Messages API natively, so tools built for Anthropic — Claude Code and the Anthropic Agent SDK — can route through the marketplace with nothing but environment variables. No local proxy, no client-side translation.

This is the same idea as OpenRouter's "Anthropic skin": point the Anthropic client's base URL at Surplus, authenticate with a Surplus buyer key, and every request is routed to the cheapest healthy seller and settled on-chain like any other marketplace call.

It is model-agnostic. Routing is by the model string, not by family — so you can run Claude Code on Claude or GPT, GLM, Llama, Gemini, DeepSeek, or any other catalog model, all through the Anthropic wire.

Base URL

text
https://api.surplusintelligence.ai/anthropic

This is what you set as ANTHROPIC_BASE_URL. The Anthropic client appends /v1/messages (and the other paths below) to it. The skin lives under a dedicated /anthropic prefix so it never collides with the OpenAI-compatible surface at /v1/....

Authentication

Use a Surplus buyer API key (inf_…), sent either way the Anthropic ecosystem sends it:

HeaderSet viaNotes
Authorization: Bearer inf_xxxANTHROPIC_AUTH_TOKENWhat Claude Code uses
x-api-key: inf_xxxANTHROPIC_API_KEYThe Anthropic SDK default

Always set ANTHROPIC_API_KEY="" when using ANTHROPIC_AUTH_TOKEN, or the cached Anthropic credential can take precedence. An unauthenticated or non-buyer request returns an Anthropic-shaped 401 authentication_error (the skin does not issue x402/MPP 402 challenges — Claude Code can't satisfy them; use a buyer key with credits or an on-chain allowance).

Endpoints (under /anthropic)

MethodPathDescription
POST/anthropic/v1/messagesSend a message; non-streaming or streaming (SSE)
POST/anthropic/min{N}/v1/messagesSame, but only route to sellers ≥ N% cheaper than reference
POST/anthropic/v1/messages/count_tokensEstimate input tokens for a request
GET/anthropic/v1/modelsList models (Anthropic shape)
GET/anthropic/v1/models/{id}Retrieve one model

Send a Message

POST/anthropic/v1/messages

Parameters

  • Name
    model
    required
    Description
    Any catalog model (canonical, -latest alias, dated Anthropic ID, or ~anthropic/…)
  • Name
    max_tokens
    required
    Description
    Maximum output tokens (required by the Anthropic API)
  • Name
    messages
    required
    Description
    Array of messages; content is a string or content blocks (text, image, tool_use, tool_result, thinking)
  • Name
    system
    Description
    System prompt — a string, or an array of text blocks (with cache_control)
  • Name
    temperature, top_p, top_k
    Description
    Sampling controls
  • Name
    stop_sequences
    Description
    Custom stop sequences
  • Name
    stream
    Description
    true for SSE streaming
  • Name
    tools
    Description
    Tool definitions (name, description, input_schema)
  • Name
    tool_choice
    Description
    auto / any / {type:"tool",name} / none
  • Name
    thinking
    Description
    {type:"enabled", budget_tokens} (or adaptive) — extended thinking
  • Name
    metadata
    Description
    {user_id} — passed through as the OpenAI user field
  • Name
    provider
    Description
    Provider pin / allow-list — a string, string[], or the OpenRouter {order|only:[...]} object
  • Name
    provider_base_url
    Description
    Pin to a specific provider host (matched against the marketplace allowlist)
  • Name
    max_price_per_1m
    Description
    Price cap in USD per 1M input tokens — offers above it are excluded

Request and version/beta headers (anthropic-version, anthropic-beta) are accepted; version/beta are tolerated and ignored (never required).

The non-streaming response is a standard Anthropic Message. content blocks may be text, tool_use, or thinking. stop_reason is tool_use if and only if a tool_use block is present. usage.input_tokens is net of cache (cache_read_input_tokens / cache_creation_input_tokens are reported separately when the provider supplies them).

Send a message
bash
curl https://api.surplusintelligence.ai/anthropic/v1/messages \
  -H "x-api-key: inf_xxx" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4.8",
    "max_tokens": 1024,
    "system": "You are concise.",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
json
{
  "id": "msg_…",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4.8",
  "content": [{"type": "text", "text": "Hello!"}],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {"input_tokens": 12, "output_tokens": 3}
}

Streaming

With "stream": true, the response is the standard Anthropic SSE event sequence:

text
event: message_start        → the Message skeleton
event: content_block_start  → per content block (text / thinking / tool_use)
event: content_block_delta  → text_delta / thinking_delta / signature_delta / input_json_delta
event: content_block_stop
event: message_delta        → stop_reason + cumulative usage
event: message_stop

Count Tokens

POST/anthropic/v1/messages/count_tokens

Returns an estimate (includes the system prompt and tool schemas). This is a heuristic estimate (no upstream round-trip); it is sufficient for context-budget sizing.

Count tokens
bash
curl https://api.surplusintelligence.ai/anthropic/v1/messages/count_tokens \
  -H "x-api-key: inf_xxx" -H "Content-Type: application/json" \
  -d '{"model":"claude-opus-4.8","messages":[{"role":"user","content":"Hello"}]}'
json
{ "input_tokens": 14 }

List Models

GET/anthropic/v1/models

Anthropic-shaped model list, served from the Surplus catalog (lists all marketplace models, not just Claude).

List models
json
{
  "data": [{"id": "claude-opus-4.8", "type": "model", "display_name": "Claude Opus 4.8", "created_at": "2025-01-01T00:00:00.000Z"}],
  "has_more": false,
  "first_id": "…",
  "last_id": "…"
}

Errors

Errors on /anthropic/* use the Anthropic envelope:

json
{ "type": "error", "error": { "type": "invalid_request_error", "message": "…" }, "request_id": "…" }
HTTPerror.typeWhen
400invalid_request_errorBad request / malformed JSON / out-of-credit
401authentication_errorMissing or invalid buyer key
404not_found_errorUnknown model id, or no sellers under your price threshold
429rate_limit_errorRate limited
413request_too_largeBody exceeds the size limit
5xxapi_error / overloaded_errorUpstream/provider error, or no healthy sellers

There is no Anthropic 402 — an out-of-credit buyer gets a 400 invalid_request_error (mirroring Anthropic's "credit balance too low" behavior).

Model names & aliases

Send any catalog model id. The skin additionally resolves:

  • -latest tags: claude-opus-latest, claude-sonnet-latest, claude-haiku-latest, plus cross-family gpt-latest, glm-latest, deepseek-latest, gemini-latest, and more.
  • Dated Anthropic IDs (e.g. claude-sonnet-4-5-20250929) → canonical.
  • The OpenRouter ~anthropic/… floating-tag prefix.

A model must exist in the catalog and have a healthy offer to route; otherwise you get an Anthropic-shaped 404/overloaded_error. Call GET /anthropic/v1/models for the catalog and GET /api/markets for models with live seller liquidity.

Feature fidelity on non-Claude models

The wire is fully translated, but some Anthropic features are model-dependent:

  • Works on every model: text, system prompt, multi-turn, streaming, tool use (tool_use/tool_result), images, stop reasons, usage/billing.
  • Best-effort: extended thinking — non-Claude models don't emit Anthropic thinking blocks; the field is accepted and the request still works, but no reasoning blocks are returned. Thinking-signature continuity across multi-turn tool loops is preserved on providers that echo signatures and degrades gracefully elsewhere.

Routing controls

Everything the marketplace offers applies here too: provider pinning / allow-lists, provider_base_url, max_price_per_1m price caps, the /anthropic/min{N}/v1/messages minimum-discount mirror, and the buyer's trusted-only / allow-untrusted preference. See Minimum-Discount Routing and BYOK / Priority Provider.