> For the complete documentation index, see [llms.txt](https://docs.avis.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.avis.xyz/api-reference/introduction/openai-compatibility.md).

# OpenAI Compatibility

Point the official `openai` SDK — or any tool that speaks the OpenAI API — at Avis. Set your real Avis API key in `apiKey` (see Authentication).

### Base URL

```
https://api.avis.xyz/api/openai/v1
```

### Switching an existing app

```typescript
import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: process.env.AVIS_API_KEY,
  baseURL: 'https://api.avis.xyz/api/openai/v1',
})
```

Nothing else in your existing OpenAI integration needs to change.

### Endpoints

| Method | Path                                | Streaming              | Description                               |
| ------ | ----------------------------------- | ---------------------- | ----------------------------------------- |
| `HEAD` | `/api/openai`                       | —                      | Connectivity probe (no auth)              |
| `GET`  | `/api/openai/v1/models`             | —                      | List available models                     |
| `POST` | `/api/openai/v1/chat/completions`   | ✅                      | Chat completions                          |
| `POST` | `/api/openai/v1/images/generations` | ✅ (provider-dependent) | Image generation                          |
| `POST` | `/api/openai/v1/videos`             | —                      | Submit an async video generation job      |
| `GET`  | `/api/openai/v1/videos/:id`         | —                      | Poll video job status                     |
| `GET`  | `/api/openai/v1/videos/:id/content` | —                      | Download the generated video              |
| `POST` | `/api/openai/v1/responses`          | ✅                      | Responses API (used by Codex CLI/Desktop) |
| `POST` | `/api/openai/v1/embeddings`         | —                      | Text embeddings; float vectors only       |

#### `POST /chat/completions`

```typescript
const response = await client.chat.completions.create({
  model: 'gpt-4-1-mini',
  messages: [{ role: 'user', content: 'Hello!' }],
})
console.log(response.choices[0].message.content)
```

#### `POST /images/generations`

```typescript
import { writeFileSync } from 'node:fs'

const response = await client.images.generate({
  model: 'seedream-4-0',
  prompt: 'A simple red apple on a white table, photorealistic',
  n: 1,
  size: '1024x1024',
  response_format: 'b64_json',
})

writeFileSync('output.jpg', Buffer.from(response.data[0].b64_json!, 'base64'))
console.log('Image saved to output.jpg')
```

#### `POST /videos` — async job

```typescript
import { writeFileSync } from 'node:fs'

const job = await client.videos.create({
  model: 'veo-3-1',
  prompt: 'A red apple falling from a tree in slow motion, photorealistic',
})
console.log('Job submitted:', job.id, '| status:', job.status)

let video = job
while (video.status !== 'completed' && video.status !== 'failed') {
  await new Promise((r) => setTimeout(r, 3000))
  video = await client.videos.retrieve(job.id)
  console.log('Status:', video.status)
}

if (video.status !== 'completed') {
  throw new Error(`Video generation failed. Status: ${video.status}`)
}

const content = await client.videos.downloadContent(video.id)
writeFileSync('output.mp4', Buffer.from(await content.arrayBuffer()))
console.log('Video saved to output.mp4 (via downloadContent)')
```

Supported video model providers currently route to OpenRouter only.

#### `POST /embeddings`

```typescript
const response = await client.embeddings.create({
  model: 'text-embedding-3-small',
  input: 'The quick brown fox jumps over the lazy dog.',
})
console.log(response.data[0].embedding)
```

`input` also accepts an array of strings (batched, up to 128) for multiple embeddings in one call.

Multimodal input (image/audio/file, and video on `gemini-embedding-2`/`gemini-embedding-2-preview`) is not part of the OpenAI wire format — use the low-level request body directly, or call through the Gemini-compatible or Anthropic-compatible surface instead, both of which accept Avis's normalized content-block input.

#### `GET /models`

```typescript
const models = await client.models.list()
console.log(models.data[0])
```

### Field support

This proxy is a **thin pass-through**. Request fields mostly follow OpenAI-compatible upstream definitions and are forwarded as-is. Whether a field is honored depends on the resolved provider/model.

### `/models` response

| Field                                   | Type            | Required | Notes                                                                                                                                                       |
| --------------------------------------- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                    | `string`        | ✅        | User-facing model ID used in `model` for OpenAI-compatible calls                                                                                            |
| `name`                                  | `string`        | —        | Human-readable model name                                                                                                                                   |
| `inputModalities`                       | `array<string>` | —        | Supported input modalities for the model                                                                                                                    |
| `outputModalities`                      | `array<string>` | —        | Supported output modalities for the model                                                                                                                   |
| `capabilitiesProviderId`                | `string`        | —        | Provider row selected by priority for capability resolution                                                                                                 |
| `capabilities`                          | `object`        | —        | Effective capability object for the priority-winning provider row. Absent means unconstrained.                                                              |
| `capabilities.text.supportedParameters` | `array<string>` | —        | For text models: accepted generation parameters (e.g. `maxTokens`, `temperature`, `topP`, `tools`, `thinking`).                                             |
| `capabilities.params`                   | `object`        | —        | Per-parameter bounds/constraints keyed by request field name. For image/video models, read from `capabilities.image.params` or `capabilities.video.params`. |
| `capabilities.inputs`                   | `object`        | —        | Accepted content-part inputs (roles, media types, limits).                                                                                                  |
| `capabilities.strictParams`             | `boolean`       | —        | When `true`, unsupported gated params are rejected.                                                                                                         |
| `chatPricing`                           | `object`        | —        | Effective chat pricing metadata for the selected provider row                                                                                               |
| `imagePricing`                          | `object`        | —        | Effective image pricing metadata for the selected provider row                                                                                              |
| `videoPricing`                          | `object`        | —        | Effective video pricing metadata for the selected provider row                                                                                              |
| `threeDPricing`                         | `object`        | —        | Effective 3D pricing metadata for the selected provider row                                                                                                 |
| `embeddingPricing`                      | `object`        | —        | Effective embedding pricing metadata for the selected provider row                                                                                          |

#### `capabilities.params` value shapes

For image/video models, use per-model `capabilities.image.params` or `capabilities.video.params` instead of hardcoding shared limits across models.

| `type`  | Extra fields                                          | Meaning                                                                                        |
| ------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `enum`  | `values: string[]`, `default?`                        | Value must be one of `values`.                                                                 |
| `range` | `min`, `max`, `default?`, `unit?`, `steps?: number[]` | Value must be between `min` and `max`. When `steps` exists, only those exact values are valid. |
| `int`   | `min`, `max`, `default?`                              | Value must be an integer between `min` and `max`.                                              |
| `bool`  | `default?`                                            | Value must be `true` or `false`.                                                               |

### `/chat/completions`

| Field               | Type               | Required | Notes                                                                          |
| ------------------- | ------------------ | -------- | ------------------------------------------------------------------------------ |
| `model`             | `string`           | ✅        | OpenAI model ID; resolved and rewritten to provider model ID before forwarding |
| `messages`          | `array`            | ✅        | Standard chat message array                                                    |
| `temperature`       | `number`           | —        | Sampling control                                                               |
| `max_tokens`        | `number`           | —        | Max completion tokens                                                          |
| `stream`            | `boolean`          | —        | Enable SSE response; used to choose streaming path                             |
| `stream_options`    | `object`           | —        | Streaming options; forced to `{ include_usage: true }` when `stream: true`     |
| `top_p`             | `number`           | —        | Nucleus sampling                                                               |
| `frequency_penalty` | `number`           | —        | Frequency penalty                                                              |
| `presence_penalty`  | `number`           | —        | Presence penalty                                                               |
| `tools`             | `array`            | —        | Function/tool calling definitions                                              |
| `tool_choice`       | `string \| object` | —        | Tool selection strategy                                                        |
| `response_format`   | `object`           | —        | Structured output mode                                                         |
| `provider`          | `object`           | —        | Provider routing/fallback options                                              |

### `/responses`

| Field                  | Type               | Required | Notes                                                                                                                  |
| ---------------------- | ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `model`                | `string`           | ✅        | OpenAI model ID; resolved and rewritten to provider model ID before forwarding                                         |
| `input`                | `string \| array`  | ✅        | Plain text or structured input items                                                                                   |
| `instructions`         | `string`           | —        | System-level instruction text                                                                                          |
| `stream`               | `boolean`          | —        | Enable SSE response events                                                                                             |
| `max_output_tokens`    | `number`           | —        | Output token cap                                                                                                       |
| `temperature`          | `number`           | —        | Sampling control                                                                                                       |
| `top_p`                | `number`           | —        | Nucleus sampling                                                                                                       |
| `tools`                | `array`            | —        | Function/tool calling definitions; filtered for non-native providers and keeps `type: "function"` only when applicable |
| `tool_choice`          | `string \| object` | —        | Tool selection strategy; subject to provider support                                                                   |
| `text`                 | `object`           | —        | Text output configuration                                                                                              |
| `store`                | `boolean`          | —        | Persist response upstream; dropped for non-native providers                                                            |
| `metadata`             | `object`           | —        | Custom metadata                                                                                                        |
| `reasoning`            | `object`           | —        | Reasoning config; dropped for non-native providers                                                                     |
| `include`              | `array`            | —        | Extra response parts; dropped for non-native providers                                                                 |
| `previous_response_id` | `string`           | —        | Link to prior response; dropped for non-native providers                                                               |
| `provider`             | `object`           | —        | Provider routing/fallback options                                                                                      |

### `/images/generations`

| Field             | Type      | Required | Notes                                                                                 |
| ----------------- | --------- | -------- | ------------------------------------------------------------------------------------- |
| `model`           | `string`  | ✅        | Image-capable model ID; resolved and rewritten to provider model ID before forwarding |
| `prompt`          | `string`  | ✅        | Image prompt text                                                                     |
| `quality`         | `string`  | —        | Quality tier                                                                          |
| `n`               | `number`  | —        | Number of images; used for pre-check estimation, then forwarded unchanged             |
| `size`            | `string`  | —        | Output dimensions                                                                     |
| `output_format`   | `string`  | —        | Output image format                                                                   |
| `response_format` | `string`  | —        | OpenAI-compatible payload format                                                      |
| `background`      | `string`  | —        | Background mode                                                                       |
| `style`           | `string`  | —        | Style preset                                                                          |
| `stream`          | `boolean` | —        | Stream image events when supported                                                    |
| `provider`        | `object`  | —        | Provider routing/fallback options                                                     |

### `/videos`

| Field                       | Type         | Required | Notes                                                                                        |
| --------------------------- | ------------ | -------- | -------------------------------------------------------------------------------------------- |
| `model`                     | `string`     | ✅        | Video-capable model ID; resolved and rewritten to provider model ID before forwarding        |
| `prompt`                    | `string`     | ✅        | Video prompt text (`1..32000` chars)                                                         |
| `seconds`                   | \`integer \\ | string\` | —                                                                                            |
| `size`                      | `string`     | —        | OpenAI-style output size. Supported values: `720x1280`, `1280x720`, `1024x1792`, `1792x1024` |
| `input_reference`           | `object`     | —        | Optional reference input. Must include exactly one of `image_url` or `file_id`               |
| `input_reference.image_url` | `string`     | —        | HTTP/HTTPS URL reference image                                                               |
| `input_reference.file_id`   | `string`     | —        | OpenAI file reference ID (currently rejected for routed providers that do not support it)    |

Notes:

* This endpoint validates request fields against OpenAI-style video create params before routing.
* For OpenRouter routing, the proxy maps OpenAI params into OpenRouter wire fields:
  * `seconds` -> `duration`
  * `size` -> `resolution` + `aspect_ratio`
  * `input_reference.image_url` -> `input_references[]`
* Unsupported fields for this compatibility route return `400`.

### `GET /videos/:id` polling response

| Field           | Type            | Required | Notes                                                                                    |
| --------------- | --------------- | -------- | ---------------------------------------------------------------------------------------- |
| `id`            | `string`        | ✅        | Video job ID                                                                             |
| `polling_url`   | `string`        | ✅        | Poll endpoint URL                                                                        |
| `status`        | `string`        | ✅        | Common statuses: `pending`, `in_progress`, `completed`, `failed`, `cancelled`, `expired` |
| `generation_id` | `string`        | —        | Generation record ID (available once processed)                                          |
| `unsigned_urls` | `array<string>` | —        | Provider video URLs when available                                                       |
| `usage`         | `object`        | —        | Cost and usage details when available                                                    |

### `GET /videos/:id/content` download response

| Field           | Type      | Required | Notes                                |
| --------------- | --------- | -------- | ------------------------------------ |
| `id` (path)     | `string`  | ✅        | Video job ID                         |
| `index` (query) | `integer` | —        | Video index to download, default `0` |

### `/embeddings`

| Field             | Type                      | Required | Notes                                                                                                                                                                  |
| ----------------- | ------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`           | `string`                  | ✅        | Embedding-capable model ID                                                                                                                                             |
| `input`           | `string \| array<string>` | ✅        | Text input. String arrays are batched (max 128). Multimodal content blocks aren't reachable through this OpenAI-shaped field — use Gemini or Anthropic compat instead. |
| `dimensions`      | `integer`                 | —        | Output vector dimensionality, when the model supports variable dimensions                                                                                              |
| `encoding_format` | `string`                  | —        | Only `"float"` is supported; anything else returns `400`                                                                                                               |

Response: `{ object: "list", data: [{ object: "embedding", index, embedding: number[] }], model, usage: { prompt_tokens, total_tokens } }`. Streaming and base64-encoded vector output are not supported.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.avis.xyz/api-reference/introduction/openai-compatibility.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
