One AI API.
Every provider.
A production-ready REST gateway: send one POST /api/v1/chat request and route it to
OpenRouter, Poolside AI, or any OpenAI-compatible provider —
if a provider errors, the gateway automatically fails over to the next one until a response arrives.
Typed errors, rate limiting and zero key exposure included.
{ "message": "What are channels in Go?" }
// openrouter was rate-limited -> auto-failover -> poolside answered
{ "success": true, "provider": "poolside", "reply": "Channels are typed conduits…",
"failover": { "attempts": [{ "provider": "openrouter", "code": "UPSTREAM_RATE_LIMIT" }] } }
Pluggable provider architecture
Every provider is a small adapter object. The three built-ins below are ready to use, and the custom provider system accepts any OpenAI-compatible endpoint with zero code.
Loading live provider status…
Status is fetched live from GET /api/v1/providers ·
see all endpoints
Everything a production AI API needs
Built on Hono for Cloudflare Pages Functions, runnable anywhere Node.js 18+ runs.
Multi-provider routing
Switch provider or model per request with a single JSON field. Same response shape no matter who answers, so client code never changes.
Automatic provider failover
If one provider errors — rate limit, timeout, outage — the gateway instantly retries the next configured provider and keeps cycling until a response arrives. Zero code in your app.
Keys never leave the server
Provider API keys live in server environment variables. Browsers and clients only ever talk to your gateway — never to upstream providers.
Zero-code custom providers
Point CUSTOM_BASE_URL at any OpenAI-compatible server — OpenAI, DeepSeek, Ollama, LM Studio, vLLM — and it becomes a first-class provider.
Typed errors & rate limits
Upstream failures map into one consistent envelope with 16 typed codes, per-IP sliding-window limits, and Retry-After hints on 429s.
One .env controls everything
App name, version, providers, failover rounds — all env-driven. Change .env once and every page, endpoint and response reflects it after redeploy.
Three steps from request to reply
You send one JSON call
Your app posts a message (or a full multi-turn messages[] array) to your gateway, optionally naming a provider and model.
Validate, route, protect
The gateway validates input, applies rate limits and CORS, attaches the right server-side API key, and forwards to the chosen upstream provider.
One predictable envelope
You always get {success, provider, reply, model, usage} — or a typed error with an actionable message and retry hints.
A compact, honest API surface
Five endpoints. No SDK required. Full reference on the Endpoints page · browse every model on the Models page.
Live uptime monitoring: API Status →
Call it from anywhere
The base URL below is auto-detected from your current address — the same snippet works on localhost and in production.
curl -X POST https://YOUR-DOMAIN/api/v1/chat \
-H "Content-Type: application/json" \
-d '{
"message": "What is the meaning of life?",
"temperature": 0.7
}'
const base = window.location.origin; // auto-detected API base URL
const res = await fetch(base + "/api/v1/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "Write a Go function that sums a slice of ints",
max_tokens: 500,
}),
});
const data = await res.json();
if (data.success) console.log(data.reply, "(served by", data.provider + ")");
else console.error(data.error.code, data.error.message);
import requests
res = requests.post(
"https://YOUR-DOMAIN/api/v1/chat", # auto-detected — this very domain
json={
"message": "What is the meaning of life?",
"temperature": 0.7,
},
timeout=60,
)
data = res.json()
print(data["reply"] if data["success"] else data["error"]["message"])
More patterns (multi-turn, retries, error handling): Usage & Integration Guide →
What builders say
Feedback from developers routing their apps through the gateway.
“I replaced three provider SDKs with one fetch call. When OpenRouter rate-limits me, the reply still arrives from another provider — my users never notice.”
Backend developer, Dhaka
“The deep failover is the killer feature — it doesn’t just switch providers, it walks every model until one answers. Zero code on my side.”
Indie hacker, Chattogram
“Deployed on Cloudflare Pages in one afternoon. Typed errors, rate limits, Bengali docs and a Telegram bot — everything I’d have built myself.”
CTO, startup studio
Frequently asked questions
FAILOVER_MAX_ATTEMPTS) keeps latency bounded, and the response reports the real provider + model that answered.CUSTOM_BASE_URL for any OpenAI-compatible endpoint (zero code), or write a small adapter file in src/providers/ for exotic APIs. Both are first-class citizens in the failover chain./api/telegram/<SECRET>) ships built in. Register it once with @BotFather and your bot answers through the same failover chain. Full guide on the Telegram page.Ready to route your first request?
Try the interactive playground right now — no setup, no SDK, works on mobile too.