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

> ## Agent Instructions
> Authenticate every request with your API key in the `X-API-Key` header or `Authorization: Bearer`. Keys start with `sk-nunchux-`.
> Image generation is synchronous: the image is in the response.
> Video generation is asynchronous: submit the job, poll its task until it reaches a terminal status, then download the output promptly, because output URLs expire.

# OpenAI Compatibility

> Use the OpenAI Python or JavaScript SDK with the Nunchux API for image generation.

# OpenAI Compatibility

### Use the OpenAI SDK with the Nunchux API

## Overview

The Nunchux API is compatible with the [OpenAI Python SDK](https://github.com/openai/openai-python). Point the client at the [Nunchux base URL](/nunchux-optimized/overview#endpoints) and use your [Nunchux API key](/authentication). Your existing OpenAI code keeps working.

## Installation

Install the OpenAI Python SDK:

```bash theme={"system"}
pip install openai
```

## Client Setup

Point the OpenAI client at the Nunchux API by setting the `base_url` and `api_key`.

```python theme={"system"}
from openai import OpenAI

client = OpenAI(
    base_url="https://api.nunchux.ai/v1",
    api_key="YOUR_API_KEY",
)
```

The SDK sends your key as an `Authorization: Bearer` header, which the Nunchux API accepts on every endpoint. See [Authentication](/authentication) for details.

## Text-to-Image

Generate images from text descriptions using `client.images.generate()`. Nunchux-specific parameters like `tier` and `seed` are passed via `extra_body`.

```python theme={"system"}
import base64
from pathlib import Path

response = client.images.generate(
    model="nunchux-flux.2-klein-4b",
    prompt="A beautiful sunset over mountains",
    size="1024x1024",
    response_format="b64_json",
    n=1,
    extra_body={
        "tier": "radical_speed",
        "seed": 42,
    },
)

image_b64 = response.data[0].b64_json
Path("output.png").write_bytes(base64.b64decode(image_b64))
```

## Image-to-Image

Edit and transform existing images using `client.images.edit()`. Pass the source image as a file object opened in binary mode.

```python theme={"system"}
response = client.images.edit(
    model="nunchux-flux.2-klein-4b-edit",
    image=open("photo.jpg", "rb"),
    prompt="Transform into a watercolor painting",
    size="1024x1024",
    response_format="url",
    extra_body={
        "tier": "radical_speed",
    },
)

# URL format requested above
print(response.data[0].url)
```

## Nunchux-Specific Parameters

The OpenAI SDK does not natively support all Nunchux parameters. Use the `extra_body` argument to pass Nunchux-specific fields.

<ParamField body="tier" type="string" optional>
  Performance tier controlling the tradeoff between speed and cost. See [Performance Tiers](/performance-tiers) for details.

  Options: `radical_speed`, `radical_value`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed for reproducible generation. Use the same seed with identical
  parameters for consistent results.
</ParamField>

<ParamField body="width" type="integer">
  Output width in pixels. Send it together with `height`. The two fields take
  precedence over the standard `size` argument. Models priced per megapixel
  require `width` and `height`, or `size`. Range: 1-8192.
</ParamField>

<ParamField body="height" type="integer">
  Output height in pixels. Send it together with `width`. Models priced per
  megapixel require `width` and `height`, or `size`. Range: 1-8192.
</ParamField>

<Info>
  Sizing

  The examples on this page use `size` because it is the standard OpenAI argument and it works. Elsewhere in these docs you will see `width` and `height`, which are the preferred spelling. The API accepts either form and resolves both to the same dimensions. Pass them through `extra_body` if you want to match the rest of the platform.

  Models priced per megapixel need dimensions. The [pricing page](https://nunchux.ai/pricing) shows each model's unit. Today, every image model except Ideogram 4 is priced per megapixel. The OpenAI SDK sends no `size` unless you set it. On a per-megapixel model, a request with neither `size` nor `width` and `height` returns a 400.
</Info>

## Using Other SDK Format

Nothing about the API is Python-specific. The official [OpenAI Node SDK](https://github.com/openai/openai-node) works against the same base URL and the same key.

| | Python | Node | TypeScript |
| - | - | - | - |
| Base URL | `base_url` | `baseURL` | `baseURL` |
| API key | `api_key` | `apiKey` | `apiKey` |
| Methods | `client.images.generate()` | `client.images.generate()` | `client.images.generate()` |
| Nunchux params | `extra_body={...}` | inline in the request object | inline, assigned to a variable |
| Input image | `open("photo.jpg", "rb")` | a stream, or `toFile()` | a stream, or `toFile()` |

<Note>
  TypeScript

  TypeScript refuses undeclared properties in an object literal, but applies that check only to literals. Assign the parameters to a variable first. This rule is TypeScript excess property checking, not an API limit. See the [TypeScript handbook](https://www.typescriptlang.org/docs/handbook/2/objects.html#excess-property-checks) for the full rule.
</Note>

## Limitations

The API speaks the OpenAI image shape, but it is not OpenAI. Two differences matter when you port existing code:

1. `n` must be 1. One image per request. Any other value returns `400`. Send concurrent requests to generate a batch.
2. Errors do not use the OpenAI error shape. See [Error Handling](#error-handling) below.

## Error Handling

Two error shapes are in use. Most endpoints return `detail` and `request_id`. Migrated endpoints add a catalog envelope under `error`.

```jsonc theme={"system"}
// Rejecting n=4
{
  "detail": "only n=1 is currently supported for image requests, got n=4",
  "request_id": "9f3c1e2a4b5d4f6e8a7b9c0d1e2f3a4b"
}
```

On `/v1/images/generations`, a non-integer `n` also returns HTTP 400 with a plain `detail` string. The message text depends on the model. This example is from a per-megapixel model:

```jsonc theme={"system"}
// Rejecting n="not-a-number" on a per-megapixel model (HTTP 400)
{
  "detail": "n must be a positive integer for per-megapixel billing, got 'not-a-number'",
  "request_id": "9f3c1e2a4b5d4f6e8a7b9c0d1e2f3a4b"
}
```

Neither shape carries OpenAI's `type` or `param`, so `.type` and `.param` on the raised exception are always `None`. Branch on the HTTP status code, not on the error body. `request_id` is present on both shapes. Quote it when you contact support. It is how we find your request. See [Errors](/errors) for the full code catalog.

## Supported models

Every Nunchux Optimized image model works with the OpenAI SDK. See the [models table](/nunchux-optimized/overview#models) for the model IDs, and [Text-to-image](/nunchux-optimized/text-to-image) and [Image-to-image](/nunchux-optimized/image-to-image) for every request field.


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