# Quickstart

> Send your first request to router.africa in a few minutes, using the SDK you already have.

Source: https://router.africa/docs/quickstart

> **Note:** router.africa is compatible with the OpenAI and Anthropic SDKs. If your code already uses one of them, you only change the base URL and the API key. For the Anthropic SDK, see [Messages](https://router.africa/docs/messages).

## Get an API key

Create a key in the dashboard under **API keys**. Keys start with `sk-ra-` and are shown once, so copy yours now and store it as an environment variable.

**macOS and Linux**

```bash
export ROUTER_AFRICA_API_KEY="sk-ra-..."
```

**Windows PowerShell**

```powershell
$env:ROUTER_AFRICA_API_KEY = "sk-ra-..."
```

> **Keep your key server-side:** Never put a key in a browser app, a mobile app or a public repository. Anyone who has it can spend your credits. If a key leaks, revoke it in the dashboard and create a new one.

## Install an SDK

Pick your package manager. The same package works with router.africa; there is no separate router.africa SDK.

**npm**

```bash
npm install openai
```

**pnpm**

```bash
pnpm add openai
```

**yarn**

```bash
yarn add openai
```

**bun**

```bash
bun add openai
```

**pip**

```bash
pip install openai
```

> **Tip:** Your choice of language, SDK and package manager is remembered on every page of the docs.

## Send your first request

Choose how you call the API. Every tab sends the same request to `https://api.router.africa/v1`.

**OpenAI SDK**

*curl*

```bash
curl https://api.router.africa/v1/chat/completions \
  -H "Authorization: Bearer $ROUTER_AFRICA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{"role": "user", "content": "Habari! Say hello in Swahili."}]
  }'
```

*Python*

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.router.africa/v1",
    api_key="sk-ra-...",  # use an environment variable in real code
)

completion = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Habari! Say hello in Swahili."}],
)
print(completion.choices[0].message.content)
```

*TypeScript*

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.router.africa/v1",
  apiKey: process.env.ROUTER_AFRICA_API_KEY,
});

const completion = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Habari! Say hello in Swahili." }],
});
console.log(completion.choices[0].message.content);
```

**Anthropic SDK**

*curl*

```bash
curl https://api.router.africa/v1/messages \
  -H "Authorization: Bearer $ROUTER_AFRICA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4",
    "max_tokens": 256,
    "messages": [{"role": "user", "content": "Habari! Say hello in Swahili."}]
  }'
```

*Python*

```python
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.router.africa",
    api_key="sk-ra-...",  # sent as x-api-key
)

message = client.messages.create(
    model="anthropic/claude-sonnet-4",
    max_tokens=256,
    messages=[{"role": "user", "content": "Habari! Say hello in Swahili."}],
)
print(message.content[0].text)
```

*TypeScript*

```typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.router.africa",
  apiKey: process.env.ROUTER_AFRICA_API_KEY, // sent as x-api-key
});

const message = await client.messages.create({
  model: "anthropic/claude-sonnet-4",
  max_tokens: 256,
  messages: [{ role: "user", content: "Habari! Say hello in Swahili." }],
});
console.log(message.content[0].text);
```

**HTTP**

*curl*

```bash
curl https://api.router.africa/v1/chat/completions \
  -H "Authorization: Bearer $ROUTER_AFRICA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{"role": "user", "content": "Habari! Say hello in Swahili."}]
  }'
```

*Python*

```python
import os
import requests

response = requests.post(
    "https://api.router.africa/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['ROUTER_AFRICA_API_KEY']}"},
    json={
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Habari! Say hello in Swahili."}],
    },
    timeout=60,
)
print(response.json()["choices"][0]["message"]["content"])
```

*TypeScript*

```typescript
const response = await fetch("https://api.router.africa/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ROUTER_AFRICA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/gpt-4o-mini",
    messages: [{ role: "user", content: "Habari! Say hello in Swahili." }],
  }),
});
const data = await response.json();
console.log(data.choices[0].message.content);
```

A successful response includes the model's reply and a `usage` object with the tokens used. The response header `x-request-id` identifies the request in your logs and in any support message.

## Stream the response

Add `"stream": true` to receive tokens as they are generated. See [Streaming](https://router.africa/docs/streaming) for the details, including streaming with the Anthropic SDK. Ask for a final usage chunk with `stream_options.include_usage`.

```bash
curl https://api.router.africa/v1/chat/completions \
  -H "Authorization: Bearer $ROUTER_AFRICA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "stream": true,
    "stream_options": { "include_usage": true },
    "messages": [
      { "role": "system", "content": "You are a helpful assistant for a Nairobi delivery startup." },
      { "role": "user", "content": "Write a two-line status message for a delayed parcel." }
    ]
  }'

# The response is a stream of server-sent events:
data: {"id":"gen-8f2c","choices":[{"delta":{"role":"assistant","content":"Your"}}]}
data: {"id":"gen-8f2c","choices":[{"delta":{"content":" parcel is on its way"}}]}
data: {"id":"gen-8f2c","choices":[{"delta":{"content":", running a little late."}}]}
data: {"id":"gen-8f2c","choices":[],"usage":{"prompt_tokens":38,"completion_tokens":21,"total_tokens":59}}
data: [DONE]
```

## What a request costs

Requests are paid for with **credits**. Before a request runs, router.africa holds the credits it may need at the published rate; when it finishes, you are charged for the tokens actually used and the rest of the hold is released. You can see your balance and every request in the dashboard.

> **Note:** Credits are shown as a plain number and are used only for requests. When your available credits are too low, the API returns `402` with the reason `insufficient_credits` and does not call the model.

## Next steps

- [Authentication](https://router.africa/docs/authentication): how keys work and how to keep them safe.
- [Messages](https://router.africa/docs/messages): use the Anthropic SDK.
- [Responses](https://router.africa/docs/responses): use the OpenAI Responses API.
- [Look up a request](https://router.africa/docs/generation): check what one request cost.
- [Credits and billing](https://router.africa/docs/credits-and-billing): what a request costs.
- [Errors](https://router.africa/docs/errors) and [Rate limits](https://router.africa/docs/rate-limits): what to do when a request fails.
- [Compatibility notes](https://router.africa/docs/compatibility-notes): where router.africa differs from OpenAI and Anthropic.
