> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swarms.world/llms.txt
> Use this file to discover all available pages before exploring further.

# RouteHub quickstart

> Make your first call, switch providers, stream, run async and call tools with RouteHub

> [!NOTE]
>
> Before you begin, [install RouteHub](https://docs.swarms.world/routehub/installation.md) and set an API key for at least one provider.

## Make your first call

**1. Set a provider key**

```bash theme={null}
export OPENAI_API_KEY="sk-..."
```

**2. Call a model**

```python theme={null}
import routehub

response = routehub.completion(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "Summarize our Q3 risks in three bullets."}],
)
print(response.choices[0].message.content)
print(response.usage.total_tokens)
```

`response` is an `openai.types.chat.ChatCompletion`, the same object the OpenAI SDK returns.

**3. Switch providers**

Change the model string to change providers. The call and the response type stay the same:

```python theme={null}
messages = [{"role": "user", "content": "Summarize our Q3 risks in three bullets."}]

routehub.completion(model="claude-sonnet-4-6", messages=messages)
routehub.completion(model="gemini/gemini-3-flash-preview", messages=messages)
routehub.completion(model="groq/llama-3.3-70b-versatile", messages=messages)
routehub.completion(model="openrouter/anthropic/claude-sonnet-4.6", messages=messages)
```

Each provider reads its own key variable, such as `ANTHROPIC_API_KEY` or `GROQ_API_KEY`. See [Providers](https://docs.swarms.world/routehub/providers.md).

## Stream a response

Pass `stream=True` to get an iterator of `ChatCompletionChunk` objects:

```python theme={null}
for chunk in routehub.completion(
    model="claude-sonnet-4-6", messages=messages, stream=True
):
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="")
```

## Run async

`acompletion` takes exactly the same arguments as `completion`:

```python theme={null}
import asyncio

import routehub


async def main():
    response = await routehub.acompletion(
        model="gpt-5.4-mini", messages=messages
    )
    print(response.choices[0].message.content)


asyncio.run(main())
```

## Call a tool

Tools use the OpenAI format for every provider. RouteHub translates them for Claude.

```python theme={null}
weather = {
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the weather for a city.",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}

response = routehub.completion(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Weather in Paris?"}],
    tools=[weather],
)
call = response.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)
```

## Handle errors

Every provider failure is raised as a typed exception:

```python theme={null}
try:
    routehub.completion(model="gpt-5.4-mini", messages=messages, num_retries=3)
except routehub.ContextWindowExceededError:
    ...  # trim the conversation and retry
except routehub.RateLimitError as error:
    print(error.status_code, error.llm_provider, error.model)
```

## Next steps

> **[Streaming and async](https://docs.swarms.world/routehub/streaming-and-async.md)**
>
> Usage on streams, context managers and async streams

> **[Tool calling](https://docs.swarms.world/routehub/tool-calling.md)**
>
> Run a complete tool loop

> **[Structured output](https://docs.swarms.world/routehub/structured-output.md)**
>
> Get JSON that matches a pydantic model

> **[Reasoning](https://docs.swarms.world/routehub/reasoning.md)**
>
> Control thinking with one argument across providers


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.