Core concepts
A handful of ideas explain most of how MindsHub behaves.
Aliases
You address models by a short, stable name (sonnet, gpt, kimi), not by a provider version string. The alias resolves server-side to a concrete model at the provider.
{"model": "sonnet"}
Aliases exist so that a provider version bump doesn't become a deploy on your side. When Claude Sonnet 5 is superseded, sonnet follows it and your code doesn't change.
Two consequences:
- Raw provider IDs don't work on the OpenAI-compatible endpoints.
claude-sonnet-5returns404 model_not_found. The exception is Messages, which maps real Claude names onto aliases so Claude Code's picker works unmodified. - Log the alias you sent, not the
modelyou get back. Chat Completions reports the resolved provider ID, which changes when the alias is repointed.
The live list is GET /v1/models; the catalog is in Models.
Passthrough
MindsHub does not host models. Each request is translated into the target provider's format, sent to that provider, and translated back into the format you asked in. There is no MindsHub model sitting in the middle rewriting your prompts.
This is why capability tracks the underlying model: if a model can't see images, MindsHub can't change that. And it's why the response's resolved model ID tells you which provider actually served the request, which matters if you have data-handling requirements about where prompts travel.
Three APIs, one engine
Chat Completions, Responses, and Messages are three wire formats over the same inference pipeline. Any model is reachable from any of them. Pick the one your existing code speaks.
The formats differ in shape, not in power. Where a genuine capability gap exists (explicit cache breakpoints, the token-counting endpoint), it's flagged in the capability matrix.
Parameters are adapted, not rejected
Models disagree about which generation parameters they accept. MindsHub is a router, so instead of failing a request over a parameter the target model doesn't take:
- A parameter the model supports is passed through at whatever value you sent.
- A parameter it doesn't support is dropped, and named in
X-MindsHub-Dropped-Params. - A value above the model's range (
max_tokensover its ceiling, areasoning_effortabove its ladder) is clamped down, and named inX-MindsHub-Clamped-Paramsasname=requested>applied. - An unknown top-level field is ignored silently.
Neither header appears when nothing changed. SDKs and coding agents treat a 400 as a hard failure, which is why unsupported parameters are dropped rather than bounced.
The boundaries:
- A model can restrict the values of a parameter it supports, and that error passes through as the provider's 400: Kimi K3 takes
temperatureonly at1andtop_ponly at0.95. - Unknown nested content, such as an unrecognized block inside
messages, can still reach the provider and fail there. response_formatis accepted and ignored, so there is no guaranteed JSON.
Reasoning effort
Many current models reason before answering. Two things follow.
Where it's adjustable, it's a parameter. Models whose catalog entry lists reasoning_efforts accept reasoning_effort (reasoning.effort on Responses). Levels vary by model; GET /v1/models is authoritative. Omitting it applies the model's default_reasoning_effort, which for most reasoning models is not "off".
Where it isn't adjustable, it still happens. reasoning_efforts: null means you can't tune it, not that the model won't reason. mindshub_air and kimi both reason internally on every request.
Either way, reasoning bills as output tokens, and the reasoning content itself isn't returned. Two practical effects: a one-sentence reply can meter 80 or more output tokens, and a tight max_tokens can be used up by reasoning before the visible answer. Give reasoning models a few hundred tokens of headroom.
Funding: included tokens and the wallet
Two separate pots pay for requests.
Included tokens: a monthly allowance (5,000,000 by default) usable on mindshub_air. Resets on your organization's anniversary date, doesn't roll over.
The wallet: a prepaid, organization-level balance that funds everything else: every other model, embeddings, web search, and cache writes.
Funding is checked before the model runs, so an unfunded request is refused up front and costs nothing. Running out is not the same as going too fast:
| Meaning | Fix | |
|---|---|---|
429 rate_limited | Too fast | Back off, honor Retry-After |
429 included_allowance_exhausted | Included tokens gone, no payment method on file | Wait for reset or add credit |
402 wallet_empty | Wallet empty | Top up |
Only the first is fixed by retrying. Details in Billing and Rate limits.
Conversations live client-side
There is no conversation chaining: every request carries its full history, on all three APIs, including Responses, where previous_response_id and store are accepted but not honored.
Keep the message list client-side, append to it each turn, and send it. Prompt caching means resending a long history is cheaper than it looks: repeated prefixes bill at roughly a tenth of the input rate. Caching is automatic on most of the catalog; Claude-family targets cache when the request marks cache_control breakpoints on Messages, which Claude Code does for you.
Terms in one line each
| Term | Meaning |
|---|---|
| Alias | Short stable model name you put in model |
| Passthrough | Requests are translated and proxied to the upstream provider |
| Included tokens | Monthly allowance on mindshub_air |
| Wallet | Prepaid balance funding everything else |
| Reasoning effort | How hard a model thinks before answering; billed as output |
| Dropped / clamped | Parameters adapted to the target model, reported in headers |
| Cache write | Prompt tokens stored for reuse; billable, never drawn from included tokens |