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

FieldRequiredNotes
modelyesAn ID of a video model.
promptyesVideo description, up to 4,000 characters.
duration_secondsyesDuration in seconds (alias duration). At most the model's max_duration_seconds, or 15 when the model does not state one.
resolutionyesOne of the model's pricing.resolutions keys, for example 720P. The per-second price depends on it.
nnoNumber of videos, default 1. The per-model limit is max_videos_per_request.
aspect_rationoFor example 16:9 or 9:16.
audionotrue 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

200 OK
{
  "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 overloaded with a Retry-After header.