Choosing an API
MindsHub speaks three request formats. All three reach the same models, the same key, and the same bill. Pick by the code you already have, not by capability.
Pick in ten seconds
| If you… | Use | Base URL | Auth |
|---|---|---|---|
Already call OpenAI's chat.completions | Chat Completions | https://api.mindshub.ai/v1 | api_key |
Already call OpenAI's responses | Responses (mid-upgrade) | https://api.mindshub.ai/v1 | api_key |
| Already use the Anthropic SDK or Claude Code | Messages | https://api.mindshub.ai | auth_token |
| Are starting fresh | Chat Completions | https://api.mindshub.ai/v1 | api_key |
| Run OpenAI Codex | Responses (mid-upgrade) | https://api.mindshub.ai/v1 | api_key |
Starting fresh? Use Chat Completions. It is the most widely supported shape in the ecosystem and the best documented here.
The two URL traps, worth repeating because they cause most first-run failures:
- OpenAI SDKs want the base URL with
/v1. Anthropic SDKs want it without; the client appends/v1/messagesitself. - Anthropic SDKs must authenticate with
auth_token, notapi_key.api_keysends anx-api-keyheader, which MindsHub rejects with a 401 before the request lands.
Capability at a glance
Every model in the catalog is reachable from every API. What differs is a handful of protocol features:
| Capability | Chat Completions | Responses | Messages |
|---|---|---|---|
| Every generation model | yes | yes | yes |
| Streaming | yes | yes | yes |
| Tool calling | yes | yes | yes |
| Images in | yes | yes | yes |
| Built-in web search | yes | yes | yes |
| Reasoning effort | reasoning_effort | reasoning.effort | not exposed |
| Automatic prompt caching | yes | yes | yes |
| Explicit cache breakpoints | no | no | cache_control |
| Token counting endpoint | no | no | /v1/messages/count_tokens |
| Conversation chaining | no | no | no |
| Guaranteed JSON / schema output | no | no | no |
embed-small is the exception to the first row: it's embeddings-only and lives on its own endpoint. The Responses column describes the upgrade that's rolling out.
Two of those rows need explanation:
No conversation chaining, on any API. Send the full conversation each turn and keep history client-side. On Responses specifically, this means previous_response_id and store are accepted but not honored: chaining calls by ID won't carry context. This is the OpenAI SDK's default behavior when you aren't chaining, so most code is unaffected.
No guaranteed structured output. response_format and the Responses text field are accepted and ignored. Ask for JSON in your prompt and validate what comes back. Tool calling is the reliable path to structured data: arguments arrive as JSON matching the schema you declared.
Parameter handling
Whichever API you pick, parameters the target model supports are honored at whatever value you send; ones it doesn't support are dropped, and out-of-range values are clamped, with every change reported in the X-MindsHub-Dropped-Params and X-MindsHub-Clamped-Params response headers. A model can still restrict the values of a parameter it supports and return its own 400 (Kimi K3 takes temperature only at 1). Unknown top-level fields are accepted and ignored on all three APIs; unknown nested content can still reach the provider and fail there. The full contract is in Core concepts.
Response shapes differ
The three APIs return their own native shapes, which is the point: your existing parsing code keeps working.
- Chat Completions
- Responses
- Messages
{
"id": "chatcmpl-636a4f9b",
"object": "chat.completion",
"model": "claude-sonnet-5",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Canberra."},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 12, "completion_tokens": 4, "total_tokens": 16}
}
{
"id": "resp_9f2c1a",
"object": "response",
"status": "completed",
"model": "sonnet",
"output": [{
"type": "message",
"role": "assistant",
"content": [{"type": "output_text", "text": "Canberra.", "annotations": []}]
}],
"output_text": "Canberra.",
"usage": {
"input_tokens": 12,
"input_tokens_details": {"cached_tokens": 0},
"output_tokens": 4,
"total_tokens": 16
}
}
{
"id": "msg_5084f823",
"type": "message",
"role": "assistant",
"model": "sonnet",
"content": [{"type": "text", "text": "Canberra."}],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 12,
"output_tokens": 4,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}
One inconsistency to know about the model field: Messages echoes back the alias you sent (sonnet), while Chat Completions and, today, Responses report the resolved provider model ID (claude-sonnet-5). If you aggregate usage per model on your side, key on the alias you requested rather than reading it back off the response.
Mixing APIs in one codebase
Nothing stops you. A common split:
- Application traffic on Chat Completions, because the ecosystem support is broadest.
- Coding agents on whichever format they speak: Claude Code on Messages, Codex on Responses. See Coding agents.
All of it meters into the same usage summary.