SumoRouter
SumoRouter Customer API

SumoRouter Customer API

AI gateway (OpenAI / Anthropic compatible) and the dashboard account API.

SumoRouter is an AI gateway with prepaid credit. This reference covers everything a customer can call:

  • AI API (/v1/*) — OpenAI Chat Completions, Responses, Embeddings and Models, the Anthropic Messages API, and decision models (OpenAI Decisions / TypeSafe System One). Authenticate with an API key (sk-…). Point any OpenAI SDK at https://<host>/v1, or any Anthropic SDK / Claude Code at https://<host>. The same routes are also served under /api/v1/* for older clients.
  • Dashboard API (/api/*) — sign-up and sign-in, account, API key management, usage analytics, billing and the playground. Authenticate with a session token (JWT) from POST /api/auth/login. Use this to build your own frontend on top of SumoRouter.

Admin routes (/api/admin/*), the admin MCP server (/mcp) and payment webhooks are not part of this reference.

Money

All amounts on the Dashboard API are integers in nano-USD: 1 USD = 1_000_000_000 (fields ending in _nano). Model prices (prompt_price_nano, completion_price_nano, cache_read_price_nano) are nano-USD per 1 million tokens. Top-ups are paid in Indonesian Rupiah (amount_idr, whole rupiah) and converted to credit at the configured idr_per_usd rate.

The AI API follows OpenAI conventions instead: non-streamed responses carry usage.cost as a float in USD, and GET /v1/models prices are decimal strings in USD per token.

Errors

Errors are JSON in the OpenAI shape:

JSONCode
{ "error": { "message": "insufficient credits, please top up", "type": "insufficient_credits", "code": 402 } }

type is one of invalid_request_error (400), authentication_error (401), permission_error (403), not_found_error (404), conflict_error (409), insufficient_credits (402), rate_limit_error (429), upstream_error (502) or internal_error (500). /v1/messages and /v1/messages/count_tokens use the Anthropic shape instead ({"type":"error","error":{"type":…,"message":…}}).

When the upstream model provider itself rejects a request, its status code and error body are passed through unchanged. Malformed JSON on Dashboard endpoints is rejected by the framework with a plain-text 400, 415 or 422 before reaching SumoRouter's own validation.

Tags