If you can call OpenAI, you can call Hero Run.
One base URL, one key, 500+ models across 16 gateways. Use model auto and the router picks a right-sized model for every request at one flat price, paid in $HERO. Every call funds open-source AI.
Quickstart
The standard OpenAI client in any language. Just change the base URL.
from openai import OpenAI
client = OpenAI(base_url="https://herorunai.com/v1", api_key="hr_live_...")
r = client.chat.completions.create(
model="auto", # the router picks a right-sized model, one flat price
messages=[{"role": "user", "content": "Explain CRDTs in one line"}],
)
print(r.choices[0].message.content)Streaming works the standard way: pass stream: true and read SSE chunks. Works with the Vercel AI SDK, LangChain, CrewAI, LlamaIndex, and anything else that accepts an OpenAI base URL.
Official SDK: hero-run-ai
Zero-dependency JS/TS client with chat, streaming, image/video/audio generation, a Vercel AI SDK provider, and a drop-in React chat widget.
npm install hero-run-aiimport { createHeroRun } from "hero-run-ai";
const hero = createHeroRun({ apiKey: process.env.HERO_RUN_KEY });
const { text, hero: meta } = await hero.chat([{ role: "user", content: "hi" }]);
const img = await hero.generate({ kind: "image", prompt: "a molten flame mascot" });
// Vercel AI SDK: import { createHeroRunProvider } from "hero-run-ai/ai-sdk"
// React widget: import { HeroRunChat } from "hero-run-ai/react"Routing modes
Modes are just model ids, with no custom parameters.
| auto | Reads your prompt and routes to a right-sized model: best quality per dollar. Same as optimized. | default |
| cheapest | Always the cheapest trusted model, regardless of prompt complexity. | lowest cost |
| fastest | The fastest model on its fastest gateway, by measured speed. | lowest latency |
| openai/gpt-oss-120b | Or any of the 500+ catalog ids (see GET /v1/models). | specific |
Each response carries an x_hero field with the router's decision: tier, resolved model, gateway, and the $HERO charged.
Function calling
Pass tools in the standard OpenAI format; the model's tool_calls come back with finish_reason: "tool_calls", and you return results as role: "tool" messages. Tool turns respond unstreamed.
tools = [{"type": "function", "function": {
"name": "get_price",
"description": "Get a token price in USD",
"parameters": {"type": "object", "properties": {"symbol": {"type": "string"}}, "required": ["symbol"]},
}}]
r = client.chat.completions.create(model="auto", messages=messages, tools=tools)
call = r.choices[0].message.tool_calls[0] # finish_reason == "tool_calls"
messages += [r.choices[0].message, # then send the result back:
{"role": "tool", "tool_call_id": call.id, "content": '{"usd": 0.00000022}'}]
r2 = client.chat.completions.create(model="auto", messages=messages, tools=tools)Images, audio & video
The catalog covers more than text. Generate images through the native API with kind: "image". Model auto routes to the image pool at one flat price, or pick a specific model (Nano Banana / Gemini image, GPT Image, FLUX). The response carries a data:image/png;base64 URI.
import base64, requests
r = requests.post("https://herorunai.com/api/run",
headers={"x-api-key": "hr_live_..."},
json={"model": "auto", # flat-price image routing, or any image model id
"input": "a molten-orange anime flame mascot, token logo",
"kind": "image"})
data_uri = r.json()["image"] # "data:image/png;base64,..."
open("out.png", "wb").write(base64.b64decode(data_uri.split(",")[1]))| Images | 16 models live: Gemini image (Nano Banana), GPT Image, and the FLUX line. Also the MCP server's generate_image tool. | live |
| Audio | Speech (GPT Audio) and music (Lyria), same call shape with kind: "audio". The response carries a playable data:audio/wav URI plus the transcript as text. | live |
| Video | Text-to-video via WaveSpeed, from wavespeed-ai/wan-2.2/t2v-480p-ultra-fast up to Kling 2.5 and Seedance 2.0. Same call shape with kind: "video"; the response's video is the finished MP4's URL. Clips take 1–3 minutes. | live |
Browse what's live right now: GET /api/models and filter by kind.
Agents & MCP
Grok Build (and any custom-model agent)
Grok Build takes a custom model in ~/.grok/config.toml. Point it at Hero Run's /v1 (Chat Completions, with tools + streaming) and it runs on our catalog, billed to your key in $HERO.
[model.hero-run]
model = "auto" # or any catalog id, e.g. openai/gpt-oss-120b
base_url = "https://herorunai.com/v1"
name = "Hero Run (paid in $HERO)"
env_key = "HERO_RUN_KEY"
[models]
default = "hero-run"export HERO_RUN_KEY=hr_live_... # mint one at https://herorunai.com/keys
grok -m hero-run -p "Explain this repo" # or just: grokdsh (DeepSeek Harness) example, in ~/.dsh/settings.yaml: point a provider at the base URL and pick a default.
llm-pi-ai:
providers:
hero-run:
apiKeyEnv: HERO_RUN_KEY
api: openai-completions
baseURL: https://herorunai.com/v1
models:
- id: auto
- id: cheapest
agent-default-model:
provider: hero-run
model: autoFor on-chain memory (mint / checkpoint / recall), also add the Hero Run MCP server. The one-paste setup on the API page covers Grok Build, opencode, Claude Code, Codex, and Cursor. Note: use the base_url / Chat Completions path above; Hero Run does not serve the OpenAI Responses API.
Native HTTP API
Prefer plain endpoints? Same key, same billing.
GET https://herorunai.com/api/models # catalog + $HERO prices
POST https://herorunai.com/api/run # {"model":"auto","input":"...","kind":"text"} header: x-api-key
GET https://herorunai.com/api/keys/info # prepaid balance header: x-api-key
GET https://herorunai.com/api/gateways # live per-gateway speed (tok/s, TTFT)No signup, no per-provider accounts. Mint a key with a Base wallet, or pay per call on-chain. Usage funds open-source AI, which is the whole point.