# Make a video from an image

> Turn a finished image into a short video, describing the movement you want while everything keeps the look it already has. Delivered as one `video/mp4` file.

**Endpoint:** `POST https://api.refabric.com/v1/tasks/video.generate` · **Task:** `video.generate` · **Scope:** `tasks:run` · **Category:** Video

Send a finished image and describe the movement you want; you get a short video in which everything keeps the look it already has. Pick its length with `duration` and how it is rendered with `quality`, and send other angles of the same garment in `references` when the video should show more of it.

## Quick start

```python
import os
import time
import requests

headers = {"Authorization": f"Key {os.environ['REFABRIC_API_KEY']}"}

job = requests.post(
    "https://api.refabric.com/v1/tasks/video.generate",
    headers=headers,
    json={
        "image": "art:9f2c01",
        "prompt": "she turns towards the camera and smiles",
    },
).json()
print(job["job_id"])

while True:
    status = requests.get(job["status_url"], headers=headers).json()
    if status["lifecycle"] == "terminal":
        break
    time.sleep(5)

print(requests.get(job["result_url"], headers=headers).json())
```

```javascript
const headers = {
  Authorization: `Key ${process.env.REFABRIC_API_KEY}`,
  "Content-Type": "application/json",
};

const job = await fetch("https://api.refabric.com/v1/tasks/video.generate", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "image": "art:9f2c01",
    "prompt": "she turns towards the camera and smiles"
  }),
}).then((r) => r.json());
console.log(job.job_id);

let status = job;
while (status.lifecycle !== "terminal") {
  await new Promise((r) => setTimeout(r, 5000));
  status = await fetch(job.status_url, { headers }).then((r) => r.json());
}

console.log(await fetch(job.result_url, { headers }).then((r) => r.json()));
```

```bash
curl -X POST "https://api.refabric.com/v1/tasks/video.generate" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{"image":"art:9f2c01","prompt":"she turns towards the camera and smiles"}'
```

## Input schema

- `prompt` (string, _required_) — What happens in the video ('she turns towards the camera and smiles'). Required and not blank; describe movement — the image already says what everything looks like.
  Example: `she turns towards the camera and smiles`
- `image` (string, _required_, pattern: ^(https://|art:|file:).+$) — The finished image to animate; it is the video's first frame. As one string: a URL, a file from an earlier result (`art:…` or its url) or an upload (`file:…`). If it is one of your files placed in a project or on a design in the Refabric app, the result is filed there too.
  Example: `art:9f2c01`
- `duration` (string, _optional_, default: `4`) — How long the video is, in seconds. A video with `references` is always 8 seconds long. With nothing sent the video is 4 seconds long; send `8` for a longer clip.
  Values: `4` (Four seconds.); `8` (Eight seconds. When the motion needs more time, such as a full turn or a longer walk.)
  Example: `8`
- `quality` (string, _optional_, default: `standard`) — How carefully the video is rendered. With nothing sent you get `standard`, the faster of the two renderings, which suits previews and most videos; ask for `premium` when the video is final work.
  Values: `standard` (Made quickly; right for previews and most uses.); `premium` (Rendered with more care. Takes longer. When the video is final work and detail matters more than speed.)
  Example: `standard`
- `references` (array<object>, _optional_, at most 3 items) — Up to 3 other angles of the same garment, each `{image}`. Sending any makes the video from the image and these angles together, and it is then always 8 seconds long.
  - `image` (string, _required_, pattern: ^(https://|art:|file:).+$) — A picture, as one string: a URL, a file from an earlier result (`art:…`, or its `url`) or an upload (`file:…`).

## Required-fields example

```json
{
  "image": "art:9f2c01",
  "prompt": "she turns towards the camera and smiles"
}
```

## Full example

```json
{
  "image": "art:9f2c01",
  "prompt": "she turns towards the camera and smiles",
  "duration": "8",
  "quality": "standard"
}
```

## Output schema

- `files` (array<object>, _optional_) — One `video/mp4` file.

## Response example

```json
{
  "job_id": "d2b3c4d5000040008000000000000010",
  "lifecycle": "queued",
  "status_url": "http://v3-api.refabric.com/v1/jobs/d2b3c4d5000040008000000000000010",
  "result_url": "http://v3-api.refabric.com/v1/jobs/d2b3c4d5000040008000000000000010/result",
  "cancel_url": "http://v3-api.refabric.com/v1/jobs/d2b3c4d5000040008000000000000010/cancel"
}
```

## Result example

```json
{
  "job_id": "d2b3c4d5000040008000000000000010",
  "files": [
    {
      "file": "art:9f2c0a",
      "url": "https://files.example.com/video.generate/1.mp4",
      "media_type": "video/mp4",
      "task": "video.generate",
      "job_id": "d2b3c4d5000040008000000000000010",
      "created_at": "2026-10-01T09:52:47Z"
    }
  ],
  "has_more": false
}
```

`duration` and `quality` take the values their fields list in the input schema. With `references[{image}]` (up to the schema's `maxItems`) the video takes the longer `duration`.

## Built for

- A product page video from a shoot image
- Short clips for social posts
- A garment shown turning or walking

## What you get

- One `video/mp4` file of the movement you described.

## Prompting

Describe movement, not looks: what the person or the garment does ('she turns towards the camera and smiles'). The image already says what everything looks like.

## Specs

- **Input formats:** Images, each one string: a URL, an upload (`file:…`) or a file from an earlier result (`art:…`). Upload types and sizes: `GET /v1/meta` `limits.upload`.
- **Input count:** `image`: one; `references`: up to 3, each with its image
- **Output format:** Files: each one line with its `url` and its `media_type`, in the job's result.
- **Outputs per job:** One video file per job.

## Errors

- `field_not_accepted`
- `invalid_request`
- `not_found`
- `permission_denied`
- `insufficient_credits`
- `content_refused`
- `processing_failed`
- `invalid_option`
- `too_many_references`

## Related

- `photoshoot.create` — It runs before: its result is this input.
- `mannequin_photoshoot.create` — It runs before: its result is this input.
- `image.change_background` — It runs before: its result is this input.

## Good to know

- `references` holds at most 3 items.

## For agents and code generation

- https://api.refabric.com/v1/tasks/video.generate/llms.txt
- https://api.refabric.com/v1/tasks/video.generate/openapi.json
- GET https://api.refabric.com/v1/tasks/video.generate
