Getting started
MindsHub Inference gives you every major model behind one API key, reachable through the three APIs developers already use:
- OpenAI Chat Completions:
POST /v1/chat/completions - OpenAI Responses:
POST /v1/responses - Anthropic Messages:
POST /v1/messages
These are three request formats over the same engine, not three products. Streaming, tool calling, vision, and web search work through all of them, and any model works behind any of the three: Claude Fable from the OpenAI SDK, GPT 5.6 Sol from the Anthropic SDK.
You keep the SDK and the code you already have, and change a base URL.
1. Get a key
- Sign up at console.mindshub.ai.
- Create an API key.
- Copy it when it appears: the full key is shown once, at creation.
export MINDSHUB_API_KEY="mdb_..."
New organizations get a monthly allowance of included tokens on mindshub_air, so your first calls cost nothing. Everything else draws a prepaid wallet. See Billing.
2. The same request, three ways
Here is one prompt, sent through all three APIs. Note the model in each: a Claude model through the OpenAI SDK, a GPT model through the Anthropic SDK. The Chat Completions and Messages tabs work today as shown. The Responses tab shows where that API is heading; it fails today because the endpoint still returns Chat Completions shapes (status).
- Chat Completions
- Responses
- Messages
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.mindshub.ai/v1",
api_key=os.environ["MINDSHUB_API_KEY"],
)
response = client.chat.completions.create(
model="sonnet", # a Claude model, via the OpenAI SDK
messages=[{"role": "user", "content": "Name three uses for a paperclip."}],
)
print(response.choices[0].message.content)
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.mindshub.ai/v1",
api_key=os.environ["MINDSHUB_API_KEY"],
)
response = client.responses.create(
model="kimi", # Kimi K3, via the OpenAI SDK
input="Name three uses for a paperclip.",
)
print(response.output_text)
import anthropic
import os
client = anthropic.Anthropic(
base_url="https://api.mindshub.ai", # host only, no /v1
auth_token=os.environ["MINDSHUB_API_KEY"], # auth_token, not api_key
)
message = client.messages.create(
model="gpt", # GPT 5.6 Sol, via the Anthropic SDK
max_tokens=1024,
messages=[{"role": "user", "content": "Name three uses for a paperclip."}],
)
print(message.content[0].text)
Two details worth remembering:
- The OpenAI SDKs take the base URL with
/v1and authenticate withapi_key. - The Anthropic SDKs take the base URL without
/v1(the client appends the path itself) and authenticate withauth_token, notapi_key. Theapi_keyfield sends anx-api-keyheader, which MindsHub rejects.
Not sure which to use? Choosing an API has a one-screen decision table.
3. Switch models by editing one string
Every model is addressed by a short, stable alias. The alias resolves server-side to a concrete model at the provider, so upgrades don't break your code.
for model in ["fable", "gpt", "kimi", "deepseek", "gemini-flash"]:
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "Explain a hash map in one sentence."}],
)
print(f"{model:14} {response.choices[0].message.content}")
That loop runs five models from five vendors on one key and one bill. A sample of the catalog:
| Alias | Model |
|---|---|
fable | Claude Fable 5 |
opus | Claude Opus 5 |
sonnet | Claude Sonnet 5 |
gpt | GPT 5.6 Sol |
gpt-mini | GPT 5.4 Mini |
gemini | Gemini 3.1 Pro Preview |
kimi | Kimi K3 |
deepseek | DeepSeek V4 Pro |
qwen | Qwen3.7 Plus |
grok | Grok 4.5 |
The full list, with reasoning-effort support and live availability, is in Models and from GET /v1/models.
4. Stream the output
Set stream=True. Each API streams in its own native format, so your existing streaming code keeps working.
- Chat Completions
- Responses
- Messages
stream = client.chat.completions.create(
model="sonnet",
messages=[{"role": "user", "content": "Count to five."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
stream = client.responses.create(
model="sonnet",
input="Count to five.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
with client.messages.stream(
model="sonnet",
max_tokens=1024,
messages=[{"role": "user", "content": "Count to five."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Guard on chunk.choices being non-empty in the Chat Completions loop: some models end the stream with a usage-bearing chunk that carries no choices.
5. Call your tools
Tool calling works on every API and on the models that support it. Declare a function, and when the model asks for it, run it and hand the result back.
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "What's the weather in Lisbon?"}]
response = client.chat.completions.create(model="sonnet", messages=messages, tools=tools)
call = response.choices[0].message.tool_calls[0]
# Run the real function here; hard-coded for the example.
result = "19°C, light rain"
messages.append(response.choices[0].message)
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
final = client.chat.completions.create(model="sonnet", messages=messages, tools=tools)
print(final.choices[0].message.content)
Send the same tools array on the follow-up call, and echo tool_call_id back exactly as you received it. Full reference in Chat completions → Tool calling.
6. Send an image
Attach an image as a data: URL or a public URL:
response = client.chat.completions.create(
model="sonnet",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url", "image_url": {"url": "https://example.com/chart.png"}},
],
}],
)
7. Give the model the web
Add the built-in web_search and fetch tools and the platform handles retrieval; there's no search API to sign up for:
response = client.chat.completions.create(
model="sonnet",
messages=[{"role": "user", "content": "What shipped in Python 3.14?"}],
tools=[{"type": "web_search"}, {"type": "fetch"}],
)
Searches carry a small per-search charge on top of tokens; see Billing.
8. See what it cost
Every non-streaming response carries usage; streams end with a usage chunk when you ask via stream_options: {"include_usage": true}:
print(response.usage.prompt_tokens, response.usage.completion_tokens)
And your account-wide totals are one call away:
curl "https://auth.mindshub.ai/v1/usage/summary/?range=period&group_by=model" \
-H "Authorization: Bearer $MINDSHUB_API_KEY"
That returns per-model token counts and cost for the current billing period, covering every SDK and coding agent you've pointed at MindsHub. One place to check instead of four vendor dashboards.
What we adapt for you
Models disagree about parameters: some take no top_k, some take no reasoning_effort, and output ceilings differ. A parameter the target model can't take is dropped, a value above its range (max_tokens over the model's ceiling, a reasoning_effort above its ladder) is clamped down, and the request is served either way, with every change named 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; that error passes through as a 400 (Kimi K3 takes temperature only at 1). The full contract is in Core concepts.
Use it in your coding agent
The same key runs your terminal and editor agents. Claude Code points at MindsHub with two environment variables and can run on Kimi K3 or any other catalog model, billed to the same balance as your application traffic. Codex support is coming.
Where to next
Completions, Responses, or Messages, and what each one supports.
Claude Code and Codex on any MindsHub model.
The full catalog, aliases, and reasoning effort.
Aliases, funding, effort, and how routing works.
The complete parameter reference.
Included tokens, the wallet, and prices.