Compatibility
Chat Completions, Responses and Messages side by side: lanes, accepted, translated and rejected parameters.
Three inference endpoints, side by side: what each accepts, what it translates, and what it rejects before anything is reserved or charged.
Lanes
A request takes the native lane when the model’s route is served by an upstream that speaks the same wire format and the route has the native lane enabled: the gateway relays your bytes as sent and rewrites only model. Otherwise it takes the translated lane: the body is parsed into one canonical request, and anything that cannot be honoured is rejected by name. /v1/responses is always translated. Each model’s page in Model Square shows its Anthropic lane.
Matrix
| Feature | POST /v1/chat/completions | POST /v1/responses | POST /v1/messages |
|---|---|---|---|
| Compatible with | OpenAI Chat Completions; official openai SDKs | OpenAI Responses; Codex CLI, responses.create | Anthropic Messages; official anthropic SDKs, Claude Code |
| Base URL | https://api.topbilling.in/v1 | https://api.topbilling.in/v1 | https://api.topbilling.in (the SDK adds /v1) |
| Auth | Authorization: Bearer tb_live_… or x-api-key: tb_live_…; scope chat:write | ||
| Lanes | Native or translated | Translated only | Native or translated |
| Streaming | stream; stream_options.include_usage | stream: response.created … response.completed | stream: Anthropic events, ping keep-alive |
| Function tools | tools (type function), tool_choice, parallel_tool_calls; other tool types → 400 | Function tools; hosted tools are dropped and counted in tb-dropped-hints | tools, tool_choice; server tools (e.g. web search) → 400 capability_rejected: server_tools on both lanes |
| Images | image_url parts (https or base64 data URL) | input_image; input_file and file_id → 400 | image blocks (base64 or URL) |
| Structured output | response_format text or json_schema; json_object → 400 | text.format text or json_schema; others → 400 | output_config.format json_schema only |
| Reasoning | reasoning_effort: native lane only; translated → 400 unsupported_parameter | reasoning.effort: an advisory hint, never rejected | thinking on reasoning models; output_config.effort is an advisory hint |
| Prompt caching | Cached input reported as prompt_tokens_details.cached_tokens | Cached input reported as usage.input_tokens_details.cached_tokens | cache_control relayed on the native lane; on the translated lane dropped and counted in tb-dropped-hints |
n > 1 | 400 unsupported_parameter on both lanes | — | — |
| Stored state | — | previous_response_id, conversation, background, prompt → 400; store accepted and reported as false | — |
| Unknown fields | Translated: 400 unsupported_parameter naming the field (e.g. logprobs, logit_bias, seed, legacy functions). Native: relayed | Dropped and counted in tb-dropped-hints, so a Codex upgrade does not fail | Translated: 400 capability_rejected: <field>. Native: relayed |
anthropic-beta | — | — | Native: relayed. Translated: ignored and listed in tb-ignored-betas |
| Token counting | — | — | POST /v1/messages/count_tokens on models with token_counting |
| Empty wallet / spend cap | 402 | 429 insufficient_quota (what Codex stops on) | 402 billing_error |
A rejected request is refused before credits are reserved, so it costs nothing. A model that lacks a capability you asked for (tools, vision, structured output…) is refused with a
400 (capability_not_supported on the OpenAI-compatible endpoints, invalid_request_error on Messages).