> ## 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.

# Hailuo 2.3

> Hailuo 2.3 video generation API for standard and pro text-to-video and image-to-video workflows

## Overview

Hailuo 2.3 generates videos from text prompts or a single first-frame image. Use this page when you are ready to call the API after trying the model in the APIXO playground.

| Capability        | Value                                                                                          |
| ----------------- | ---------------------------------------------------------------------------------------------- |
| Model ID          | `hailuo-2-3`                                                                                   |
| Modes             | `standard-text-to-video`, `standard-image-to-video`, `pro-text-to-video`, `pro-image-to-video` |
| Prompt            | Non-empty string                                                                               |
| Reference images  | Exactly 1 URL for image-to-video modes                                                         |
| Output resolution | Standard modes: `768p`; pro modes: `1080p`                                                     |
| Output duration   | Standard modes: `6` or `10` seconds; pro modes: fixed `5` seconds                              |
| Result format     | MP4 URL array in `resultJson.resultUrls`                                                       |

## Endpoint and authentication

Base URL:

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

| Method | Endpoint                                 | Purpose                               |
| ------ | ---------------------------------------- | ------------------------------------- |
| `POST` | `/generateTask/hailuo-2-3`               | Submit a generation task              |
| `GET`  | `/statusTask/hailuo-2-3?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 standard text-to-video task and returns a `taskId`.

```bash theme={null}
curl -X POST "https://api.apixo.ai/api/v1/generateTask/hailuo-2-3" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "async",
    "input": {
      "mode": "standard-text-to-video",
      "prompt": "a dramatic sunrise over a futuristic skyline with slow cinematic camera movement",
      "duration": 6
    }
  }'
```

Successful response:

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

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

## Poll for result

```bash theme={null}
curl -X GET "https://api.apixo.ai/api/v1/statusTask/hailuo-2-3?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/video.mp4\"]}",
    "createTime": 1767965610929,
    "completeTime": 1767965730929,
    "costTime": 120000
  }
}
```

Failed response:

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

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

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

## Request body

### Standard text-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "standard-text-to-video",
    "prompt": "a dramatic sunrise over a futuristic skyline with slow cinematic camera movement",
    "duration": 6
  }
}
```

### Standard image-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "standard-image-to-video",
    "prompt": "make this still image move naturally with cinematic camera motion",
    "image_urls": [
      "https://example.com/input.jpg"
    ],
    "duration": 10
  }
}
```

### Pro text-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "pro-text-to-video",
    "prompt": "a premium commercial shot of a glass perfume bottle with elegant camera movement"
  }
}
```

### Pro image-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "pro-image-to-video",
    "prompt": "smoothly animate this image with a subtle camera push-in and natural lighting variation",
    "image_urls": [
      "https://example.com/input.jpg"
    ]
  }
}
```

## Parameters

<ParamField body="request_type" type="string" 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 HTTPS URL that can receive the final task payload. See [Webhooks](/api-reference/webhooks).
</ParamField>

<ParamField body="input" type="object" required>
  Hailuo 2.3 input parameters.

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

    <ParamField body="prompt" type="string" required>
      Text prompt describing the video. The backend requires a non-empty string.
    </ParamField>

    <ParamField body="image_urls" type="string[]">
      Required for `standard-image-to-video` and `pro-image-to-video`. The backend requires exactly 1 non-empty image URL. Text-to-video modes ignore this field.
    </ParamField>

    <ParamField body="duration" type="integer|string">
      Required for standard modes. Supported values: `6`, `10`, `"6"`, or `"10"`. Pro modes have a fixed 5-second output and ignore `duration` if it is present.
    </ParamField>
  </Expandable>
</ParamField>

| Mode                      | Required media      | `duration` behavior           | Output                       |
| ------------------------- | ------------------- | ----------------------------- | ---------------------------- |
| `standard-text-to-video`  | None                | Required: `6` or `10` seconds | `768p` video                 |
| `standard-image-to-video` | Exactly 1 image URL | Required: `6` or `10` seconds | `768p` video                 |
| `pro-text-to-video`       | None                | Ignored                       | Fixed 5-second `1080p` video |
| `pro-image-to-video`      | Exactly 1 image URL | Ignored                       | Fixed 5-second `1080p` video |

<Tip>
  Image-to-video uses the provided image as the first frame. Use a direct JPG, JPEG, or PNG URL; upstream validation may reject images over 20MB, images whose short side is 300px or smaller, or images outside the 2:5 to 5:2 aspect-ratio range.
</Tip>

## Response format

### Submit task response

`POST /generateTask/hailuo-2-3` 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: `processing`, `success`, or `failed`.
</ResponseField>

<ResponseField name="resultJson" type="string">
  JSON string containing generated video URLs in `resultUrls`. 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 completion when timing data is available.
</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/hailuo-2-3" \
  -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": "pro-image-to-video",
      "prompt": "animate this product image with a clean studio camera move",
      "image_urls": [
        "https://example.com/product.jpg"
      ]
    }
  }'
```

The callback payload mirrors the final status response shape with `code`, `message`, and `data`. See [Webhooks](/api-reference/webhooks) for delivery requirements and retry behavior.

## Billing

Hailuo 2.3 billing depends on the selected mode family.

| Mode family    | APIXO price       | Billing rule               | Example charge                 |
| -------------- | ----------------- | -------------------------- | ------------------------------ |
| Standard modes | `$0.056 / second` | `duration * $0.056`        | 6s: `$0.336`; 10s: `$0.56`     |
| Pro modes      | `$0.49 / use`     | Fixed price per generation | Fixed 5-second output: `$0.49` |

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

## Latency and polling

Actual latency may vary by prompt complexity, image accessibility, mode, provider queue load, and upstream processing time. The status response reports `costTime` in milliseconds after completion when timing data is available.

| Mode family    | Output duration | Recommended first poll      | Poll interval |
| -------------- | --------------- | --------------------------- | ------------- |
| Standard modes | 6s or 10s       | 30s after task creation     | 10s-15s       |
| Pro modes      | Fixed 5s        | 45s-60s after task creation | 10s-15s       |

<Tip>
  For high-concurrency production workloads, use callback mode to avoid frequent polling on long-running video tasks.
</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](/api-reference/system).

## Errors and troubleshooting

### HTTP errors

| Code  | Meaning                                                                                                   | What to do                                       |
| ----- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `400` | Invalid request body, missing `input`, unsupported `mode`, invalid `duration`, or invalid 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                                                                      | Check permissions and route strategy             |
| `429` | Rate limit or concurrency limit reached                                                                   | Retry with exponential backoff                   |
| `500` | Server error or unknown upstream failure                                                                  | Retry with backoff                               |
| `502` | Upstream provider error                                                                                   | Retry with backoff                               |
| `504` | Upstream timeout                                                                                          | Retry or use callback mode for long-running jobs |

### Validation notes

| Condition                                          | Backend behavior                   |
| -------------------------------------------------- | ---------------------------------- |
| Missing `input`                                    | Request fails before task creation |
| Missing or empty `prompt`                          | Request fails before task creation |
| Unsupported `mode`                                 | Request fails before task creation |
| Image mode without `image_urls`                    | Request fails before task creation |
| `image_urls` contains 0 or more than 1 item        | Request fails before task creation |
| Standard mode without `duration`                   | Request fails before task creation |
| Standard mode with duration other than `6` or `10` | Request fails before task creation |
| Pro mode with `duration`                           | `duration` is ignored              |

### Task failure codes

| Fail code                                                  | Meaning                                              | What to do                                                                       |
| ---------------------------------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------- |
| `PromptInvalid`                                            | Prompt was rejected or malformed                     | Adjust the prompt and retry                                                      |
| `SensitiveContent` / `InputOutputSensitiveContentDetected` | Prompt, input image, or output failed content checks | Change the prompt or input image                                                 |
| `ImageFormatIncorrect` / `InvalidImageSize`                | Input image failed upstream image validation         | Use a public JPG/JPEG/PNG URL within the documented size and aspect-ratio limits |
| `RateLimited`                                              | Provider-side rate limit                             | Retry with exponential backoff                                                   |
| `Timeout`                                                  | Provider-side timeout                                | Retry, simplify the request, or use callback mode                                |
| `Unknown error`                                            | Provider returned an unmapped failure                | Retry with backoff or contact support with the `taskId`                          |

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

## Related links

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