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

# InfiniteTalk API

> Audio-driven talking avatar video generation from a portrait and audio

## Overview

InfiniteTalk turns a source portrait plus an audio track into a talking or singing avatar video with lip synchronization. Use this page when you are ready to call the API after trying the model in the APIXO playground.

| Capability    | Value                                                |
| ------------- | ---------------------------------------------------- |
| Model ID      | `infinitetalk`                                       |
| Mode          | `image-to-video`                                     |
| Source images | 1 required image URL, plus 1 optional mask image URL |
| Audio input   | Exactly 1 public HTTP(S) MP3, WAV, or M4A URL        |
| Audio limits  | Up to 128 MB and 600 seconds                         |
| Resolutions   | `480p`, `720p`                                       |
| Billing       | Per probed audio second, minimum 5 seconds           |

## Endpoint and authentication

Base URL:

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

| Method | Endpoint                                   | Purpose                               |
| ------ | ------------------------------------------ | ------------------------------------- |
| `POST` | `/generateTask/infinitetalk`               | Submit a generation task              |
| `GET`  | `/statusTask/infinitetalk?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 an InfiniteTalk task and returns a `taskId`.

```bash theme={null}
curl -X POST "https://api.apixo.ai/api/v1/generateTask/infinitetalk" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "async",
    "input": {
      "mode": "image-to-video",
      "image_urls": [
        "https://example.com/portrait.png"
      ],
      "audio_urls": [
        "https://example.com/voice.mp3"
      ],
      "prompt": "make the portrait speak naturally with subtle head motion",
      "resolution": "480p",
      "seed": -1
    }
  }'
```

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/infinitetalk?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": 1767965652317,
    "costTime": 41388
  }
}
```

Failed response:

```json theme={null}
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_12345678",
    "state": "failed",
    "failCode": "SensitiveContent",
    "failMsg": "Content violates safety policy, please adjust the prompt",
    "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

### Image-to-video

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "image-to-video",
    "image_urls": [
      "https://example.com/portrait.png"
    ],
    "audio_urls": [
      "https://example.com/voice.m4a"
    ],
    "prompt": "keep the face stable while syncing lips to the audio",
    "resolution": "480p",
    "seed": -1
  }
}
```

### With an optional mask image

```json theme={null}
{
  "request_type": "async",
  "input": {
    "mode": "image-to-video",
    "image_urls": [
      "https://example.com/portrait.png",
      "https://example.com/mask.png"
    ],
    "audio_urls": [
      "https://example.com/voice.wav"
    ],
    "prompt": "subtle head motion, natural eye movement",
    "resolution": "720p",
    "seed": 7
  }
}
```

`image_urls[0]` is sent as the source image. `image_urls[1]`, when provided, is sent as the mask image.

## 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`. Use a public endpoint that can receive the final task payload. See [Webhooks](/docs/api-reference/webhooks).
</ParamField>

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

  <Expandable title="properties">
    <ParamField body="mode" type="string" required>
      Generation mode. Only `image-to-video` is supported.
    </ParamField>

    <ParamField body="image_urls" type="string[]" required>
      Image URLs. Supports 1 or 2 URLs. The first URL is the source portrait; the optional second URL is forwarded as `mask_image`.
    </ParamField>

    <ParamField body="audio_urls" type="string[]" required>
      Audio URL list. Must contain exactly 1 public HTTP(S) URL. The audio must be MP3, WAV, or M4A, up to 128 MB, and no longer than 600 seconds.
    </ParamField>

    <ParamField body="prompt" type="string">
      Optional prompt for expression, motion, or scene guidance. If provided, it must be a non-empty string.
    </ParamField>

    <ParamField body="resolution" type="string" default="480p">
      Output resolution. Supported values: `480p`, `720p`. Values are normalized to lowercase.
    </ParamField>

    <ParamField body="seed" type="integer" default="-1">
      Random seed. Use `-1` for random output, or an integer from `0` to `2147483647` for reproducible generation.
    </ParamField>
  </Expandable>
</ParamField>

## Response format

### Submit task response

`POST /generateTask/infinitetalk` 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 as `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 time in milliseconds. Present after successful completion when 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/infinitetalk" \
  -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",
      "image_urls": [
        "https://example.com/portrait.png"
      ],
      "audio_urls": [
        "https://example.com/voice.mp3"
      ],
      "prompt": "natural speech with subtle head movement",
      "resolution": "720p",
      "seed": -1
    }
  }'
```

Callback payloads use the same `code`, `message`, and `data` shape as the status response. See [Webhooks](/docs/api-reference/webhooks) for delivery requirements and retry behavior.

## Billing

InfiniteTalk is billed per probed audio second. The backend downloads the audio, probes its real audio length, then bills:

```text theme={null}
billableSeconds = max(5, actualAudioSeconds)
totalCost = billableSeconds * resolutionUnitPrice
```

| Resolution | APIXO price      |
| ---------- | ---------------- |
| `480p`     | `$0.03 / second` |
| `720p`     | `$0.06 / second` |

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

## Latency and polling

Actual latency varies by audio length, selected resolution, upstream queue load, and final result storage. Longer audio generally takes longer to complete.

| Audio length | Recommended first poll   | Poll interval |
| ------------ | ------------------------ | ------------- |
| Up to 30s    | 30s after task creation  | 10s-15s       |
| 30s-120s     | 60s after task creation  | 15s-30s       |
| 120s-600s    | 120s after task creation | 30s           |

<Tip>
  For production workloads, especially long audio, use callback mode to avoid frequent polling.
</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, unsupported mode, invalid parameter type or value, unreachable URL, or audio probe failure | 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 unmapped upstream failure                                                                        | Retry with backoff                               |
| `502` | Upstream service error                                                                                           | Retry with backoff                               |
| `504` | Upstream timeout                                                                                                 | Retry or use callback mode for long-running jobs |

### Common validation issues

| Issue                          | What happened                                        | What to do                                              |
| ------------------------------ | ---------------------------------------------------- | ------------------------------------------------------- |
| Missing `input.mode`           | InfiniteTalk requires `image-to-video` mode          | Set `input.mode` to `image-to-video`                    |
| Invalid `image_urls` length    | The backend accepts 1 or 2 image URLs                | Send the portrait URL first, then the optional mask URL |
| Invalid `audio_urls` length    | The backend accepts exactly 1 audio URL              | Send a single MP3, WAV, or M4A URL                      |
| Audio cannot be fetched        | The backend must fetch the audio before billing      | Use a public HTTP(S) direct URL                         |
| Audio is too large or too long | Audio is limited to 128 MB and 600 seconds           | Shorten or compress the audio                           |
| Empty prompt                   | `prompt` is optional, but cannot be blank if present | Remove the field or send a non-empty string             |
| Invalid seed                   | `seed` must be an integer from `-1` to `2147483647`  | Use `-1` or a valid integer                             |

### Task failure codes

| Fail code                          | Meaning                                                  | What to do                                              |
| ---------------------------------- | -------------------------------------------------------- | ------------------------------------------------------- |
| `SensitiveContent`                 | Upstream rejected the prompt or media for safety reasons | Change the prompt, source image, or audio               |
| `PromptInvalid`                    | Upstream rejected or could not use the prompt            | Simplify the prompt and retry                           |
| `RateLimited`                      | Upstream rate limited the task                           | Retry with backoff                                      |
| `Timeout`                          | Upstream timed out                                       | Retry, reduce input complexity, or use callback mode    |
| `MissingParameter` or `BadRequest` | Upstream reported a malformed request                    | Recheck the request body                                |
| `Unknown error`                    | Failure could not be mapped to a known code              | 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)
* [Video Models](/docs/models/video)
* [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)
* [Try InfiniteTalk in the APIXO Playground](https://apixo.ai/models/infinitetalk)
* [Pricing](https://apixo.ai/pricing)
