# Generate an AI Video

> Generate a short clip from a prompt, animate an image, or make a photo speak. Billed in AI credits per second; returns a job to poll.

- **URL**: https://orshot.com/docs/api-reference/ai-video-generate

---

Generate a video clip with AI. What you send decides what runs: a `prompt` alone gives footage from text, `prompt` + `imageRef` animates the image, `imageRef` + `lastImageRef` makes a transition, and `imageRef` + `script` makes the person in the photo speak. Every clip is saved to your Brand Library and listed in AI usage logs. The full guide is at [AI video](https://orshot.com/docs/video-generation/ai-video).

```markdown tab="Endpoint"
POST https://api.orshot.com/v1/ai/video
```

Async by default: the response is a [job](https://orshot.com/docs/api-reference/async-render-start#the-job-object). Poll [Get a Render Job](https://orshot.com/docs/api-reference/async-render-job-get) until `finished` is `true`, or pass `webhook_url`. Pass `sync: true` to wait up to 120 seconds in the same request.

## Request Body

## Request

**Request**
```js {8-12}
await fetch("https://api.orshot.com/v1/ai/video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    prompt: "a ceramic coffee cup on a wooden table by a window, morning light",
    duration: 5,
    preset: "product-hero",
    look: "clean-studio",
    aspect: "9:16",
  }),
});
```

**Response**
```json
{
  "id": 89,
  "status": "queued",
  "finished": false,
  "created_at": "2026-09-08T10:30:00.000Z",
  "self": "https://api.orshot.com/v1/studio/render-jobs/89"
}
```

Once the job succeeds, `result.data` holds the clip:

```json
{
  "url": "https://storage.orshot.com/generated/video/0472d0….mp4",
  "thumbnailUrl": "https://storage.orshot.com/generated/video/0472d0….jpg",
  "ref": "gen://0472d0…",
  "seconds": 5,
  "width": 768,
  "height": 1344,
  "creditsUsed": 15,
  "cached": false,
  "videoId": 151
}
```

## Credits

HD clips are 3 AI credits per second, Full HD 6, with a 3 second minimum. Nothing is charged for a failed generation, and a request identical to an earlier one is served from cache for free. Check the cost first with [Estimate AI Video Credits](https://orshot.com/docs/api-reference/ai-video-estimate).

## Errors

| Code | Meaning |
| ---- | ------- |
| `ai-media-no-input` | Nothing usable was sent. Give a prompt, an image, or a photo plus a script. |
| `ai-credits-insufficient` | Not enough AI credits. Top up or upgrade. |
| `ai-daily-cap` | The workspace's daily AI generation cap is reached (429). Resets at midnight UTC; do not retry until then. |
| `ai-video-not-on-plan` | AI video is not included in the plan. |
| `ai-speech-consent-required` | Speech needs `consent: true`. |
| `ai-speech-not-on-plan` | Speech needs a paid plan. |
| `ai-speech-too-long` | The script or audio runs past the plan's speech cap (`plan.ai_credits.video.max_speech_seconds`). Nothing was charged. |
| `ai-unknown-preset`, `ai-unknown-look`, `ai-invalid-aspect` | An id that is not in `GET /v1/ai/presets`, or an aspect outside `1:1, 16:9, 9:16, 4:3, 3:4`. |
| `ai-prompt-too-long`, `ai-script-too-long` | Over 2,000 characters. |
| `invalid-media-ref`, `invalid-data-uri`, `input-too-large`, `asset-not-found` | A media value that is not an https URL, an image/audio/video data URI under 25 MB, a brand asset in this workspace, or a `gen://` reference. |
| `ai-media-rejected` | The provider refused the inputs, for example a photo with no face. Nothing was charged. |
| `ai-media-provider-down` | All providers failed. Nothing was charged. Retry later. |
| `ai-video-unavailable` | No generation provider is configured on this server. |
| `ai-media-busy` | The same clip is already being generated; wait for it instead of resending. |
| `too-many-active-jobs` | The workspace has too many queued or running jobs; wait for some to finish. |
| `generation-timeout` | The job ran past 30 minutes and was closed. Retry; contact support with the job id if it repeats. |