# Overview

RouterPlus is an LLM gateway. One API key and one prepaid balance give you models from many providers, over an OpenAI-compatible API and an Anthropic-compatible API.

Every chat model works on both APIs. RouterPlus translates requests, streams and errors between them. You pay the listed per-token prices, and each billed response states its cost in `usage.cost`.

## Get a key

1. Open [Sign up](https://demo.routerplus.com/signup). Complete Clerk authentication and email verification.
2. Save the first API key shown after sign-in.
3. Buy credits in [Billing](https://demo.routerplus.com/console/billing). Signup does not add free credit.

If you have an account, [sign in](https://demo.routerplus.com/login) and create another key at [API keys](https://demo.routerplus.com/console/keys).

If purchase matching is offered for your account, Billing shows the cap and remaining matching credit.

## Make a call

```bash
export TM_API_KEY=tm_vk_...

curl -N https://demo-api.routerplus.com/v1/chat/completions \
  -H "Authorization: Bearer $TM_API_KEY" \
  -H "content-type: application/json" \
  -d '{"model":"claude-haiku-4-5","stream":true,"max_tokens":60,"messages":[{"role":"user","content":"hello"}]}'
```

The last usage chunk of the stream has the token counts and `cost`: the USD amount this request debited.

With an SDK, change only the base URL and the key:

```python
import os
from openai import OpenAI

client = OpenAI(base_url="https://demo-api.routerplus.com/v1", api_key=os.environ["TM_API_KEY"])
r = client.chat.completions.create(
    model="claude-haiku-4-5",   # a Claude model over the OpenAI format
    max_tokens=60,
    messages=[{"role": "user", "content": "hello"}],
)
print(r.model_dump()["usage"]["cost"])  # USD debit for this request
```

```python
import os
import anthropic

client = anthropic.Anthropic(base_url="https://demo-api.routerplus.com", api_key=os.environ["TM_API_KEY"])
msg = client.messages.create(
    model="gpt-4o-mini",        # a GPT model over the Anthropic format
    max_tokens=60,
    messages=[{"role": "user", "content": "hello"}],
)
```

## Two APIs, one key

| API | Base URL | Endpoint | Works with |
|---|---|---|---|
| OpenAI-compatible | `https://demo-api.routerplus.com/v1` | `POST /v1/chat/completions`, and `POST /v1/responses` for OpenAI's models | OpenAI SDKs, Codex, Cursor, Cline, Kilo Code, OpenCode, any OpenAI-format client |
| Anthropic-compatible | `https://demo-api.routerplus.com` | `POST /v1/messages` | Anthropic SDKs, Claude Code |

The key works on both APIs, as `Authorization: Bearer` or `x-api-key`. The API you use does not limit the model: OpenAI-format code can call Claude models, and Anthropic-format code can call GPT models. See [Authentication](/docs/authentication).

## How requests behave

- **Cost.** Every billed response has `usage.cost` in USD. It covers the full debit, including attempts that failed over before your answer started. See [Pricing & billing](/docs/pricing).
- **Failover.** Before any output reaches you, RouterPlus fails over to another provider. After output starts, the request stays with that provider. A failure then ends the stream with one error event. See [Routing & failover](/docs/routing).
- **Keep-alives.** During a silence, the stream sends a keep-alive every 15 seconds. See [Streaming](/docs/streaming).
- **No substitution.** An unknown model id returns a 404 that names the id you sent. RouterPlus does not pick another model.
- **Strict requests.** `n>1` returns a 400. Content or a parameter that cannot be translated returns a typed 400 that names the field. RouterPlus drops unknown top-level parameters and names each one in the `x-tm-dropped-params` header. See [Wire compatibility](/docs/compat).
- **Metadata only.** Metering and logs record token counts, timings, outcomes and cost. See [Data policy](/docs/data-policy).

## Gateway endpoints

All gateway endpoints at `https://demo-api.routerplus.com` take your API key.

| Endpoint | What it does |
|---|---|
| `POST /v1/chat/completions` | OpenAI-compatible completions, streamed or not |
| `POST /v1/messages` | Anthropic-compatible messages, streamed or not |
| `POST /v1/messages/count_tokens` | Anthropic token counting, not billed. Only models with an Anthropic-format deployment |
| `POST /v1/responses` | OpenAI Responses API. See [POST /v1/responses](/docs/api-responses) |
| `POST /v1/embeddings` | Text to vectors. See [POST /v1/embeddings](/docs/api-embeddings) |
| `POST /v1/audio/transcriptions`, `POST /v1/audio/speech` | Speech to text and text to speech. See [POST /v1/audio](/docs/api-audio) |
| `POST /v1/images/generations` | OpenAI Images API, base64 in the body. See [POST /v1/images/generations](/docs/api-images) |
| `POST /v1/videos` | Video from a text prompt. See [POST /v1/videos](/docs/api-videos) |
| `POST /v1/decisions` | Typed answers from a decision model. See [POST /v1/decisions](/docs/api-decisions) |
| `/v1/files`, `/v1/batches` | Many requests from one file. See [Batches](/docs/api-batches) |
| `GET /v1/models` | Models your key can call. OpenAI list shape by default, Anthropic shape when you send an `anthropic-version` header |
| `GET /v1/usage` | Balance, credited and spent totals, recent requests with cost |
| `GET /v1/generation?id=<request id>` | Audit of each attempt for one request: tokens, provenance, cost, outcome |
| `POST /v1/route` | Shows how a request would route, without sending it. See [Routing policies](/docs/routing-policies) |
| `GET /v1/limits?model=<id>` | The rate limits that apply to your key. See [Limits and capacity](/docs/admission) |

## Site

| Page | What it does |
|---|---|
| [`/api/models.json`](https://demo.routerplus.com/api/models.json) | Public catalog: ids, prices, context windows, who serves each model. No auth. See [Models & catalog](/docs/models) |
| `/models/<id>` | Each model's providers, prices, latency and uptime over the last 24 hours |
| [`/playground`](https://demo.routerplus.com/playground) | Chat with any catalog model, compare up to three side by side, judge with a decision model, and make images. See [Playground](/docs/playground) |
| [`/model-search`](https://demo.routerplus.com/model-search) | Optimize: find a cheaper model or mix that scores as well as yours on your Braintrust evals, then deploy it. See [Optimize](/docs/model-search) |
| [`/endpoints`](https://demo.routerplus.com/endpoints) | Your [dedicated endpoints](/docs/dedicated-endpoints) and the models you deployed from Optimize. Each has a `tm/...` model id that your keys can call |
| [`/console`](https://demo.routerplus.com/console) | Keys, usage, logs, credits, limits, team and governance. See [Console](/docs/console) |
| `/signup`, `/login` | Browser signup and sign-in through Clerk |
| [`/llms.txt`](https://demo.routerplus.com/llms.txt), [`/llms-full.txt`](https://demo.routerplus.com/llms-full.txt) | The docs index for agents, and every docs page as raw markdown in one file |

## Where next

- [Quickstart](/docs/quickstart) - browser signup to a streamed API call in five steps.
- [Agent integration guide](/docs/agent-integration) - the page an AI agent reads to build RouterPlus into your product.
- [Coding agents](/docs/install) - setup for Claude Code, Codex, Cursor, Cline, Kilo Code, OpenCode and more.
- [Migrate in one prompt](/docs/migration) - move the OpenAI SDK, Anthropic SDK, Claude Code or Codex with one paste.
- [Errors & remediation](/docs/errors) - every `error_type`, what it means and what to do.

> [!TIP]
> If a coding agent does the work, point it at
> [https://demo.routerplus.com/docs/agent-integration.md](https://demo.routerplus.com/docs/agent-integration.md) to build
> RouterPlus into a product, or at [Install](/docs/install) to set up a coding tool.
> [https://demo.routerplus.com/llms.txt](https://demo.routerplus.com/llms.txt) is the index it reads first.
