Console
Get started

Quickstart

Get a key and make your first call.

Go from signup to a streamed, billed model call in five steps. You need a browser, curl and an email address.

One RouterPlus key works on two APIs:

APIEndpointWorks with
OpenAI-compatiblePOST https://demo-api.routerplus.com/v1/chat/completionsOpenAI SDKs, any OpenAI-format client
Anthropic-compatiblePOST https://demo-api.routerplus.com/v1/messagesAnthropic SDKs, Claude Code

Every chat model works on both APIs. Image models use POST /v1/images/generations.

Tip

To set up with a coding agent, give it the runbook on Coding agents. Complete browser signup first, then let the agent configure your client.

1. Sign up and save your key

  1. 01
    Open Sign up and complete Clerk authentication and email verification.
  2. 02
    Save the tm_vk_ API key shown after your first verified sign-in. You can copy it again later from its row at API keys.
  3. 03
    Buy credits in Billing before your first call. Signup does not add free credit.

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

If you have an account, sign in with the same verified email and create a key at API keys. Your balance and keys stay.

You can create an account only in the browser. POST /v1/signup is removed. See Authentication.

Export the key:

bash
export TM_API_KEY=tm_vk_...

2. Pick a model

bash
# Public catalog, no auth: ids, prices, context windows, provider retention
curl -s https://demo.routerplus.com/api/models.json

# Models your key can call, in your SDK's list shape
curl -s -H "Authorization: Bearer $TM_API_KEY" https://dev2-api.routerplus.com/v1/models

GET /v1/models returns the OpenAI list shape. It returns the Anthropic shape when you send an anthropic-version header. See Models & catalog.

Note

An id that is not in the catalog returns a 404 with error_type: model_unavailable and the id you sent. RouterPlus does not substitute another model.

3. Make a streamed call on the OpenAI API

This calls a Claude model in the OpenAI format:

bash
curl -N https://dev2-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": "Say hello in five words."}]
  }'

The stream sends a role delta, content deltas, a finish chunk, a usage chunk, then data: [DONE]. The usage chunk holds the cost:

json
{
  "prompt_tokens": 13,
  "completion_tokens": 9,
  "total_tokens": 22,
  "prompt_tokens_details": { "cached_tokens": 0, "cache_write_tokens": 0 },
  "completion_tokens_details": { "reasoning_tokens": 0 },
  "cost": 0.000058
}

cost is in USD. RouterPlus computes it with the same integer micro-USD math as the ledger. It covers the full request, including attempts that failed over before your answer started. You can compute it again from the token counts and the public prices. See Pricing & billing.

With the OpenAI SDK, change only 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"])

stream = client.chat.completions.create(
    model="claude-haiku-4-5",
    max_tokens=60,
    stream=True,
    messages=[{"role": "user", "content": "Say hello in five words."}],
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
    if chunk.usage:  # the final chunk before [DONE]
        print(f"\ncost: ${chunk.usage.cost}")
typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://demo-api.routerplus.com/v1",
  apiKey: process.env.TM_API_KEY,
});

const stream = await client.chat.completions.create({
  model: "claude-haiku-4-5",
  max_tokens: 60,
  stream: true,
  messages: [{ role: "user", content: "Say hello in five words." }],
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Tip

Before dispatch, RouterPlus reserves the cost of the call: about (estimated input + max_tokens) at the model's prices. Without max_tokens it reserves at most 32,768 output tokens. After the call, it settles to the real usage. On a small balance, keep max_tokens low. If the reservation is larger than your balance, you get insufficient_quota before RouterPlus calls a provider. See Rate limits & spend caps.

4. Use the same key on the Anthropic API

This calls a GPT model in the Anthropic format:

bash
curl -N https://dev2-api.routerplus.com/v1/messages \
  -H "x-api-key: $TM_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "stream": true,
    "max_tokens": 60,
    "messages": [{"role": "user", "content": "Say hello in five words."}]
  }'

The last message_delta event has the usage: input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens and cost in USD.

python
import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://demo-api.routerplus.com",
    api_key=os.environ["TM_API_KEY"],
)

with client.messages.stream(
    model="gpt-4o-mini",
    max_tokens=60,
    messages=[{"role": "user", "content": "Say hello in five words."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="")
Note

Both endpoints accept both auth headers: Authorization: Bearer and x-api-key. Use the one your SDK sends. See Authentication.

5. Check the cost

bash
curl -s -H "Authorization: Bearer $TM_API_KEY" https://dev2-api.routerplus.com/v1/usage
json
{
  "balance_usd": 4.999942,
  "credited_usd": 5.0,
  "spent_usd": 0.000058,
  "recent_attempts": [
    {
      "request_id": "5a2e…",
      "deployment": "anthropic",
      "model": "claude-haiku-4-5",
      "outcome": "completed",
      "usage_provenance": "observed",
      "input_tokens": 13,
      "output_tokens": 9,
      "cost_usd": 0.000058,
      "billing_source": "house",
      "at": "2026-09-04T10:14:03.201Z"
    }
  ]
}

The example is shortened. Each attempt also has its price snapshot and inference cost. recent_attempts lists your last 20 attempts. See GET /v1/usage.

For the full audit of one request, pass the x-request-id header of any response. The audit shows every attempt, including failovers, cache splits, and reserved and settled cost:

bash
curl -s -H "Authorization: Bearer $TM_API_KEY" \
  "https://demo-api.routerplus.com/v1/generation?id=REQUEST_ID"

Both endpoints return metadata only: token counts, timings, outcomes and cost. See Data policy.

You can also see usage and each request in the console: open Usage or Logs.

Rules to know

  • An unknown model id returns a 404. RouterPlus does not substitute another model. See Routing & failover.
  • n > 1 returns a 400 invalid_request.
  • The first key shown after verified sign-in starts at 20 requests per minute. Until your organization buys credit, all its keys together stay at 20 requests per minute. After the first purchase, keys you create in the console get 300. Every organization also has token-per-minute and concurrency limits. See Rate limits & spend caps.
  • Every error body has a stable error_type, on both APIs, in your SDK's error shape. See Errors.

Next steps

For agents: /docs/quickstart.md and /llms.txt