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

# Sora 2 Pro

> OpenAI premium video generation API for text-to-video and image-to-video workflows

## Overview

Sora 2 Pro is an OpenAI video generation model for premium text-to-video and image-to-video workflows. Use this page when you are ready to call the API after trying the model in the APIXO playground.

| Capability                 | Value                                            |
| -------------------------- | ------------------------------------------------ |
| Model ID                   | `sora-2-pro`                                     |
| Modes                      | `text-to-video`, `image-to-video`                |
| Prompt length              | 1-5000 characters                                |
| Duration                   | `4`, `8`, or `12` seconds                        |
| Text-to-video sizes        | `720*1280`, `1280*720`, `1024*1792`, `1792*1024` |
| Image-to-video resolutions | `720p`, `1080p`                                  |
| Reference images           | 1 URL for `image-to-video`                       |
| Output format              | MP4 video URL in `resultJson.resultUrls`         |

## Endpoint and authentication

Base URL:

```text theme={null}
https://api.apixo.ai/api/v1
```

| Method | Endpoint                                 | Purpose                               |
| ------ | ---------------------------------------- | ------------------------------------- |
| `POST` | `/generateTask/sora-2-pro`               | Submit a generation task              |
| `GET`  | `/statusTask/sora-2-pro?taskId={taskId}` | Poll task status and retrieve results |

All requests require your APIXO API key:

```http theme={null}
Authorization: Bearer YOUR_API_KEY
```

Submit requests also require:

```http theme={null}
Content-Type: application/json
```

## Copy-paste async quickstart

This minimal request submits a text-to-video task and returns a `taskId`.

```bash theme={null}
curl -X POST "https://api.apixo.ai/api/v1/generateTask/sora-2-pro" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "async",
    "input": {
      "mode": "text-to-video",
      "prompt": "a cinematic tracking shot of a futuristic city with flying cars",
      "duration": 4,
      "size": "1280*720"
    }
  }'
```

Successful response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678"
  }
}
```

Save the `taskId`; you need it to poll for the final video.

## Poll for result

```bash theme={null}
curl -X GET "https://api.apixo.ai/api/v1/statusTask/sora-2-pro?taskId=task_12345678" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Processing response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678",
    "state": "processing",
    "createTime": 1767965610929
  }
}
```

Success response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678",
    "state": "success",
    "resultJson": "{\"resultUrls\":[\"https://file.apixo.ai/xxx.mp4\"]}",
    "createTime": 1767965610929,
    "completeTime": 1767965790929,
    "costTime": 180000
  }
}
```

Failed response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678",
    "state": "failed",
    "failCode": "PromptInvalid",
    "failMsg": "Prompt is invalid or rejected by upstream service",
    "createTime": 1767965610929,
    "completeTime": 1767965620132
  }
}
```

Parse `resultJson` after `state` becomes `success`:

```javascript theme={null}
const payload = JSON.parse(data.resultJson);
const videoUrls = payload.resultUrls;
```

## Request body

### Text-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "text-to-video",
    "prompt": "a cinematic tracking shot of a futuristic city with flying cars",
    "duration": 8,
    "size": "1280*720"
  }
}
```

### Image-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "image-to-video",
    "prompt": "make this image come alive with subtle camera motion",
    "duration": 4,
    "resolution": "1080p",
    "image_urls": [
      "https://example.com/reference-image.jpg"
    ]
  }
}
```

## Parameters

<ParamField body="request_type" type="string" required default="async">
  Result delivery mode. Use `async` for polling with `statusTask`, or `callback` for webhook delivery.
</ParamField>

<ParamField body="callback_url" type="string">
  Required when `request_type` is `callback`. Must be a public URL that can receive the final task payload. See [Webhooks](/docs/api-reference/webhooks).
</ParamField>

<ParamField body="input" type="object" required>
  Sora 2 Pro input parameters.

  <Expandable title="properties">
    <ParamField body="mode" type="string" required>
      Generation mode. Supported values: `text-to-video`, `image-to-video`.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      Text prompt describing the desired video. Supports 1-5000 characters.
    </ParamField>

    <ParamField body="duration" type="integer" required>
      Video duration in seconds. Supported values: `4`, `8`, `12`.
    </ParamField>

    <ParamField body="size" type="string">
      Required for `text-to-video`. Supported values: `720*1280`, `1280*720`, `1024*1792`, `1792*1024`.
    </ParamField>

    <ParamField body="resolution" type="string">
      Required for `image-to-video`. Supported values: `720p`, `1080p`.
    </ParamField>

    <ParamField body="image_urls" type="string[]">
      Required for `image-to-video`. Provide exactly 1 publicly accessible reference image URL.
    </ParamField>
  </Expandable>
</ParamField>

## Response format

### Submit task response

`POST /generateTask/sora-2-pro` returns a task ID when the task is accepted:

<ResponseField name="code" type="integer">
  API status code. `200` means the task was accepted.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable status message.
</ResponseField>

<ResponseField name="data.taskId" type="string">
  Unique task identifier used with the status endpoint.
</ResponseField>

### Status response fields

<ResponseField name="taskId" type="string">
  Unique task identifier.
</ResponseField>

<ResponseField name="state" type="string">
  Current task state: `pending`, `processing`, `success`, or `failed`.
</ResponseField>

<ResponseField name="resultJson" type="string">
  JSON string containing the generated video URLs. Present when `state` is `success`.
</ResponseField>

<ResponseField name="failCode" type="string">
  Machine-readable failure code. Present when `state` is `failed`.
</ResponseField>

<ResponseField name="failMsg" type="string">
  Human-readable failure message. Present when `state` is `failed`.
</ResponseField>

<ResponseField name="createTime" type="integer">
  Task creation timestamp in Unix milliseconds.
</ResponseField>

<ResponseField name="completeTime" type="integer">
  Task completion timestamp in Unix milliseconds. Present after completion.
</ResponseField>

<ResponseField name="costTime" type="integer">
  Processing duration in milliseconds. Present after successful completion.
</ResponseField>

## Webhook callback mode

Use callback mode when your backend should receive the final result automatically instead of polling.

```bash theme={null}
curl -X POST "https://api.apixo.ai/api/v1/generateTask/sora-2-pro" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "callback",
    "callback_url": "https://your-server.com/webhooks/apixo",
    "input": {
      "mode": "image-to-video",
      "prompt": "animate the scene with slow cinematic camera movement",
      "duration": 4,
      "resolution": "1080p",
      "image_urls": [
        "https://example.com/reference-image.jpg"
      ]
    }
  }'
```

See [Webhooks](/docs/api-reference/webhooks) for delivery requirements and retry behavior.

## Billing

Sora 2 Pro is billed per second. The selected output tier determines the per-second unit price, and the final task cost is:

```text theme={null}
unit price x duration
```

| Output tier | APIXO price      |
| ----------- | ---------------- |
| `720p`      | `$0.30 / second` |
| `1080p`     | `$0.50 / second` |

For `text-to-video`, `720*1280` and `1280*720` use the `720p` tier, while `1024*1792` and `1792*1024` use the `1080p` tier. For `image-to-video`, the `resolution` value selects the tier directly.

For current route and market comparison pricing, see [Pricing](https://apixo.ai/pricing).

## Latency and polling

Video generation usually takes longer than image generation. Actual latency may vary by prompt complexity, selected duration, output tier, route health, and current queue load.

| Duration     | Typical generation time | Recommended first poll   | Poll interval |
| ------------ | ----------------------- | ------------------------ | ------------- |
| `4` seconds  | 2-5 minutes             | 120s after task creation | 5-10s         |
| `8` seconds  | 2-5 minutes             | 120s after task creation | 5-10s         |
| `12` seconds | 3-6 minutes             | 120s after task creation | 5-10s         |

<Tip>
  For production workloads, use callback mode to avoid frequent polling during long video generations.
</Tip>

Rate limits and concurrency can vary by account, API key, and route. If you receive `429`, slow down requests and retry with backoff. For account-level details, see [System APIs](/docs/api-reference/system).

## Errors and troubleshooting

### HTTP errors

| Code  | Meaning                                                       | What to do                                       |
| ----- | ------------------------------------------------------------- | ------------------------------------------------ |
| `400` | Invalid request body, parameter, prompt, or image URL shape   | Fix the request before retrying                  |
| `401` | Missing or invalid API key                                    | Check the `Authorization` header                 |
| `402` | Insufficient balance or quota                                 | Add balance or switch account/key                |
| `403` | Key or route cannot access the model, or content was rejected | Check permissions and revise the prompt or input |
| `429` | Rate limit or concurrency limit reached                       | Retry with exponential backoff                   |
| `500` | Server error                                                  | Retry with backoff                               |
| `502` | Upstream service error                                        | Retry with backoff                               |
| `504` | Upstream timeout                                              | Retry or use callback mode for long-running jobs |

### Task failures

| Symptom                | Common cause                                                                | What to do                                                   |
| ---------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------ |
| Prompt rejected        | Prompt or image content was flagged by safety checks                        | Revise the prompt or use a different input image             |
| Missing parameter      | Required fields are absent for the selected `mode`                          | Check `duration`, `size`, `resolution`, and `image_urls`     |
| Invalid image          | The image URL cannot be fetched or decoded by the upstream service          | Use a public direct image URL                                |
| Timeout or no progress | The upstream job is slow or temporarily unavailable                         | Keep polling with backoff, retry later, or use callback mode |
| Insufficient balance   | The account does not have enough balance for the selected duration and tier | Add balance before retrying                                  |

### Practical checks

* `prompt` must be a non-empty string and must not exceed 5000 characters.
* `duration` is required and must be `4`, `8`, or `12`.
* `size` is required only for `text-to-video`.
* `resolution` and `image_urls` are required only for `image-to-video`.
* `image_urls` must contain exactly 1 image URL. Use JPG, PNG, or WebP when possible, and keep the image under 10 MB to reduce upstream rejections.

See [Error Codes](/docs/api-reference/errors) for the full error reference.

## Related links

* [Generation API Overview](/docs/models)
* [Generate Task](/docs/api-reference/generate-task)
* [Status Task](/docs/api-reference/status-task)
* [Webhooks](/docs/api-reference/webhooks)
* [Error Codes](/docs/api-reference/errors)
* [Parameter Specification](/docs/api-reference/parameters)
* [Routing Strategies](/docs/concepts/routing-strategies)
* [Pricing](https://apixo.ai/pricing)
