---
title: "Create an image-to-video task"
description: "Animates an image into a video with PixAI's Tsubaki video model. The video starts on firstFrameMediaId and, when you send lastFrameMediaId, ends on it. The output keeps the first frame's aspect ratio."
canonical: "https://platform.pixai.art/en/docs/api-v2/video/createFrameVideo"
last-updated: "2026-11-02"
---

# Create an image-to-video task

Animates an image into a video with PixAI's Tsubaki video model. The video starts on `firstFrameMediaId` and, when you send `lastFrameMediaId`, ends on it. The output keeps the first frame's aspect ratio.



Frames are image media IDs: upload your own with `POST /v2/media/image/upload-url`, or reuse an image you generated. Media owned by another user is rejected.

Image-to-video needs a PixAI membership. Credits are charged when the task is created. Poll `GET /v2/task/{id}` for the result; a finished task's video is `outputs.videoMediaId`.

## POST https://api.pixai.art/v2/frame-video/create

Authentication: send your API key as `Authorization: Bearer <API key>`.

Machine-readable OpenAPI spec: https://platform.pixai.art/openapi-spec.v2.yaml

### Request body (`application/json`)

- `model` (string, required)
  The video model. `tbkv1.0.1` is the latest Tsubaki video model.
  Allowed values: `tbkv1.0.1`, `tbkv1.0`.
- `firstFrameMediaId` (string, required)
  Image media ID of the first frame.
- `lastFrameMediaId` (string, optional)
  Image media ID of the last frame. Send the first frame again to make a loop.
- `prompt` (string | null, optional)
  What should happen in the video.
  Default: `null`.
- `duration` (integer, optional)
  Length in whole seconds.
  Default: `5`.
  Range: 5 to 15.
- `mode` (string, optional)
  `professional` adds a 1080p upscale on `tbkv1.0.1` and costs more. It has no effect on `tbkv1.0`.
  Allowed values: `basic`, `professional`.
  Default: `"basic"`.
- `generateAudio` (boolean, optional)
  Whether to generate a soundtrack.
  Default: `true`.
- `audioLanguage` (string | null, optional)
  Language of speech in the soundtrack. `none` for no speech.
  Allowed values: `none`, `chinese`, `english`, `japanese`, `korean`, `null`.
  Default: `null`.

Example:

```json
{
  "model": "tbkv1.0.1",
  "firstFrameMediaId": "1943547603237249965",
  "prompt": "she turns around and smiles, hair blowing in the wind",
  "duration": 5
}
```

### Example (cURL)

```bash
curl -X POST https://api.pixai.art/v2/frame-video/create \
  -H "Authorization: Bearer $PIXAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tbkv1.0.1",
    "firstFrameMediaId": "1943547603237249965",
    "prompt": "she turns around and smiles, hair blowing in the wind",
    "duration": 5
  }'
```

### Responses

- `201`
  The task was created. Poll `GET /v2/task/{id}` with its `id`.
  Body fields:
  - `id` (string, required)
    The unique identifier for the task.
  - `status` (string, required)
    The current status of the task.
    Allowed values: `waiting`, `running`, `completed`, `cancelled`, `failed`.
  - `createdAt` (string, required)
    The time the task was created.
  - `updatedAt` (string, required)
    The time the task was last updated.
  - `startedAt` (string, optional)
    The time the task started running.
  - `endAt` (string, optional)
    The time the task finished.
  - `taskKind` (string, optional)
    What the task makes: `t2i` or `i2i` for images, `inpaint` for `POST /v2/gen-task/inpaint`, `i2v-inhouse` for `POST /v2/frame-video/create`, `reference-video` for `POST /v2/reference-video/create`.
  - `paidQuota` (integer, optional)
    Credits charged for the task.
  - `taskStatusMsgI18n` (object, optional)
    Why a `failed` task failed.
  - `taskStatusMsgI18n.key` (string, optional)
    A stable message key.
  - `taskStatusMsgI18n.defaultMessage` (string, optional)
    The message in English.
  - `outputs` (object, optional)
    The outputs produced by the task.
  - `outputs.videoMediaId` (string, optional)
    For video tasks, the media ID of the video. Resolve it with `GET /v2/media/batch?ids=<videoMediaId>` and download `fileUrl`. `mediaIds` then holds only the poster image.
  - `outputs.seed` (string, optional)
    The seed used, as a decimal string.
  - `outputs.mediaIds` (string[], optional)
    Media IDs of the generated images. Use these IDs to fetch detailed information about each generated image.

    Generated images are not permanently retained — retrieve them as soon as possible.
  - `outputs.mediaUrls` ((string | null)[], optional)
    Public URLs of the generated images.

    Generated images are not permanently retained — retrieve them as soon as possible. If an image is unavailable, its entry may be `null`.
- `400`
  - `INVALID_REFERENCE_MEDIA`: a frame is missing, is not an image, or belongs to another user. `data.code` is `invalid_input` or `media_not_owned`, and `data.mediaId` names the frame.
  - `BAD_REQUEST` with `data.issues`: the body failed validation.
- `401`
  `UNAUTHORIZED`: no API key was sent. An invalid, revoked or expired key answers `{"message": "invalid token", "code": 40100001}` instead, with a numeric `code`.
- `403`
  The account cannot run this task right now. `code` says why:

  - `INSUFFICIENT_BALANCE`: not enough credits for the task.
  - `WAITING_NUM_EXCEEDED`: too many of your tasks are still `waiting` (`data.currentWaitingTasks`). Wait for some to start before submitting more.
  - `REQUIRE_MEMBERSHIP`: the feature needs a PixAI membership (image-to-video).
  - `NSFW_PROMPTS_DETECTED`: the prompt was refused because the account is in safe mode.
- `500`
  `CREATION_FAILED`: the task could not be created. Retry with exponential backoff.
