If you can call OpenAI, you can call Hero Run.
One base URL, one key, 375+ models across 10 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://hero-run.vercel.app/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 — 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 375+ 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 isn't text-only. 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://hero-run.vercel.app/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
Native HTTP API
Prefer plain endpoints? Same key, same billing.
GET https://hero-run.vercel.app/api/models # catalog + $HERO prices
POST https://hero-run.vercel.app/api/run # {"model":"auto","input":"...","kind":"text"} header: x-api-key
GET https://hero-run.vercel.app/api/keys/info # prepaid balance header: x-api-key
GET https://hero-run.vercel.app/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 — that's the whole point.