Get started in 5 minutes.
InferHub speaks both the OpenAI /v1/chat/completions API and the Anthropic /v1/messages API. Point your existing SDK at us, paste your API key, and you're live — or configure Claude Code, Codex, OpenCode, and more in one command.
Fastest path for coding agents
One command. Claude, Codex, OpenCode, Hermes, Cline…
Create an API key, then run the interactive helper. It validates your key against GET /v1/models, lets you pick agents and models (searchable), and writes the right config files for each tool on Windows, macOS, and Linux.
# after you have a key from Dashboard → API Keys
npx @inferhub/helper
# interactive wizard:
# 1. paste API key → validated via /v1/models
# 2. select agents → Claude Code, Codex, OpenCode, Hermes, OpenClaw, Cline
# 3. search models → e.g. free/grok/grok-4.5
# 4. confirm → configs written (with .inferhub-backup)Package: @inferhub/helper. Also available as ih-helper after npm i -g @inferhub/helper.
Get an API key
Create an account and head to Dashboard → API Keys. Click Create key, copy it, and store it somewhere safe. Keys start with sk-airo- and are shown only once.
Top up with USDC
Open Dashboard → Deposit. Each account gets a unique Solana address. Send USDC to it from any wallet — no memo required. After finalized commitment (~13 seconds) your balance is credited.
Settlement is on Solana mainnet — send real USDC. Double-check the address and network before sending; funds sent to the wrong network or address may be unrecoverable.
Make your first request
Prefer coding agents? Skip the SDK samples and run npx @inferhub/helper above. For SDKs and curl:
from openai import OpenAI
client = OpenAI(
base_url="https://api.inferhub.dev/v1",
api_key="sk-airo-...",
)
resp = client.chat.completions.create(
model="ocg/glm-5.1",
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)from anthropic import Anthropic
# IMPORTANT: Anthropic clients append /v1 themselves.
# Use the API root, NOT ".../v1" (that becomes /v1/v1/messages).
client = Anthropic(
base_url="https://api.inferhub.dev",
api_key="sk-airo-...",
)
# Or skip manual env setup:
# npx @inferhub/helper
# Claude Code:
# ANTHROPIC_BASE_URL=https://api.inferhub.dev
# ANTHROPIC_AUTH_TOKEN=sk-airo-...
# ANTHROPIC_MODEL=free/grok/grok-4.5
resp = client.messages.create(
model="zai/glm-4.6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.content[0].text)curl https://api.inferhub.dev/v1/chat/completions \
-H "Authorization: Bearer sk-airo-..." \
-H "Content-Type: application/json" \
-d '{
"model": "ocg/glm-5.1",
"messages": [{"role": "user", "content": "Hello!"}]
}'curl https://api.inferhub.dev/v1/images/generations -H "Authorization: Bearer sk-airo-..." -H "Content-Type: application/json" -d '{
"model": "gpt-image-2",
"prompt": "A single red apple on a plain white studio background.",
"size": "1024x1024"
}'
# The image comes back inline: data[0].b64_json. There is no hosted URL.
# quality (low/medium/high) changes what the image costs, a lot.
# Image models also answer on /v1/chat/completions, where the picture arrives
# as an image_url content part.
#
# Anything the OpenAI shape has no field for goes in custom_params, which is
# passed to the upstream verbatim — this is how you reach the per-model knobs
# on rails like leo/* that expose a different parameter set per model:
# "custom_params": { "contrast": 3.5, "style_ids": ["..."] }# 1. Submit. This returns a JOB, not a video: generation takes 90s to several
# minutes, which is longer than any HTTP request should stay open.
curl https://api.inferhub.dev/v1/videos -H "Authorization: Bearer sk-airo-..." -H "Content-Type: application/json" -d '{
"model": "leo/veo-3.1-fast-generate-001",
"prompt": "A red cube slowly rotating on a white table.",
"seconds": "8",
"custom_params": { "motion_has_audio": false }
}'
# -> {"id":"video_...","object":"video","status":"queued","progress":0}
# 2. Poll until status is "completed" (or "failed").
curl https://api.inferhub.dev/v1/videos/video_... -H "Authorization: Bearer sk-airo-..."
# 3. Download the mp4.
curl https://api.inferhub.dev/v1/videos/video_.../content -H "Authorization: Bearer sk-airo-..." -o out.mp4
# A generation that fails is not billed. The charge lands when the job
# completes, and appears on the job object as usage.cost.curl https://api.inferhub.dev/v1/messages \
-H "x-api-key: sk-airo-..." \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "zai/glm-4.6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'Read the API reference
/v1/modelsList every model addressable as <prefix>/<model-id>.
/v1/chat/completionsOpenAI-compatible chat completions. Streaming and tool calling supported.
/v1/messagesAnthropic-compatible messages API. Same key, native SSE event stream.
/v1/images/generationsOpenAI-compatible image generation. Returns the picture inline as b64_json.
/v1/images/editsEdit an image you supply. Same contract, plus the input picture.
/v1/videosVideo generation, OpenAI Videos API shape. Returns a job to poll, not a video.
/v1/videos/{id}/contentDownload a finished video once its job reports completed.
/v1/embeddingsOpenAI-compatible embeddings.
Routing tips
- Address models by prefix: Every model lives under an upstream prefix. For example,
model="ocg/glm-5.1"targets OpenCode Go’s GLM-5.1;zai/glm-4.6targets Z.AI’s. See /pricing for the full list. - Auto routing: The router picks the best publisher serving that prefix per request, falling over to another on failure (up to 5 hops).
- Bidding (optional): Cap what you’ll pay per million tokens with two headers:
x-max-input-price: 0.50andx-max-output-price: 2.00. We only route to providers whose asks meet your cap. If none match you get402 no_provider_under_bidwithmin_input_per_mtok/min_output_per_mtokin the body so you can re-bid. Omit the headers to skip the filter. - Excluding upstreams (optional): Skip one or more upstreams for a single request with
x-ignore-upstream: cmc,qd,cx— a comma-separated list of prefixes (case-insensitive, e.g.cmc,qd,cx). The router drops any serving upstream whose prefix matches, so a model alias routes only to the providers you didn’t exclude. If every upstream for the requested model is excluded you get404 model_not_found. - Streaming: Pass
stream=true. We forward SSE byte-for-byte for OpenAI; for Anthropic we emit the fullmessage_start → content_block_delta* → message_stopevent sequence. - Quotas: If every publisher serving a prefix has hit their plan’s monthly cap, we return
503 no_capacityuntil any of their periods rolls over.