# Perplexity Router API

:::callout{intent="note"}
Router API is in private preview. Email api@perplexity.ai to request access.
:::

## Overview

The Router API provides unified access to open-weight models hosted by Perplexity through a single API and API key. Send requests in the OpenAI Chat Completions, OpenAI Responses, or Anthropic Messages format, pick any model from the [catalog](/guides/router-api-models), and the platform routes each request to a healthy deployment automatically — no per-provider accounts, SDKs, or failover logic on your side.

Any model in the catalog can be called through any supported schema, regardless of the model's original provider. This makes the Router a drop-in replacement for existing OpenAI or Anthropic integrations — only the base URL and API key need to change.

Use the Router API for direct model access with your own prompts and tools. For web-grounded answers with built-in citations, use the [Agent API](/guides/agent-api-quickstart).

The base URL is `https://api.perplexity.ai/router/v1`, and your existing Perplexity API key works as-is.

## Installation

The Router API supports the OpenAI Chat Completions and Responses formats plus the Anthropic Messages format, so you can use either provider's official SDK — install whichever matches your integration (or both):

:::code-group
```bash Python theme={null}
pip install openai       # OpenAI Chat Completions and Responses formats
pip install anthropic    # Anthropic Messages format
```

```bash Typescript theme={null}
npm install openai              # OpenAI Chat Completions and Responses formats
npm install @anthropic-ai/sdk   # Anthropic Messages format
```
:::

## Authentication

Set your API key as an environment variable:

::::tabs
:::tab{title="macOS/Linux"}
```bash theme={null}
export PERPLEXITY_API_KEY="your_api_key_here"
```
:::

:::tab{title="Windows"}
```powershell theme={null}
setx PERPLEXITY_API_KEY "your_api_key_here"
```
:::
::::

Requests authenticate with an `Authorization: Bearer` header, which the SDKs set for you from the `api_key` parameter.

## Basic Usage

Point the OpenAI SDK at the Router base URL and pass any model id from the [catalog](/guides/router-api-models). Model ids use `creator/model-name` slugs, so switching providers is a one-line change:

:::code-group
```python Python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("PERPLEXITY_API_KEY"),
    base_url="https://api.perplexity.ai/router/v1"
)

response = client.chat.completions.create(
    model="perplexity/kimi-k3",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Explain the CAP theorem in two sentences."}
    ]
)

print(response.choices[0].message.content)
```

```typescript Typescript theme={null}
import OpenAI from 'openai';

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

const response = await client.chat.completions.create({
    model: "perplexity/kimi-k3",
    max_tokens: 1024,
    messages: [
        { role: "user", content: "Explain the CAP theorem in two sentences." }
    ]
});

console.log(response.choices[0].message.content);
```

```bash cURL theme={null}
curl -X POST 'https://api.perplexity.ai/router/v1/chat/completions' \
  -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "perplexity/kimi-k3",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Explain the CAP theorem in two sentences."}
    ]
  }' | jq
```
:::

:::accordion{title="Response"}
```json theme={null}
{
  "id": "chatcmpl-Xr7aQ2mVb9L4tW8pDcEfGh1JkNs0y",
  "object": "chat.completion",
  "created": 1753747200,
  "model": "perplexity/kimi-k3",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The CAP theorem states that a distributed system can guarantee at most two of three properties: consistency, availability, and partition tolerance. Since network partitions are unavoidable in practice, designers must choose between consistency and availability when a partition occurs.",
        "annotations": []
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 18,
    "completion_tokens": 52,
    "total_tokens": 70,
    "prompt_tokens_details": {
      "cached_tokens": 0
    }
  }
}
```
:::

The response echoes the model id you requested, and you are always billed at that model's [published rates](/guides/router-api-models) no matter how the request was served.

## OpenAI Responses

Use `client.responses.create()` with the same Router base URL when your integration uses the OpenAI Responses format. The Router Responses endpoint is stateless, so include the full conversation in `input` on each request.

:::code-group
```python Python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("PERPLEXITY_API_KEY"),
    base_url="https://api.perplexity.ai/router/v1"
)

response = client.responses.create(
    model="perplexity/kimi-k3",
    input="Explain the CAP theorem in two sentences.",
    max_output_tokens=1024
)

print(response.output_text)
```

```typescript Typescript theme={null}
import OpenAI from 'openai';

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

const response = await client.responses.create({
    model: "perplexity/kimi-k3",
    input: "Explain the CAP theorem in two sentences.",
    max_output_tokens: 1024
});

console.log(response.output_text);
```

```bash cURL theme={null}
curl -X POST 'https://api.perplexity.ai/router/v1/responses' \
  -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "perplexity/kimi-k3",
    "input": "Explain the CAP theorem in two sentences.",
    "max_output_tokens": 1024
  }' | jq
```
:::

## Streaming Chat Completions

Set `stream: true` to receive tokens as server-sent events. To get token usage with a streamed response, also set `stream_options: {"include_usage": true}` — usage then arrives in a final chunk before `data: [DONE]`:

:::code-group
```python Python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get("PERPLEXITY_API_KEY"),
    base_url="https://api.perplexity.ai/router/v1"
)

stream = client.chat.completions.create(
    model="perplexity/kimi-k3",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Write a haiku about network latency."}
    ],
    stream=True,
    stream_options={"include_usage": True}
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
    if chunk.usage:
        print(f"\n\nTokens used: {chunk.usage.total_tokens}")
```

```typescript Typescript theme={null}
import OpenAI from 'openai';

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

const stream = await client.chat.completions.create({
    model: "perplexity/kimi-k3",
    max_tokens: 1024,
    messages: [
        { role: "user", content: "Write a haiku about network latency." }
    ],
    stream: true,
    stream_options: { include_usage: true }
});

for await (const chunk of stream) {
    if (chunk.choices[0]?.delta?.content) {
        process.stdout.write(chunk.choices[0].delta.content);
    }
    if (chunk.usage) {
        console.log(`\n\nTokens used: ${chunk.usage.total_tokens}`);
    }
}
```

```bash cURL theme={null}
curl -N -X POST 'https://api.perplexity.ai/router/v1/chat/completions' \
  -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "perplexity/kimi-k3",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Write a haiku about network latency."}
    ],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'
```
:::

## Anthropic Messages

The same models are available in the Anthropic Messages format at `/router/v1/messages`, so code written against the Anthropic SDK works with a base-URL change:

:::callout{intent="info"}
The Anthropic SDK appends `/v1/messages` to its base URL, so configure it with `https://api.perplexity.ai/router` (no `/v1`). The OpenAI SDK appends `/chat/completions` and is configured with `https://api.perplexity.ai/router/v1`.
:::

:::code-group
```python Python theme={null}
from anthropic import Anthropic
import os

client = Anthropic(
    api_key=os.environ.get("PERPLEXITY_API_KEY"),
    base_url="https://api.perplexity.ai/router"
)

message = client.messages.create(
    model="perplexity/kimi-k3",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Explain the CAP theorem in two sentences."}
    ]
)

print(message.content[0].text)
```

```typescript Typescript theme={null}
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
    apiKey: process.env.PERPLEXITY_API_KEY,
    baseURL: "https://api.perplexity.ai/router"
});

const message = await client.messages.create({
    model: "perplexity/kimi-k3",
    max_tokens: 1024,
    messages: [
        { role: "user", content: "Explain the CAP theorem in two sentences." }
    ]
});

console.log(message.content[0].text);
```

```bash cURL theme={null}
curl -X POST 'https://api.perplexity.ai/router/v1/messages' \
  -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "perplexity/kimi-k3",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Explain the CAP theorem in two sentences."}
    ]
  }' | jq
```
:::

## Discovering Models

List the current catalog at any time — the response is OpenAI-compatible, sorted by model id, and includes each model's base token prices in USD per 1M tokens:

```bash theme={null}
curl 'https://api.perplexity.ai/router/v1/models' \
  -H "Authorization: Bearer $PERPLEXITY_API_KEY" | jq
```

:::accordion{title="Response"}
```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "perplexity/kimi-k3",
      "object": "model",
      "created": 0,
      "owned_by": "perplexity",
      "pricing": {
        "input": 3,
        "output": 15,
        "cache_read": 0.3,
        "unit": "usd_per_1m_tokens"
      }
    }
  ]
}
```
:::

See the [models page](/guides/router-api-models) for the full catalog with pricing.

## Next Steps

::::card-grid
:::card{title="Models & Pricing" href="/guides/router-api-models" icon="brain"}
The model catalog with per-token rates.
:::

:::card{title="Routing & Reliability" href="/guides/router-api-routing-and-reliability" icon="arrows-shuffle"}
How requests are routed and what happens when a provider fails.
:::

:::card{title="Chat Completions Reference" href="/guides/router-api-2-gateway-chat-completions-post" icon="code"}
Full request and response schema.
:::

:::card{title="Responses Reference" href="/guides/router-api-2-gateway-responses-post" icon="code"}
The OpenAI Responses-compatible endpoint schema.
:::

:::card{title="Messages Reference" href="/guides/router-api-2-gateway-messages-post" icon="code"}
The Anthropic-compatible endpoint schema.
:::
::::

Need help? Check out our [community](https://community.perplexity.ai) for support.

## Related pages

- [Admin & Management](./admin-management-index.md)
- [Agent API](./agent-api-2-index.md)
- [Agent API](./agent-api-index.md)
- [Analytics API](./analytics-api-index.md)
- [Authentication](./authentication-index.md)
- [Changelog](../changelog.md)
- [Cookbook](./cookbook-2-index.md)
- [Embeddings API](./embeddings-api-2-index.md)
- [Embeddings API](./embeddings-api-index.md)
- [Getting Started](./getting-started-index.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
