RouteHaven

Documentation

RouteHaven exposes an OpenAI-compatible API. Any OpenAI SDK works — change the base URL and API key.

Quickstart

  • Create an account and organization, then create an API key under Dashboard → API keys.
  • Add a provider key under Dashboard → BYOK (OpenAI, Anthropic or Google), or try the free sandbox/echo model first.
  • Send requests to https://routehaven.ai/api/v1.
curl https://routehaven.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $ROUTEHAVEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "anthropic/claude-sonnet-5.5",
  "messages": [{"role": "user", "content": "What is the meaning of life?"}]
}'

Authentication

Send your key as a bearer token: Authorization: Bearer sk-rh-…. Keys are shown once at creation and stored only as SHA-256 hashes. Optional headers X-Title or HTTP-Referer label requests in your activity log.

Chat completions

POST /api/v1/chat/completions accepts the OpenAI Chat Completions body. Supported fields:

FieldNotes
modelRequired. A model slug such as openai/gpt-6.1-sol. See GET /api/v1/models.
modelsOptional ordered fallback list of additional model slugs (max 8 total).
messagessystem, developer, user (text and image_url parts), assistant (with tool_calls), tool.
streamServer-sent events in OpenAI chunk format, terminated by data: [DONE].
max_tokens / max_completion_tokensOutput cap. Anthropic requires one; RouteHaven applies a default if omitted.
temperature, top_p, stop, seed, presence_penalty, frequency_penaltyForwarded when the target model accepts them; dropped for models that reject sampling parameters.
tools, tool_choice, parallel_tool_callsOpenAI function-calling format, translated for Anthropic and Gemini.
response_formatjson_object or json_schema (structured outputs where the provider supports it).
reasoning_effortMapped to the provider's effort / thinking-level control.
providerRouting preferences: order, only, ignore, allow_fallbacks, sort.
userEnd-user identifier forwarded to the provider for abuse monitoring.

Example response:

{
  "id": "gen-2xYq…",
  "object": "chat.completion",
  "model": "anthropic/claude-sonnet-5.5",
  "provider": "anthropic",
  "choices": [{ "index": 0, "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }],
  "usage": { "prompt_tokens": 21, "completion_tokens": 118, "total_tokens": 139,
             "prompt_tokens_details": { "cached_tokens": 0 }, "cost": 0.000035 }
}

Streaming

Set "stream": true. Each event is a chat.completion.chunk. A final chunk with an empty choices array carries usage (including cost) unless you set stream_options.include_usage to false. Failover happens only before the first byte is sent; errors after that arrive as a data: {"error": …} event followed by [DONE].

Tool calling

{
  "model": "google/gemini-3.8-flash",
  "messages": [{"role": "user", "content": "What's the weather in Paris?"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Current weather for a city",
      "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
    }
  }]
}

Return results with a tool message whose tool_call_id matches the call. Echo tool-call ids back unchanged: for Gemini they carry the provider's thought signature. Some newer models (for example Claude Opus 5.5, Sonnet 5.5, Fable 5.1) do not accept forced tool choice; RouteHaven downgrades "required" or a named tool to "auto" for those models.

Routing & failover

For each request RouteHaven builds an ordered list of attempts: every model in [model, ...models], every active provider endpoint for that model, and every credential you have for that provider. It moves to the next attempt on HTTP 401/403 (bad key), 404, 408, 429, 5xx, timeouts and network errors. Validation errors (400/422) are returned immediately.

{
  "model": "sandbox/unavailable",
  "models": ["anthropic/claude-haiku-5.5", "sandbox/echo"],
  "provider": { "order": ["anthropic"], "allow_fallbacks": true },
  "messages": [{"role": "user", "content": "hi"}]
}

The full attempt chain for any request is visible in the dashboard activity log and via GET /api/v1/generation?id=….

Bring your own key (BYOK)

Add provider keys under Dashboard → BYOK. They are encrypted with AES-256-GCM (key version tracked for rotation) and bound to your organization; only the last four characters are ever displayed. When you hold several keys for a provider, they are tried in priority order. With BYOK the provider bills you directly for tokens; RouteHaven deducts only the plan's BYOK fee from your balance after the monthly free allowance.

Platform-billed access (RouteHaven's own provider keys) is disabled for every provider until a reseller agreement with that provider is on file. Requests for such models without a BYOK key return byok_required.

Limits & budgets

  • Per-key rate limit (requests/minute), defaulting to your plan's limit. Responses include x-ratelimit-* headers.
  • Per-key spend cap, optional model allow-list and expiry date.
  • Organization monthly spend limit and team monthly budgets.
  • Prepaid balance: requests that would be billed need sufficient balance (plus any credit line granted to your organization).

Usage & cost

Tokens are taken from the provider's usage report. If a provider omits usage (for example on an interrupted stream), RouteHaven estimates it and flags the record as usage_estimated. Cost is computed from list price per 1M tokens for uncached prompt, cached prompt and completion tokens, plus the applicable fee.

Other endpoints

GET /api/v1/modelsPublic catalog with pricing, context length, modalities and access type.
GET /api/v1/keyInformation about the calling key: usage, limit, rate limit, organization balance.
GET /api/v1/generation?id=Metadata, tokens, cost and fallback attempts for one request id (own organization only).

Errors

Errors use the OpenAI shape { "error": { "message", "type", "code" } }.

HTTPcodeMeaning
400invalid_request_errorMalformed body or parameters.
400byok_requiredNo credential for the model's provider. Add a BYOK key.
401authentication_errorMissing, invalid, revoked or expired key.
402insufficient_balanceBalance too low for the estimated charge.
402key_spend_limit_exceeded / org_monthly_limit_exceeded / team_monthly_limit_exceededA budget was reached.
403model_not_allowed / permission_errorModel not in key allow-list, or organization suspended.
404model_not_foundUnknown model slug.
429rate_limit_exceededPer-key rate limit hit; see retry-after.
502upstream_unavailable / upstream_errorAll attempts failed; details in error.attempts.
503no_available_providerNo active endpoint could serve the request.

Sandbox models

sandbox/echo and sandbox/unavailable never call a real provider and are never billed. echo repeats your last message, streams word by word, and emits a tool call when tools are supplied and the message mentions a tool. unavailable always fails with 503 so you can test failover.