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

# OpenAI SDK

> Use the official openai npm package against apisale.

Point the [official OpenAI JavaScript SDK](https://github.com/openai/openai-node) at apisale. Routes and response shapes match OpenAI's image/video APIs where applicable.

## Install

```bash theme={null}
npm install openai
```

## Configure client

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

const client = new OpenAI({
  apiKey: process.env.APISALE_API_KEY, // sk-... or sk_test-...
  baseURL: "https://api.apisale.ai/v1",
});
```

<Note>
  The SDK sends `Authorization: Bearer &lt;apiKey&gt;`. apisale accepts Bearer and `Key` schemes.
</Note>

## List models

```typescript theme={null}
const models = await client.models.list();
console.log(models.data.map((m) => m.id));
```

Equivalent REST:

```bash theme={null}
curl "https://api.apisale.ai/v1/models" \
  -H "Authorization: Bearer $APISALE_API_KEY"
```

Returns OpenAI-shaped models including **openai** and **grok-openai** protocol entries. See [SDK-compatible models](/sdk-compat/generated/models).

## Generate images (sync)

```typescript theme={null}
const response = await client.images.generate({
  model: "gpt-image-2",
  prompt: "A product photo on a marble desk, soft studio light",
  size: "1024x1024",
  n: 1,
});

const url = response.data[0]?.url;
```

| SDK `model`             | Operation      | apisale routes to                   |
| ----------------------- | -------------- | ----------------------------------- |
| `gpt-image-2`           | text-to-image  | `openai/gpt-image-2/text-to-image`  |
| `gpt-image-2` + `image` | image-to-image | `openai/gpt-image-2/image-to-image` |
| `grok-imagine-image`    | text/image     | `xai/grok-imagine-image/...`        |

### Image edit endpoint

```typescript theme={null}
await client.images.edit({
  model: "gpt-image-2",
  prompt: "Add a red hat",
  image: imageFile, // or URL depending on SDK version
});
```

REST: `POST /v1/images/edits`

## Generate video (async)

Video generation is **asynchronous** — submit a job, then poll until complete.

```typescript theme={null}
const job = await client.videos.generate({
  model: "sora-2",
  prompt: "Ocean waves at golden hour, cinematic",
  size: "1280x720",
  seconds: 5,
});

let status = job;
while (status.status === "queued" || status.status === "in_progress") {
  await new Promise((r) => setTimeout(r, 3000));
  status = await client.videos.retrieve(job.id);
}

// Download bytes or follow redirect
const content = await client.videos.downloadContent(job.id);
```

| Endpoint                      | Purpose                           |
| ----------------------------- | --------------------------------- |
| `POST /v1/videos/generations` | Submit video job                  |
| `GET /v1/videos/{id}`         | Poll status                       |
| `GET /v1/videos/{id}/content` | Download MP4 (redirect or binary) |

## Python (official SDK)

```python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ["APISALE_API_KEY"],
    base_url="https://api.apisale.ai/v1",
)

image = client.images.generate(
    model="gpt-image-2",
    prompt="A serene mountain lake at dawn",
    size="1024x1024",
)
print(image.data[0].url)
```

## Parameter mapping (images)

| OpenAI field          | apisale `input`             |
| --------------------- | --------------------------- |
| `prompt`              | `prompt`                    |
| `n` / `num_images`    | `num_images`                |
| `size` `1024x1024`    | `image_size: square_hd`     |
| `size` `1536x1024`    | `image_size: landscape_4_3` |
| `quality`             | `quality`                   |
| `image` / `image_url` | `image_url`                 |

## Errors

Errors follow OpenAI-style JSON where possible. Check:

* **401** — invalid API key
* **402** — insufficient wallet balance
* **429** — concurrency or rate limit ([Errors & limits](/get-started/errors-and-limits))

## Related

* [SDK-compatible models](/sdk-compat/generated/models) — live ID → slug table
* [REST run API](/model-apis/submit-run) — all catalog models
* [Account monitoring](/get-started/account-and-monitoring) — same API key
