Skip to main content

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-5 returns 404 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 model you 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_tokens over its ceiling, a reasoning_effort above its ladder) is clamped down, and named in X-MindsHub-Clamped-Params as name=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 temperature only at 1 and top_p only at 0.95.
  • Unknown nested content, such as an unrecognized block inside messages, can still reach the provider and fail there.
  • response_format is 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:

MeaningFix
429 rate_limitedToo fastBack off, honor Retry-After
429 included_allowance_exhaustedIncluded tokens gone, no payment method on fileWait for reset or add credit
402 wallet_emptyWallet emptyTop 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

TermMeaning
AliasShort stable model name you put in model
PassthroughRequests are translated and proxied to the upstream provider
Included tokensMonthly allowance on mindshub_air
WalletPrepaid balance funding everything else
Reasoning effortHow hard a model thinks before answering; billed as output
Dropped / clampedParameters adapted to the target model, reported in headers
Cache writePrompt tokens stored for reuse; billable, never drawn from included tokens