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.
Updated
/v1/ai/videocurl -X POST "https://api.orshot.com/v1/ai/video" \
-H "Authorization: Bearer <ORSHOT_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"prompt": "<PROMPT>",
"imageRef": "<IMAGE_REF>",
"lastImageRef": "<LAST_IMAGE_REF>",
"references": []
}'const res = 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": "<PROMPT>",
"imageRef": "<IMAGE_REF>",
"lastImageRef": "<LAST_IMAGE_REF>",
"references": []
}),
});
const data = await res.json();import requests
response = requests.post(
"https://api.orshot.com/v1/ai/video",
headers={"Authorization": "Bearer <ORSHOT_API_KEY>"},
json={
"prompt": "<PROMPT>",
"imageRef": "<IMAGE_REF>",
"lastImageRef": "<LAST_IMAGE_REF>",
"references": []
},
)
data = response.json()$ch = curl_init("https://api.orshot.com/v1/ai/video");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer <ORSHOT_API_KEY>",
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"prompt" => "<PROMPT>",
"imageRef" => "<IMAGE_REF>",
"lastImageRef" => "<LAST_IMAGE_REF>",
"references" => []
]));
$data = json_decode(curl_exec($ch), true);
curl_close($ch);require "net/http"
require "json"
uri = URI("https://api.orshot.com/v1/ai/video")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer <ORSHOT_API_KEY>"
req["Content-Type"] = "application/json"
req.body = {
"prompt": "<PROMPT>",
"imageRef": "<IMAGE_REF>",
"lastImageRef": "<LAST_IMAGE_REF>",
"references": []
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)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.
POST https://api.orshot.com/v1/ai/videoAsync by default: the response is a job. Poll Get a Render Job until finished is true, or pass webhook_url. Pass sync: true to wait up to 120 seconds in the same request.
Request Body#
promptStringWhat to generate. Optional when you only animate an image or make it speak.
imageRefStringReference image: the first frame to animate, or the portrait for speech. An https URL, a data URI, a brand asset reference like
brand:image:123, or agen://reference.lastImageRefStringReference image for the last frame of a transition.
referencesArrayExtra style or product images, same formats as
imageRef.scriptStringText the person should say. Runs through text to speech first (1 AI credit per 10 seconds).
voiceStringVoice id for the script. See the voice catalog on the audio endpoints.
audioStringYour own audio track instead of a script.
consentBooleanRequired for speech. Confirms you may use this person's likeness.
durationNumberAny whole number of seconds from 3 to 15, capped by your plan. Default 5. Speech follows the audio length.
presetStringRole preset id from List AI Presets. Default
cinematic-scene.lookStringLook preset id from List AI Presets.
aspectString1:1,16:9,9:16,4:3or3:4.fullHdBoolean1080p output at 2x credits.
freshBooleanSkip the cache and generate a new take.
syncBooleanWait for the result instead of returning a job (up to 120 seconds).
webhook_urlStringCalled with the job when it finishes.
Request#
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",
}),
});{
"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:
{
"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.
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. |
Ready to automate?
Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.
Get your API key- Image, PDF and video generation via API
- Visual editor with AI and smart layouts
- Zapier, Make, MCP and 50+ integrations
- White-label embed for your own app
- 30 free credits — no credit card required