Choosing an API
Choose the kind of result first. Chat models generate content, embedding models produce vectors, and decision models return typed judgments. They use the same MindsHub key and usage reporting.
For chat models, MindsHub supports three request formats: Chat Completions, Responses, and Messages. Choose whichever your existing code speaks.
Jev uses the Decisions API, with native state and typed questions. Model catalog entries with kind: "decision" use /v1/decisions; the chat APIs described here apply to kind: "chat".
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 | https://api.mindshub.ai/v1 | api_key |
| Already use the Anthropic SDK or Claude Code | Messages | https://api.mindshub.ai | auth_token |
| Need categories, scores, or yes/no probabilities | Decisions (Jev) | https://api.mindshub.ai/v1/decisions (full endpoint) | Bearer key over HTTP |
| Need text vectors | Embeddings | https://api.mindshub.ai/v1 | api_key |
| Are starting fresh with a chat model | Chat Completions | https://api.mindshub.ai/v1 | api_key |
| Run OpenAI Codex | Responses | https://api.mindshub.ai/v1 | api_key |
Starting a chat integration? 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 chat model in the catalog is reachable from all three chat APIs below. What differs is a handful of protocol features. The generated, per-parameter and per-model version of this table is the capability matrix; each row below links to the guide that shows the feature on all three APIs.
| 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 | output_config.effort |
| 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 | previous_response_id | no |
| Guaranteed JSON / schema output | response_format | text.format | output_config.format |
Embedding models use Embeddings. Decision models such as Jev use Decisions; learn how their question types work in Decision models.
Two of those rows need explanation:
Conversation chaining is Responses-only. On Chat Completions and Messages, send the full conversation each turn and keep history client-side. Responses additionally stores turns (store defaults to true) and chains them by previous_response_id; see Conversation state. Sending the full history each turn works on all three.
Structured output works the same on all three. Each API spells it differently — response_format, the Responses text field, Messages' output_config — and each is honored, so a JSON schema comes back as JSON matching it. See Structured output.
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 (except on a stream whose 200 went out early; see Errors). A model can still restrict the values of a parameter it supports and return its own 400 (Kimi K3 takes temperature only at 1). A few models refuse two supported parameters sent together, and one of them is dropped: Claude Haiku 4.5 takes temperature or top_p, so top_p goes when both are sent. 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": "sonnet",
"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
}
}
The model field behaves the same way on all three: it names the model that served (claude-sonnet-5 for a sonnet request), and the value can be sent again as-is. mindshub_air and mindshub_blaze return their own alias. See Models.
All of it meters into the same usage summary.