REST API · v1

Generate your first video with the API.

Create an asynchronous faceless-video job, follow its status, and download the protected MP4 from a terminal script or server application.

API is currently enabled.

Start here

Four things to know before you send a request.

  1. 1

    API access is included with Creator ($9.99/month) and Pro ($14.99/month). Free and Basic plans do not include API access.

  2. 2

    Your account has one active key. It is displayed once, expires after 365 days, and regeneration immediately revokes the previous key.

  3. 3

    Store the key only in the server-side VIDIPROMPT_API_KEY environment variable. Never expose it in browser code, a URL, cookie, log, screenshot, or AI prompt.

  4. 4

    Dashboard and API generations use the same plan allowance and outstanding-job cap. Check GET /usage before creating work.

Base URL
https://vidiprompt.com/api/v1
Server environment
export VIDIPROMPT_API_KEY='paste-the-one-time-key-here'
Authentication
Authorization: Bearer $VIDIPROMPT_API_KEY
Generate or regenerate your key

Quickstart

One complete request-to-download flow.

Choose your language and run the complete server-side example. cURL uses only Bash, Python's standard library, and cURL; no VidiPrompt CLI is required.

  1. 1. Save your API key

    Store the one-time key in the VIDIPROMPT_API_KEY environment variable.

  2. 2. Check capabilities and usage

    Read the valid generation options and your shared monthly allowance before creating work.

  3. 3. Create a video

    POST your settings with a new Idempotency-Key and keep the 202 response.

  4. 4. Save the job URL

    Keep the response id and links.self value; video generation runs asynchronously.

  5. 5. Poll until terminal

    While queued or processing, wait for the latest Retry-After value before requesting links.self again.

  6. 6. Download the MP4

    When status is completed, make an authenticated request to links.download.

#!/usr/bin/env bash
set -euo pipefail

: "${VIDIPROMPT_API_KEY:?Set VIDIPROMPT_API_KEY before running this script}"
BASE_URL="https://vidiprompt.com/api/v1"
IDEMPOTENCY_KEY="$(python3 -c 'import uuid; print(uuid.uuid4())')"

curl --fail-with-body --silent --show-error \
  --request POST "$BASE_URL/videos" \
  --header "Authorization: Bearer $VIDIPROMPT_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $IDEMPOTENCY_KEY" \
  --data @- \
  --dump-header response.headers \
  --output video.json <<'JSON'
{
  "topic": "The emperor who erased his own brother from history",
  "video_mode": "darkHistory",
  "style_pack": "documentary",
  "voice": "warm-storyteller",
  "language": "en",
  "captions": {
    "style": "tiktok",
    "position": "center"
  }
}
JSON

VIDEO_ID="$(python3 -c 'import json; print(json.load(open("video.json"))["id"])')"
VIDEO_URL="$(python3 -c 'import json; print(json.load(open("video.json"))["links"]["self"])')"
printf 'Created video %s\n' "$VIDEO_ID"

while true; do
  curl --fail-with-body --silent --show-error \
    --header "Authorization: Bearer $VIDIPROMPT_API_KEY" \
    --dump-header response.headers \
    --output video.json \
    "$VIDEO_URL"

  STATUS="$(python3 -c 'import json; print(json.load(open("video.json"))["status"])')"
  printf 'Status: %s\n' "$STATUS"

  case "$STATUS" in
    completed) break ;;
    queued|processing)
      RETRY_AFTER="$(python3 -c 'import re; data=open("response.headers").read(); match=re.search(r"(?im)^Retry-After:\s*(\d+)", data); print(match.group(1) if match else 5)')"
      sleep "$RETRY_AFTER"
      ;;
    *)
      printf 'Video ended with status %s. See video.json for details.\n' "$STATUS" >&2
      exit 1
      ;;
  esac
done

DOWNLOAD_URL="$(python3 -c 'import json; print(json.load(open("video.json"))["links"]["download"])')"
curl --fail-with-body --location --continue-at - \
  --header "Authorization: Bearer $VIDIPROMPT_API_KEY" \
  --output "$VIDEO_ID.mp4" \
  "$DOWNLOAD_URL"

printf 'Saved %s.mp4\n' "$VIDEO_ID"

1. Save the accepted job

202 Accepted · Retry-After: 5
{
  "id": "123e4567-e89b-42d3-a456-426614174000",
  "object": "video",
  "status": "queued",
  "created_at": "2026-08-13T18:00:00.000Z",
  "queue": {
    "position": 2
  },
  "settings": {
    "video_mode": "darkHistory",
    "style_pack": "documentary",
    "voice": "warm-storyteller",
    "language": "en",
    "captions": {
      "style": "tiktok",
      "position": "center"
    }
  },
  "usage": {
    "used": 3,
    "reserved": 1,
    "remaining": 11,
    "limit": 15
  },
  "links": {
    "self": "https://vidiprompt.com/api/v1/videos/123e4567-e89b-42d3-a456-426614174000",
    "download": null
  }
}

Keep id and links.self. The usage object reflects the shared allowance after this job is reserved.

2. Download after completion

status: completed
{
  "id": "123e4567-e89b-42d3-a456-426614174000",
  "object": "video",
  "status": "completed",
  "source": "api",
  "created_at": "2026-08-13T18:00:00.000Z",
  "updated_at": "2026-08-13T18:04:00.000Z",
  "expires_at": "2026-08-20T18:00:00.000Z",
  "settings": {
    "video_mode": "darkHistory",
    "style_pack": "documentary",
    "voice": "warm-storyteller",
    "language": "en",
    "captions": {
      "style": "tiktok",
      "position": "center"
    }
  },
  "progress": {
    "percent": 100,
    "stage": "completed",
    "detail": "Complete!"
  },
  "output": {
    "duration_seconds": 42.5
  },
  "links": {
    "self": "https://vidiprompt.com/api/v1/videos/123e4567-e89b-42d3-a456-426614174000",
    "download": "https://vidiprompt.com/api/v1/videos/123e4567-e89b-42d3-a456-426614174000/download"
  }
}

Fetch links.download with the same Bearer header before expires_at. Completed outputs are retained for 7 days.

Job lifecycle

Create once, then follow the job.

Generation is asynchronous. The create response gives you the protected job URL to poll and, after completion, the protected download URL.

  1. Create

    POST /videos
  2. Waiting

    queued
  3. Generating

    processing
  4. Ready

    completed
  5. MP4

    Authenticated download
Other terminal states: failed, cancelled, and expired do not produce a downloadable file. Stop polling and handle the final status. API v1 does not expose a customer cancellation operation.

API reference

Six operations, one predictable resource.

All paths below are relative to https://vidiprompt.com/api/v1. Send the API key as a Bearer token on every request.

POST/videos

Create a video

Reserve quota and enqueue an asynchronous video generation job.

Input
Bearer auth, Content-Type: application/json, Idempotency-Key, and the create body.
Success
202 Accepted · Location, Retry-After, request ID, and rate-limit headers.
GET/videos/{video_id}

Retrieve a video

Read the current status, progress, settings, usage, and links for one job.

Input
Bearer auth and the video_id path value.
Success
200 OK · Retry-After while queued or processing, plus request ID and rate-limit headers.
GET/videos

List videos

List API and dashboard videos with cursor-based pagination.

Input
Bearer auth; optional limit (1–100), cursor, and exact status query values.
Success
200 OK · A stable list with has_more and an opaque next_cursor.
GET/usage

Retrieve usage

Read the shared plan allowance, reservations, remaining videos, and outstanding jobs.

Input
Bearer auth.
Success
200 OK · The current allowance window, source split, and outstanding-job cap.
GET/capabilities

Retrieve capabilities

Discover accepted modes, styles, voices, languages, captions, defaults, and limits.

Input
Bearer auth.
Success
200 OK · Current generation catalogs, defaults, limits, retention, and polling advice.
GET|HEAD/videos/{video_id}/download

Download a video

Download a completed MP4 with Bearer authentication and optional range requests.

Input
Bearer auth and video_id; optional single Range: bytes=... header.
Success
200 / 206 · Private video/mp4 with Content-Length, ETag, and range headers.

Create body

Unknown fields are rejected. The complete JSON body must be no larger than 32 KiB.

topicstring
Required.The video subject. Must contain 1–500 Unicode characters after trimming.
video_modestring
Narrative format ID. Use GET /capabilities for current values and the default.
style_packstring
Visual style ID. Use GET /capabilities for current values and the default.
voicestring
Narration voice ID. Use GET /capabilities for current values and the default.
languagestring
Narration language code. Use GET /capabilities for supported values.
captionsobject
Caption settings with style and position IDs returned by GET /capabilities.

Use live capabilities

Fetch GET /capabilities instead of hardcoding modes, styles, voices, languages, caption options, or defaults. Use the OpenAPI contract for exhaustive schemas.

{
  "topic": "The emperor who erased his own brother from history",
  "video_mode": "darkHistory",
  "style_pack": "documentary",
  "voice": "warm-storyteller",
  "language": "en",
  "captions": {
    "style": "tiktok",
    "position": "center"
  }
}

Errors and retries

Every important error has a next action.

Errors use an RFC 9457 application/problem+json body. Branch on the stable code, keep request_id for support, and use bounded backoff only when retrying is appropriate.

Example problem response

{
  "type": "https://vidiprompt.com/problems/quota-exceeded",
  "title": "Video allowance exhausted",
  "status": 403,
  "code": "quota_exceeded",
  "detail": "Your current video allowance is exhausted.",
  "instance": "/api/v1/videos",
  "request_id": "00000000-0000-4000-8000-000000000001"
}

Honor Retry-After on polling, 429, and retryable 503 responses. Do not blindly retry validation, permission, quota, conflict, or not-found errors.

CodeHTTPWhat to do
invalid_api_key401Check that the Bearer token is the current key and contains no spaces or quotes.
api_access_required403Use a Creator or Pro account, then generate a key from Account settings.
quota_exceeded403Wait for the plan allowance to reset or upgrade; dashboard and API usage share the same quota.
too_many_outstanding_jobs409Wait for an existing queued or processing job to finish before creating another.
idempotency_required400Send a unique Idempotency-Key header with every create request.
idempotency_conflict409The key was already used with different input. Retry with a new key.
rate_limited429Wait for Retry-After, then retry the same safe request.
video_not_ready409Poll links.self until the video is completed before downloading.
video_not_found404Check the video ID and key owner; expired or inaccessible videos are not returned.
service_unavailable503Wait briefly and retry with backoff. Reuse the same Idempotency-Key for the same create input.

Limits and security

The API uses your existing plan safely.

There is no separate API allowance. Limits and reservations are enforced atomically across dashboard and API generation.

Creator allowance

15 videos / month

2 outstanding jobs

Pro allowance

35 videos / month

5 outstanding jobs

Quota accounting

Shared

Dashboard and API generations use the same plan allowance.

Active keys

1 per account

Regenerating immediately revokes the previous key.

Key lifetime

365 days

Generate a replacement before the current key expires.

Video retention

7 days

Download completed MP4 files before expires_at.

Idempotency retention

24 hours

A repeated key and identical body return the original create result.

Keep the key on your server

Send it only as Authorization: Bearer $VIDIPROMPT_API_KEY. Never expose it in browser code, URLs, query strings, cookies, screenshots, logs, or AI prompts. VidiPrompt stores only a one-way hash, and regenerating the account's one active key immediately revokes the previous key.

AI integration

Give an AI the exact contract.

The full-docs action copies the same canonical Markdown served publicly, without your key, email, usage, or account identifiers. The integration prompt gives an AI a safe eight-step workflow.

Paste the copied material into your AI assistant, then provide your application requirements separately. Never paste the API key itself.