---
title: "API overview"
description: "The pirouter API is served from one host, https://api.pirouter.ai, and speaks three protocols: OpenAI, Anthropic and Gemini. One key works on every endpoint that needs one."
canonical: "https://pirouter.ai/docs/api"
last-updated: "2026-10-13"
lang: "en"
source: "content/docs/en/api/index.mdx"
---

# API overview

The pirouter API is served from one host, https://api.pirouter.ai, and speaks three protocols: OpenAI, Anthropic and Gemini. One key works on every endpoint that needs one.

## Server

Every endpoint is served from one host:

`Base URL`:

```text
https://api.pirouter.ai
```

The path decides the protocol. A model answers only on the protocols it is registered for, and the gateway does not translate between them. [Models and protocols](https://pirouter.ai/docs/models.md) lists which model accepts which.

## Authentication

Send your key in one of two headers. Both carry the same key, and `Authorization` wins when a request has both.

`As a bearer token`:

```http
Authorization: Bearer $PIROUTER_API_KEY
```

`Or in X-Api-Key`:

```http
X-Api-Key: $PIROUTER_API_KEY
```

The four model catalog endpoints are public: they need no key and read none.

> **Warning:** Never ship a key in browser code or a mobile app. Call pirouter from your server and keep the key in an environment variable.

## Errors

An error body comes in one of two shapes, depending on which family the endpoint belongs to.

The inference endpoints (chat completions, responses, messages, the two Gemini endpoints and images) answer in this shape, whichever protocol they speak. `message` and `type` are always there. `code` is there whenever the platform reached a decision about the request, which is nearly always:

```json
{
  "error": {
    "message": "No such model. Model names are vendor-qualified (vendor/model), so a name copied from a provider's own docs needs its vendor prefix added. Call GET /v1/models for the slugs this gateway serves.",
    "type": "not_found_error",
    "code": "model_not_found"
  }
}
```

The four model catalog endpoints answer with a code and a message, and no `type`:

```json
{
  "error": {
    "code": "model_not_found",
    "message": "string"
  }
}
```

Branch on `error.code`, which is a stable string, and fall back to `error.type` where a response has no code. Do not match on the text of `message`. Each endpoint page lists the codes that endpoint can return and shows its error body. [Errors](https://pirouter.ai/docs/errors.md) explains every code and which errors to retry.

An error that the upstream provider itself answered is passed through with its own status and body, not rewritten into these shapes.

## Endpoints

| Protocol  | Endpoint                                                                           | Method | Path                                           |
| --------- | ---------------------------------------------------------------------------------- | ------ | ---------------------------------------------- |
| OpenAI    | [Create chat completion](https://pirouter.ai/docs/api/chat-completions.md)         | `POST` | `/v1/chat/completions`                         |
| OpenAI    | [Create response](https://pirouter.ai/docs/api/responses.md)                       | `POST` | `/v1/responses`                                |
| OpenAI    | [Create image](https://pirouter.ai/docs/api/images.md)                             | `POST` | `/v1/images/generations`                       |
| Anthropic | [Create message](https://pirouter.ai/docs/api/messages.md)                         | `POST` | `/v1/messages`                                 |
| Gemini    | [Generate content](https://pirouter.ai/docs/api/generate-content.md)               | `POST` | `/v1beta/models/{model}:generateContent`       |
| Gemini    | [Stream generate content](https://pirouter.ai/docs/api/stream-generate-content.md) | `POST` | `/v1beta/models/{model}:streamGenerateContent` |
| Catalog   | [List models](https://pirouter.ai/docs/api/list-models.md)                         | `GET`  | `/v1/models`                                   |
| Catalog   | [List models by vendor](https://pirouter.ai/docs/api/list-models-by-vendor.md)     | `GET`  | `/v1/models/{vendor}`                          |
| Catalog   | [Get model](https://pirouter.ai/docs/api/get-model.md)                             | `GET`  | `/v1/models/{vendor}/{model}`                  |
| Catalog   | [List model endpoints](https://pirouter.ai/docs/api/list-model-endpoints.md)       | `GET`  | `/v1/models/{vendor}/{model}/endpoints`        |

## OpenAPI specification

The pages of this section are generated from the OpenAPI 3.1 specification of the API. Download it to generate a client or to load it into your own tools: [openapi.json](https://pirouter.ai/docs/api/openapi.json).

> **Note:** New here? Start with the [quickstart](https://pirouter.ai/docs/quickstart.md).
