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

# Wan 3.0 Video Pro LoRA API: 1080p, 2K & 4K Video

> Wan 3.0 Video Pro LoRA generation API with 1080p, 2K, and 4K text-to-video, image-to-video, and reference-to-video workflows

## Overview

Wan 3.0 Video Pro LoRA generates 1080p, 2K, or 4K videos from prompts, first-frame or first-and-last-frame images, and multimodal reference inputs. Use this page when you are ready to call the API after trying the model in the APIXO playground.

| Capability | Value |
| - | - |
| Model ID | `wan-3-0-video-pro-LoRA` |
| Modes | `text-to-video`, `image-to-video`, `reference-to-video` |
| Prompt | Required for `text-to-video`; optional for `image-to-video` and `reference-to-video` |
| Resolutions | `1080p`, `2k`, `4k` |
| Aspect ratios | `auto`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16` |
| Duration | `-1` for smart duration, or any integer from `2` through `30` seconds; defaults to `5` |
| Image-to-video images | 1-2 image URLs; the second image is the optional last frame |
| Reference inputs | Up to 10 image URLs, 5 video URLs, or 5 audio URLs |
| Result format | MP4 URL array in `resultJson.resultUrls` |

<Note>
  `wan-3-0-video-pro-LoRA` is the public model name. It does not accept custom LoRA configuration parameters.
</Note>

## Endpoint and authentication

Base URL:

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

| Method | Endpoint | Purpose |
| - | - | - |
| `POST` | `/generateTask/wan-3-0-video-pro-LoRA` | Submit a generation task |
| `GET` | `/statusTask/wan-3-0-video-pro-LoRA?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 4K text-to-video task and returns a `taskId`.

```bash theme={null}
curl -X POST "https://api.apixo.ai/api/v1/generateTask/wan-3-0-video-pro-LoRA" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "async",
    "input": {
      "mode": "text-to-video",
      "prompt": "a premium product launch film with elegant lighting and smooth camera motion",
      "resolution": "4k",
      "aspect_ratio": "16:9",
      "duration": 5,
      "sound": true
    }
  }'
```

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/wan-3-0-video-pro-LoRA?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": 1767965790929,
    "costTime": 180000
  }
}
```

Failed response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678",
    "state": "failed",
    "failCode": "UPSTREAM_ERROR",
    "failMsg": "Generation failed",
    "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 luxury watch rotates on black glass, crisp reflections, cinematic macro shot",
    "resolution": "4k",
    "aspect_ratio": "16:9",
    "duration": 5,
    "sound": true
  }
}
```

### Image-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "image-to-video",
    "prompt": "the portrait subtly smiles while the camera moves closer",
    "image_urls": [
      "https://example.com/first-frame.png",
      "https://example.com/last-frame.png"
    ],
    "resolution": "2k",
    "aspect_ratio": "auto",
    "duration": 5,
    "sound": true
  }
}
```

### Reference-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "reference-to-video",
    "prompt": "keep the subject identity and use the motion reference",
    "image_urls": [
      "https://example.com/person.png"
    ],
    "video_urls": [
      "https://example.com/motion-reference.mp4"
    ],
    "audio_urls": [
      "https://example.com/audio-reference.mp3"
    ],
    "resolution": "1080p",
    "aspect_ratio": "auto",
    "duration": -1,
    "sound": true
  }
}
```

## Parameters

<ParamField body="request_type" type="string" default="async">
  Result delivery mode. Supported values: `async`, `callback`. Use `async` for polling with `statusTask`, or use `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](/docs/api-reference/webhooks).
</ParamField>

<ParamField body="input" type="object" required>
  Wan 3.0 Video Pro LoRA input parameters.

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

    <ParamField body="prompt" type="string">
      Prompt text. Required for `text-to-video`; optional for `image-to-video` and `reference-to-video`. Required prompts cannot be empty after trimming. Maximum length: 20000 characters.
    </ParamField>

    <ParamField body="resolution" type="string" default="1080p">
      Output resolution tier. Supported values: `1080p`, `2k`, `4k`.
    </ParamField>

    <ParamField body="aspect_ratio" type="string" default="auto">
      Output aspect ratio. Supported values: `auto`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`. Use `auto` for automatic framing.
    </ParamField>

    <ParamField body="duration" type="integer|string" default="5">
      Output duration in seconds. Supports `-1` for smart duration, or integers from `2` through `30`, including numeric strings such as `"8"`. Decimal values such as `-1.0` are rejected.
    </ParamField>

    <ParamField body="sound" type="boolean" default="true">
      Whether the generated video should include audio. This does not change the price.
    </ParamField>

    <ParamField body="seed" type="integer|string">
      Optional random seed. Supported range: `0` to `2147483647`. Numeric strings are accepted; decimal values are rejected.
    </ParamField>

    <ParamField body="image_urls" type="string[]">
      Image URLs. Required for `image-to-video` with 1-2 images, where `image_urls[0]` is the first frame and `image_urls[1]` is the optional last frame. Optional for `reference-to-video` with up to 10 images. `text-to-video` does not accept image URLs.
    </ParamField>

    <ParamField body="video_urls" type="string[]">
      Reference video URLs for `reference-to-video`. Supports up to 5 URLs when provided. Each video must be 1-15 seconds, total reference video duration cannot exceed 15 seconds, and reference video seconds are billed at the same per-second rate as the selected `resolution`. `text-to-video` and `image-to-video` do not accept video URLs.
    </ParamField>

    <ParamField body="audio_urls" type="string[]">
      Reference audio URLs for `reference-to-video`. Supports up to 5 URLs when provided. Each audio file must be 1-15 seconds, and total reference audio duration cannot exceed 15 seconds. Audio is not billed separately. `text-to-video` and `image-to-video` do not accept audio URLs.
    </ParamField>
  </Expandable>
</ParamField>

| Mode | Required input | Unsupported media fields | Billing note |
| - | - | - | - |
| `text-to-video` | `prompt` | `image_urls`, `video_urls`, `audio_urls` | Output duration is billed per second. |
| `image-to-video` | `image_urls` with 1-2 images | `video_urls`, `audio_urls` | Output duration is billed per second. |
| `reference-to-video` | At least one of `image_urls`, `video_urls`, or `audio_urls` | None | Output duration and reference video seconds are billed per second. |

<Tip>
  Use public, directly accessible URLs for all media inputs. Video references should be common video files such as MP4, MOV, or M4V; audio references should be common audio files such as MP3, WAV, or M4A.
</Tip>

<Tip>
  When `duration` is positive and `video_urls` are provided, total reference video seconds plus `duration` cannot exceed 30 seconds. When `duration` is `-1`, the request uses smart duration and is pre-charged as input video seconds plus 30 output seconds.
</Tip>

## Response format

### Submit task response

`POST /generateTask/wan-3-0-video-pro-LoRA` 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>

<ResponseField name="billing" type="object">
  Final billing snapshot. Present only on successful terminal responses for `wan-3-0-video-pro-LoRA` tasks submitted with `duration=-1`.
</ResponseField>

<ResponseField name="billing.settlementState" type="string">
  Settlement status. For this final snapshot the value is always `final`.
</ResponseField>

<ResponseField name="billing.inputVideoSeconds" type="number">
  Total duration of all input videos, in seconds, rounded half up to 3 decimal places.
</ResponseField>

<ResponseField name="billing.outputVideoSeconds" type="number">
  Actual generated output video duration, in seconds, rounded half up to 3 decimal places.
</ResponseField>

<ResponseField name="billing.totalBillableSeconds" type="number">
  Final billable duration in seconds. This is always `inputVideoSeconds + outputVideoSeconds`.
</ResponseField>

<ResponseField name="billing.unit" type="string">
  Duration unit. The value is `second`.
</ResponseField>

<ResponseField name="billing.rounding" type="string">
  Rounding rule used for duration fields. The value is `round half up to 3 decimal places`.
</ResponseField>

<ResponseField name="billing.inputVideoCount" type="integer">
  Number of input videos included in `inputVideoSeconds`.
</ResponseField>

<ResponseField name="billing.outputVideoCount" type="integer">
  Number of output videos included in `outputVideoSeconds`.
</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/wan-3-0-video-pro-LoRA" \
  -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": "reference-to-video",
      "prompt": "create a polished product video using the references",
      "image_urls": [
        "https://example.com/ref.png"
      ],
      "resolution": "1080p",
      "aspect_ratio": "auto",
      "duration": -1,
      "sound": true
    }
  }'
```

The callback payload uses the same top-level shape as status polling with `code`, `message`, and `data`. Successful callbacks include the final `state` and `resultJson`. For `duration=-1` tasks, successful terminal callbacks include the same `data.billing` object returned by status polling. See [Webhooks](/docs/api-reference/webhooks) for delivery requirements and retry behavior.

## Billing

Wan 3.0 Video Pro LoRA is billed per second. Unit price depends on `resolution`; all supported modes share the same rate for a given resolution.

| Mode | Resolution | APIXO official price |
| - | - | - |
| `text-to-video` | `1080p` | `$0.1890 / second` |
| `text-to-video` | `2k` | `$0.2380 / second` |
| `text-to-video` | `4k` | `$0.3220 / second` |
| `image-to-video` | `1080p` | `$0.1890 / second` |
| `image-to-video` | `2k` | `$0.2380 / second` |
| `image-to-video` | `4k` | `$0.3220 / second` |
| `reference-to-video` | `1080p` | `$0.1890 / second` |
| `reference-to-video` | `2k` | `$0.2380 / second` |
| `reference-to-video` | `4k` | `$0.3220 / second` |

Billing formulas:

| Request | Formula |
| - | - |
| `text-to-video` or `image-to-video` with positive `duration` | `duration * unitPrice` |
| `reference-to-video` with positive `duration` | `(input video seconds + duration) * unitPrice` |
| Any mode with `duration = -1` | Pre-charge `(input video seconds + 30) * unitPrice`; after success, final billable seconds are `input video seconds + actual output seconds`, and any difference is refunded |

Input images and audio files do not add separate billable seconds.

Successful terminal `duration=-1` responses return the final settled seconds under `data.billing`:

```json theme={null}
{
  "billing": {
    "settlementState": "final",
    "inputVideoSeconds": 25.371,
    "outputVideoSeconds": 25.042,
    "totalBillableSeconds": 50.413,
    "unit": "second",
    "rounding": "round half up to 3 decimal places",
    "inputVideoCount": 1,
    "outputVideoCount": 1
  }
}
```

All duration fields in `billing` use seconds and are rounded half up to 3 decimal places. `inputVideoSeconds` is the sum of all input video durations, and `inputVideoCount` is the number of input videos included in that sum. `outputVideoSeconds` is the actual generated output duration. `totalBillableSeconds` is always `inputVideoSeconds + outputVideoSeconds`. Without input videos, `inputVideoSeconds` is `0.000` and `inputVideoCount` is `0`. This `billing` object appears only after successful final settlement, is also included in successful callback payloads, and remains stable on repeated polling.

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

## Latency and polling

Wan 3.0 Video Pro LoRA tasks are asynchronous. Actual latency may vary by prompt complexity, duration, reference media accessibility, resolution, route queue load, and provider-side processing time.

| Workload | Typical generation time | Recommended first poll | Poll interval |
| - | - | - | - |
| Text-to-video or image-to-video | Varies by prompt, resolution, and duration | 60s after task creation | 10s-15s |
| Reference-to-video with image, video, or audio inputs | Often longer than simple generation | 60s-90s after task creation | 10s-15s |

<Tip>
  For production workloads, use callback mode to avoid frequent polling while video tasks run.
</Tip>

Result URLs are temporary. Download and store important outputs promptly after task completion.

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, missing `input`, unsupported `mode`, missing required `prompt` or media, invalid `resolution`, invalid `aspect_ratio`, invalid `duration`, or invalid media array | 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 |
| `404` | Task not found when polling | Check the `taskId` |
| `429` | Rate limit or concurrency limit reached | Retry with exponential backoff |
| `500` | Server error or unknown task failure | Retry with backoff |
| `502` | Upstream 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 `mode` | Request fails before task creation. |
| Unsupported `mode` | Request fails before task creation. Supported values are `text-to-video`, `image-to-video`, and `reference-to-video`. |
| Missing `prompt` in `text-to-video` | Request fails before task creation. |
| Empty required `prompt` | Request fails before task creation. |
| Missing `resolution` | Defaults to `1080p`. |
| Unsupported `resolution` | Request fails before task creation. Supported values are `1080p`, `2k`, and `4k`. |
| Missing `aspect_ratio` | Defaults to `auto`. |
| Unsupported `aspect_ratio` | Request fails before task creation. Use `auto`, `16:9`, `4:3`, `1:1`, `3:4`, or `9:16`. |
| Missing `duration` | Defaults to `5`. |
| `duration` outside `-1` or `2` through `30`, or a decimal value | Request fails before task creation. |
| `image-to-video` without `image_urls` | Request fails before task creation. |
| `image-to-video` with more than 2 images | Request fails before task creation. |
| `reference-to-video` without any reference input | Request fails before task creation. |
| Reference video or audio shorter than 1 second or longer than 15 seconds | Request fails before task creation. |
| Total reference video duration or total reference audio duration over 15 seconds | Request fails before task creation. |
| Positive `duration` plus total reference video duration over 30 seconds | Request fails before task creation. |

### Task failure codes

`failCode` is generated from APIXO's mapped provider error. Common values include:

| Fail code | Meaning | What to do |
| - | - | - |
| `SensitiveContent` | Prompt or input/output content was rejected by safety checks | Change the prompt or reference media |
| `PromptInvalid` | Prompt was invalid or rejected by the provider | Rewrite the prompt and retry |
| `ImageFormatIncorrect` | Reference image format could not be processed | Use a public, direct image URL in a common image format |
| `RateLimited` | Provider-side rate limit was reached | Retry with exponential backoff |
| `Timeout` | Provider-side timeout | Retry later or use callback mode |
| `Unknown error` | The provider returned an unmapped failure | Retry with backoff or contact support with the `taskId` |

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

## Related links

* [Generation API Overview](/docs/models)
* [Wan 3.0 Video LoRA](/docs/models/video/wan-3-0-video-lora)


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