Video generation
POST /v1/videos/generations creates a video from a text description. The request is synchronous: the response arrives when the video is done, which usually takes a few minutes.
Request
| Field | Required | Notes |
|---|---|---|
model | yes | An ID of a video model. |
prompt | yes | Video description, up to 4,000 characters. |
duration_seconds | yes | Duration in seconds (alias duration). At most the model's max_duration_seconds, or 15 when the model does not state one. |
resolution | yes | One of the model's pricing.resolutions keys, for example 720P. The per-second price depends on it. |
n | no | Number of videos, default 1. The per-model limit is max_videos_per_request. |
aspect_ratio | no | For example 16:9 or 9:16. |
audio | no | true or false. |
duration_seconds and resolution are required so the cost always matches what you intend. Other fields such as image_url are not forwarded.
Examples
curl https://api.markas.ai.id/v1/videos/generations \
-H "Authorization: Bearer $MARKASAI_API_KEY" \
-H "Content-Type: application/json" \
--max-time 900 \
-d '{
"model": "VIDEO_MODEL_ID",
"prompt": "ocean waves at sunset",
"duration_seconds": 5,
"resolution": "720P",
"aspect_ratio": "16:9"
}'
import os, requests
resp = requests.post(
"https://api.markas.ai.id/v1/videos/generations",
headers={"Authorization": f"Bearer {os.environ['MARKASAI_API_KEY']}"},
json={
"model": "VIDEO_MODEL_ID",
"prompt": "ocean waves at sunset",
"duration_seconds": 5,
"resolution": "720P",
},
timeout=900,
)
resp.raise_for_status()
for video in resp.json()["videos"]:
print(video["url"])
const resp = await fetch("https://api.markas.ai.id/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MARKASAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "VIDEO_MODEL_ID",
prompt: "ocean waves at sunset",
duration_seconds: 5,
resolution: "720P",
}),
signal: AbortSignal.timeout(900_000),
});
if (!resp.ok) throw new Error(await resp.text());
const result = await resp.json();
console.log(result.videos.map((v) => v.url));
Response
{
"id": "vid_...",
"status": "completed",
"created": 1790000000,
"duration_seconds": 5,
"videos": [{"url": "https://...", "duration_seconds": 5}]
}
videos[].url is an HTTPS address on the provider's CDN. Download the video and keep it in your own storage.
Billing
n × duration × price per second (resolution)is held up front.- You are billed for the duration the provider reports, never more than you requested, times the per-second price.
- Failed requests are not billed. Disconnecting does not cancel generation: the video is still created and billed.
Timeouts and capacity
- Set a long client timeout (several minutes), as in the examples.
- The number of videos processed at once is limited. When full, requests get
503 overloadedwith aRetry-Afterheader.