Open docs navigation
JSON to Video API
JSON in, video out with docs, webhooks and pricing
If you searched for json to video or json to video api, this page is the practical answer: send a JSON payload, render asynchronously, track progress, and route the output into your own app, n8n workflow, or publishing pipeline. Every endpoint below works with your SamAutomation API key.
Quickstart
See the first request
Get the curl flow from JSON payload to finished render.
Tracking
Understand async jobs
Poll status, handle progress, and wire webhooks into your stack.
Captions
Add AutoCaptions
Route rendered output into subtitle generation and social-ready videos.
Commercial
Check plans and limits
Review plan limits, AI credits and production pricing before implementation.
Quick answer
The SamAutomation JSON to Video API is for developers who need a predictable JSON in, video out workflow with polling, webhooks, pricing, captions and AI jobs in one stack.
Auth
X-API-Key
Core flow
Submit JSON -> poll progress -> fetch output
AI flow
Select model -> create job -> poll status
Implementation paths
Choose the fastest route from query to production
Most visitors on this page are deciding between three jobs: test the API quickly, wire it into n8n or webhooks, or validate pricing before production rollout. Use the path that matches your stage instead of reading the whole page front to back.
Code first
Run the first request
Copy the curl example, submit media, then poll the task UUID.
Automation first
Route it through n8n
Use HTTP Request nodes, webhooks, and delivery callbacks without building custom middleware first.
Content ops
Add captions and social output
Pair render jobs with AutoCaptions when your output needs TikTok, Shorts, or Reels-ready subtitles.
Best for
Developers who need JSON in, video out without editor clicks.
Operational fit
Async polling, webhook callbacks, captions, exports, and AI jobs under one API key.
Commercial check
Use pricing before rollout if you need plan limits, AI credits, or production usage clarity.
Authentication
Send your API key in the X-API-Key header on every request.
Legacy clients may still use the api_key query parameter.
X-API-Key: YOUR_SAMAUTOMATION_API_KEY
All endpoints below are under https://samautomation.work/api/....
Quickstart
-
Submit a JSON-to-video render job.
curl -X POST "https://samautomation.work/api/function/video-generation/mix-video" \ -H "X-API-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "media_list": [ {"type": "image", "url": "https://cdn.example.com/frame-1.jpg", "duration": 3}, {"type": "video", "url": "https://cdn.example.com/clip-2.mp4"} ], "voice_url": "https://cdn.example.com/voice.mp3", "background_url": "https://cdn.example.com/music.mp3", "settings": {"aspect_ratio": "9:16", "transition_type": "fade"} } }' -
Poll progress with the task UUID from the create response.
curl -X GET "https://samautomation.work/api/function/video-generation/progress/TASK_UUID" \ -H "X-API-Key: YOUR_KEY"
-
Optional: list recent tasks.
curl -X GET "https://samautomation.work/api/function/video-generation/tasks?limit=10" \ -H "X-API-Key: YOUR_KEY"
Payload contract (core endpoints)
Core endpoints accept either a root payload or a nested data object.
Accepted envelope shapes
{
"media_list": [...],
"settings": {...}
}
{
"data": {
"media_list": [...],
"settings": {...}
}
}
Media object fields
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | Yes | For simple-video: video or image. |
url | string | Yes | Publicly reachable media URL. |
duration | number | No | Used by image clips in multiple flows. |
| other keys | mixed | No | Passed through for renderer-level logic. |
Settings validation matrix
These validations are enforced by simple-video and reused by related JSON workflows.
| Field | Accepted values |
|---|---|
aspect_ratio | 9:16, 16:9, 1:1 |
transition_type | fade, wipe, zoom, slide, glitch |
transition_direction | left, right, up, down |
zoom_direction | in, out, alternate |
watermark_position | top_left, top_right, bottom_left, bottom_right, center |
output_quality | low, medium, high |
image_duration | 0 to 30 |
audio_volume, video_volume, zoom_intensity, watermark_size, watermark_opacity | 0 to 1 |
transition_duration | 0 to 3 |
audio_fade_in, audio_fade_out | 0 to 5 |
min_video_duration | 0 to 60 |
video_loop_duration | 0 to 120 |
watermark_padding | 0 to 100 |
fps | 15 to 60 |
loop_audio, mute_original_audio, loop_video, zoom_effect | boolean only |
text_overlays[] | Object with required text; optional position (top/middle/bottom) and background (none/black/semi-transparent) |
Request schemas by endpoint
Use this as the exact minimum/optional field reference for core JSON-to-video endpoints.
| Endpoint | Required fields | Optional fields |
|---|---|---|
POST /api/function/video-generation/mix-video |
media_list (non-empty) |
voice_url, background_url, transcripts, settings, exports |
POST /api/function/video-generation/simple-video |
media_list (non-empty), per item type + url, type in {video,image} |
settings (validated by ranges/enums in this page), exports |
POST /api/function/video-generation/loop-video |
top-level type = "LoopVideo", data.media_list, data.background_url |
data.duration (positive number), data.settings, data.exports |
Important request notes
- For
mix-videoandsimple-video, you can send fields at root or insidedata. - For
loop-video, use top-leveltypeand nesteddata. exportscan be placed at root or insidedata/config.- All three create endpoints run with rate limit
5/mper authenticated API user.
Export destinations per job
Add optional exports settings to deliver completed videos directly to your workflow tools.
This supports callback webhooks, FTP/SFTP upload, and email notifications from the same render request.
| Field | Type | Required | Notes |
|---|---|---|---|
exports.callback_url |
string | No | Public HTTP(S) URL that receives video.completed JSON payload. |
exports.callback_secret |
string | No | Optional per-job secret used for webhook signature verification. |
exports.destinations |
array | No | Up to 5 destinations. Supported types: email, ftp, sftp. |
email.to |
string or array | Yes (email) | One or more recipients. |
ftp/sftp host, username, path |
string | Yes (ftp/sftp) | Path can be a directory or full remote file path. |
ftp password or sftp password/private_key |
string | Yes (auth) | SFTP supports password or PEM private key authentication. |
{
"data": {
"media_list": [{"type": "image", "url": "https://cdn.example.com/frame.jpg", "duration": 3}],
"settings": {"aspect_ratio": "16:9"},
"exports": {
"callback_url": "https://hooks.example.com/video-completed",
"callback_secret": "your-shared-secret",
"destinations": [
{"type": "email", "to": ["ops@example.com", "creator@example.com"]},
{
"type": "sftp",
"host": "files.example.com",
"port": 22,
"username": "deploy",
"password": "YOUR_PASSWORD",
"path": "/incoming/videos/"
}
]
}
}
}
X-Samautomation-Signature (t=<unix>,v1=<hmac_sha256>),
X-Samautomation-Event: video.completed.
Delivery results are visible in progress responses under
settings.export_delivery.
Mix video endpoint
POST /api/function/video-generation/mix-video
- Requires
media_list. - Optional:
voice_url,background_url,transcripts,settings,exports. - Rate limit:
5/mper authenticated API user.
{
"data": {
"media_list": [
{"type": "image", "url": "https://cdn.example.com/scene-1.jpg", "duration": 3},
{"type": "video", "url": "https://cdn.example.com/scene-2.mp4"}
],
"voice_url": "https://cdn.example.com/voice.mp3",
"background_url": "https://cdn.example.com/music.mp3",
"transcripts": [
{"words": "Welcome to SamAutomation", "start": 0.0, "end": 2.0}
],
"settings": {
"aspect_ratio": "16:9",
"transition_type": "fade"
}
}
}
{
"success": true,
"message": "Video generation started",
"data": {
"id": "3ec95f88-54bc-4b91-b2d0-d02da8929b4a",
"progress_url": "/api/function/video-generation/progress/3ec95f88-54bc-4b91-b2d0-d02da8929b4a",
"celery_task_id": "26767b7f-b642-44ef-8f16-0d99069ed844"
}
}
{
"success": true,
"message": "Video generation started",
"data": {
"id": "f6159e7c-9a84-4c58-b9ad-1dd3a3ea12b1",
"progress_url": "/api/function/video-generation/progress/f6159e7c-9a84-4c58-b9ad-1dd3a3ea12b1",
"celery_task_id": "5dd8d7b5-a050-41ef-a11d-ecf1c4ef1495"
}
}
Common mix-video errors
{"success":false,"message":"Invalid JSON data"}{"success":false,"message":"No media items provided"}{"success":false,"message":"API key is not active or missing"}{"success":false,"message":"Free tier limit reached. You can generate 5 videos per month. Please upgrade to a paid plan for more videos.","upgrade_url":"/subscription/plans/"}{"success":false,"message":"Monthly limit reached. Your plan allows ... videos per month.","upgrade_url":"/subscription/plans/"}
Transcript object contract (Mix video)
When you send transcripts, each entry should contain timed words.
| Field | Type | Required | Meaning |
|---|---|---|---|
words | string | Yes | Caption text for that segment. |
start | number | Yes | Start time in seconds. |
end | number | Yes | End time in seconds. |
// valid
{
"transcripts": [
{"words": "First caption", "start": 0.0, "end": 1.8},
{"words": "Second caption", "start": 1.9, "end": 3.4}
]
}
// avoid this shape
{
"transcripts": [
{"text": "First caption", "start": 0.0, "end": 1.8}
]
}
Common simple-video errors
{"success":false,"message":"No media items provided"}{"success":false,"message":"Each media item must have 'type' and 'url'"}{"success":false,"message":"Media type must be 'video' or 'image'"}{"success":false,"message":"aspect_ratio must be one of ... / range errors from settings validation"}
Simple video endpoint
POST /api/function/video-generation/simple-video
- Requires
media_list. - Each media item must include
typeandurl. - Allowed media types:
videoandimage. - Applies strict settings validation (see validation matrix above).
- Rate limit:
5/m.
{
"media_list": [
{"type": "image", "url": "https://cdn.example.com/slide.jpg", "duration": 4}
],
"settings": {
"aspect_ratio": "9:16",
"fps": 30,
"output_quality": "high",
"loop_audio": false,
"transition_type": "fade",
"transition_duration": 0.5
}
}
Common loop-video errors
{"success":false,"message":"Invalid video type. Only 'LoopVideo' is supported."}{"success":false,"message":"Background URL is required"}{"success":false,"message":"Duration must be a positive number"}{"success":false,"message":"Duration must be a valid number"}
Loop video endpoint
POST /api/function/video-generation/loop-video
- Top-level
typemust be exactlyLoopVideo. data.media_listis required.data.background_urlis required.data.durationis optional but, if sent, must be a positive number.- Rate limit:
5/m.
{
"type": "LoopVideo",
"data": {
"media_list": [
{"type": "video", "url": "https://cdn.example.com/loop-source.mp4"}
],
"background_url": "https://cdn.example.com/bg-music.mp3",
"duration": 12,
"settings": {
"aspect_ratio": "16:9",
"loop_video": true
}
}
}
{
"success": true,
"message": "Video generation started",
"data": {
"id": "09574c7d-9441-4eca-a8ee-e0d11f3f1ca9",
"celery_task_id": "5f79f7f5-84ec-46a4-a844-d9668d7af385"
}
}
Reference clients (Python + JavaScript)
These examples show submit + poll flow for core JSON-to-video endpoints.
Python (requests)
import time
import requests
BASE = "https://samautomation.work"
HEADERS = {"X-API-Key": "YOUR_KEY", "Content-Type": "application/json"}
payload = {
"data": {
"media_list": [{"type": "image", "url": "https://cdn.example.com/a.jpg", "duration": 3}],
"settings": {"aspect_ratio": "9:16"}
}
}
# mix-video (replace path for simple-video or loop-video)
r = requests.post(f"{BASE}/api/function/video-generation/mix-video", headers=HEADERS, json=payload, timeout=60)
job = r.json()["data"]["id"]
while True:
s = requests.get(f"{BASE}/api/function/video-generation/progress/{job}", headers=HEADERS, timeout=30).json()["data"]
if s["status"] in {"completed", "failed", "cancelled", "timeout"}:
print(s)
break
time.sleep(5)
JavaScript (fetch)
const BASE = "https://samautomation.work";
const headers = {
"X-API-Key": "YOUR_KEY",
"Content-Type": "application/json",
};
const create = await fetch(`${BASE}/api/function/video-generation/simple-video`, {
method: "POST",
headers,
body: JSON.stringify({
media_list: [{ type: "image", url: "https://cdn.example.com/a.jpg", duration: 3 }],
settings: { aspect_ratio: "16:9" },
}),
});
const { data } = await create.json();
let done = false;
while (!done) {
const statusRes = await fetch(`${BASE}/api/function/video-generation/progress/${data.id}`, { headers });
const statusPayload = await statusRes.json();
const status = statusPayload.data.status;
done = ["completed", "failed", "cancelled", "timeout"].includes(status);
if (!done) await new Promise((r) => setTimeout(r, 5000));
}
For loop generation, call /api/function/video-generation/loop-video and include top-level type: "LoopVideo".
Task tracking and usage endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/function/video-generation/progress/{id} | Current status, progress, output URL, and error. |
| GET | /api/function/video-generation/tasks | Recent tasks list (supports limit and status). |
| GET | /api/function/video-generation/usage-summary | Usage totals and status breakdown (supports days). |
Progress response
{
"success": true,
"data": {
"id": "3ec95f88-54bc-4b91-b2d0-d02da8929b4a",
"status": "processing",
"progress": 0.6,
"created_at": "2026-02-28T14:10:00+00:00",
"completed_at": null,
"output_url": null,
"error": null,
"settings": {
"aspect_ratio": "9:16",
"duration": 0,
"size_bytes": 0
}
}
}
Usage summary response
{
"success": true,
"data": {
"window_days": 30,
"since": "2026-01-29T12:00:00+00:00",
"totals": {
"tasks": 42,
"completed": 38,
"failed": 2,
"cancelled": 1,
"timeout": 1,
"success_rate": 0.9048
},
"by_status": {
"pending": 0,
"processing": 0,
"completed": 38,
"failed": 2,
"cancelled": 1,
"timeout": 1
},
"api_key": {
"name": "Production",
"masked_key": "abcd...wxyz",
"usage_count": 128,
"last_used": "2026-02-28T13:59:00+00:00"
}
}
}
Task lifecycle states
| State | Meaning | Client action |
|---|---|---|
pending | Task row created, not started. | Continue polling. |
processing | Render is active. | Continue polling/backoff. |
completed | Render succeeded. | Read output_url and stop polling. |
failed | Render failed. | Inspect error, fix payload/media, retry. |
cancelled | Job cancelled by user/system. | Stop polling and decide whether to resubmit. |
timeout | Task timed out after inactivity window. | Treat as failed and resubmit if needed. |
Advanced renderer API
POST /api/render/advanced-video and GET /api/render/advanced-video/progress/{task_id}
- Rate limit:
3/mfor create requests. - Request body can be at root or in
config. - Supports
render_options.mode:preview(sync) orfull(async). - Optional
template_idmerges saved template settings before validation.
Required advanced config
{
"config": {
"output_settings": {
"aspect_ratio": "16:9",
"resolution": "1080p",
"framerate": 30
},
"media_inputs": {
"main_clips": [
{"type": "video", "url": "https://cdn.example.com/clip-a.mp4"},
{"type": "image", "url": "https://cdn.example.com/clip-b.jpg", "duration": 3}
],
"background": {"type": "color", "value": "#000000"}
},
"caption_elements": [
{
"text_content": "Launch day",
"start_time": 0,
"duration": 2,
"styling": {"font_size": 42, "text_color": "#FFFFFF"}
}
],
"audio_settings": {
"background_music_url": "https://cdn.example.com/bg.mp3",
"background_music_volume_percent": 20,
"voice_over_url": "https://cdn.example.com/voice.mp3",
"voice_over_volume_percent": 100
},
"render_options": {
"mode": "full",
"quality": "high"
}
}
}
Validation rules
output_settings.aspect_ratio:16:9,1:1,9:16output_settings.resolution:480p,720p,1080p,1440p,2160poutput_settings.framerate: 15 to 60media_inputs.main_clips: required, 1 to 100 clips- clip
type:videoorimage - image clip
duration: 0.1 to 30 background.type:color,image,videocaption_elements[].text_content: max 500 charsrender_options.mode:previeworfullrender_options.quality:low,medium,high
Advanced create responses
// preview mode
{
"success": true,
"message": "Preview generated successfully",
"data": {
"mode": "preview",
"preview_url": "https://media.samautomation.work/previews/preview_a1b2c3.mp4",
"request_id": "a1b2c3d4"
}
}
// full mode
{
"success": true,
"message": "Advanced video generation started",
"data": {
"id": "c5b58dc9-4c17-4380-bf34-b3ec3c10f06f",
"mode": "full",
"progress_url": "/api/render/advanced-video/progress/c5b58dc9-4c17-4380-bf34-b3ec3c10f06f",
"estimated_time": "2-5 minutes",
"request_id": "f8e96a10",
"celery_task_id": "a2be3da1-4f3a-4f5e-b7ce-7d7f71b0f5bb"
}
}
Rendering behavior that affects output
- Image clips use duration rules from your payload/settings; ensure image durations are explicit for predictable pacing.
- Final video segments can include a brief freeze extension at the end for smoother endings; do not assume strict hard-cut timing.
- Caption behavior depends on transcript timing and caption settings; timed words (
words/start/end) produce the most reliable overlays. - You can control caption behavior with settings such as caption style and caption-disable flags in renderer-level configurations.
- Background audio and voice-over volumes are mixed using your settings; set explicit volume values to avoid aggressive ducking/mix surprises.
- Loop and transition effects are settings-driven; always test one short render before scaling to bulk jobs.
Async control endpoints
| Method | Path | Use case |
|---|---|---|
| GET | /api/async/status/{task_id} | Inspect raw async processor state. |
| POST | /api/async/cancel/{task_id} | Cancel a running job if still cancellable. |
| GET | /api/async/queue/status | Queue health: workers and active load. |
| GET | /api/async/health | Health-check async processing layer. |
curl -X POST "https://samautomation.work/api/async/cancel/CELERY_TASK_ID" \ -H "X-API-Key: YOUR_KEY"
Templates API (reusable render presets)
| Method | Path | Purpose |
|---|---|---|
| POST | /api/templates/ | Create a template. |
| GET | /api/templates/list/?include_public=true&category=marketing | List private + optional public templates. |
| GET | /api/templates/{template_id}/ | Read one template. |
| PUT | /api/templates/{template_id}/ | Update name/description/category/settings/is_public. |
| DELETE | /api/templates/{template_id}/ | Delete template. |
| POST | /api/templates/{template_id}/apply/ | Fetch merged settings for reuse. |
{
"name": "My 9:16 Promo",
"description": "Short promo style with captions",
"category": "marketing",
"is_public": false,
"settings": {
"output_settings": {"aspect_ratio": "9:16", "framerate": 30},
"render_options": {"quality": "high"}
}
}
Video billing and credit pack endpoints
For core JSON-to-video volume beyond plan limits, use video pack checkout endpoints.
| Method | Path | Purpose |
|---|---|---|
| POST | /api/video-packs/{pack_id}/buy/ | Create Stripe checkout session for extra video credits. |
| POST | /api/video-packs/webhook/ | Stripe webhook applies purchased credits idempotently. |
| GET | /api/video-packs/success/ | Checkout success callback. |
| GET | /api/video-packs/cancel/ | Checkout cancel callback. |
Use /api/function/video-generation/usage-summary to monitor usage windows and avoid hard stops.
AI video API
Use the same SamAutomation key to generate AI videos via job endpoints. The available model list, constraints, options, and credit behavior are live.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/ai/models | List active models and runtime constraints. |
| GET | /api/ai/models?type=video | Filter by model type (video or image). |
| POST | /api/ai/jobs | Create new AI generation job. |
| POST | /api/ai/generate | Backward-compatible alias for /api/ai/jobs. |
| GET | /api/ai/jobs/{job_id} | Poll job status and output URLs. |
| GET | /api/ai/credits/balance | Read remaining subscription and top-up credits. |
AI job request
{
"model_id": "kling_3_0",
"prompt": "Cinematic tracking shot in a rainy neon city",
"image_urls": ["https://cdn.example.com/source.jpg"],
"options": {
"duration_seconds": 8,
"aspect_ratio": "16:9",
"quality_mode": "pro",
"sound": true,
"multiShots": true
}
}
AI job responses
// create (HTTP 202)
{
"success": true,
"job_id": 148,
"status": "running",
"credits_charged": 220,
"credits_remaining": 5230
}
// status
{
"success": true,
"job_id": 148,
"status": "success",
"result_urls": ["https://media.samautomation.work/ai/output-148.mp4"],
"error_code": null,
"error_message": null,
"credits_charged": 220,
"created_at": "2026-02-28T14:40:00+00:00",
"completed_at": "2026-02-28T14:41:33+00:00"
}
Live model coverage
Active models in current catalog: 37. Video models shown below are available through SamAutomation with plan-based access controls.
| Model | ID | Credits (base) | Capabilities | Plan visibility |
|---|---|---|---|---|
| Grok Imagine Video | grok-imagine-video |
80 | t2v, i2v | pro, ultimate |
| Grok Video | grok-video |
180 | t2v, i2v | ultimate |
| Hailuo 02 Pro | hailuo-02-pro |
110 | t2v | pro, ultimate |
| Hailuo 2.3 Pro | hailuo-2-3-pro |
55 | t2v, i2v | pro, ultimate |
| Hailuo 2.3 Standard | hailuo-2-3-standard |
40 | t2v, i2v | basic, pro, ultimate |
| Kling 2.6 Standard | kling-2-6-standard |
90 | t2v, i2v | basic, pro, ultimate |
| Kling 2.6 | kling-2-6 |
55 | t2v, i2v | basic, pro, ultimate |
| Kling 2.6 with Audio | kling-2-6-audio |
130 | t2v, i2v | pro, ultimate |
| Kling 3.0 Pro | kling-3-0-pro |
220 | t2v, i2v | pro, ultimate |
| Kling 3.0 Standard | kling-3-0-standard |
120 | t2v, i2v | pro, ultimate |
| Kling 3.0 | kling-3-0 |
75 | t2v, i2v | pro, ultimate |
| Pixverse V4.5 | pixverse-v4-5 |
95 | t2v, i2v | pro, ultimate |
| Seedance 1.5 Pro 480p | seedance-1-5-pro-480p |
75 | t2v, i2v | basic, pro, ultimate |
| Seedance 1.5 Pro 720p | seedance-1-5-pro-720p |
120 | t2v, i2v | pro, ultimate |
| Seedance 1.5 Pro | seedance-1-5-pro |
40 | t2v, i2v | basic, pro, ultimate |
| Sora 2 Image to Video | sora-2-image |
30 | i2v | basic, pro, ultimate |
| Sora 2 Pro Image to Video | sora-2-pro-image |
150 | i2v | basic, pro, ultimate |
| Sora 2 Pro Storyboard | sora-2-pro-storyboard |
180 | storyboard, t2v, i2v | ultimate |
| Sora 2 Pro Text to Video | sora-2-pro-text |
150 | t2v | basic, pro, ultimate |
| Sora 2 Pro | sora-2-pro |
120 | t2v, i2v | pro, ultimate |
| Sora 2 Text to Video | sora-2-text |
30 | t2v | basic, pro, ultimate |
| Sora 2 | sora-2 |
40 | t2v, i2v | basic, pro, ultimate |
| Veo 3.1 Fast | veo-3-1-fast |
60 | t2v, i2v | basic, pro, ultimate |
| Veo 3.1 Quality | veo-3-1-quality |
250 | t2v, i2v | basic, pro, ultimate |
| Wan 2.6 1080p | wan-2-6-1080p |
140 | t2v, i2v | pro, ultimate |
| Wan 2.6 720p | wan-2-6-720p |
70 | t2v, i2v | basic, pro, ultimate |
| Wan 2.6 | wan-2-6 |
25 | t2v, i2v | basic, pro, ultimate |
| Wan 2.6 V2V | wan-2-6-v2v |
45 | v2v, i2v, edit | basic, pro, ultimate |
| Wan VACE | wan-vace |
160 | t2v, i2v, edit | ultimate |
Need model details for both image and video? Call GET /api/ai/models directly.
Rate limits and quota behavior
| Route group | Limit | Notes |
|---|---|---|
Core create endpoints (mix/simple/loop) | 5/m | Per authenticated API user. |
| Advanced renderer create | 3/m | Header-key based limit on create calls. |
| Template endpoints | custom limiter | Designed to throttle by client IP. |
- Free tier has monthly JSON-to-video cap (5 videos) unless upgraded or extra credits are available.
403can mean plan/quota restriction, while429means request rate throttling.- Header auth is recommended. Query-string
api_keyworks for legacy clients but is less secure in logs/history.
Errors, exact payloads, and polling strategy
| HTTP | Meaning | Typical cause |
|---|---|---|
| 400 | Invalid payload | Field missing, invalid enum/range, invalid loop type/duration, JSON decode issues. |
| 401 | API key missing | {"success":false,"message":"API key required","error_code":"API_KEY_MISSING"} |
| 402 | Insufficient credits | AI jobs only; includes credits_required and credits_remaining. |
| 403 | Forbidden | Invalid key, inactive key, model plan restriction, or monthly JSON-to-video quota reached. |
| 404 | Not found | Unknown task/template/model or inaccessible resource. |
| 413 | Payload too large | Advanced renderer request rejected before validation. |
| 429 | Rate limited | Create/request frequency exceeded. |
| 500/502/503 | Server or upstream failure | Task start failure, provider issue, async health failure, or temporary service block. |
| Endpoint | Example exact error payload |
|---|---|
POST /api/function/video-generation/mix-video |
{"success":false,"message":"No media items provided"} |
POST /api/function/video-generation/simple-video |
{"success":false,"message":"Each media item must have 'type' and 'url'"} |
POST /api/function/video-generation/loop-video |
{"success":false,"message":"Invalid video type. Only 'LoopVideo' is supported."} |
POST /api/render/advanced-video |
{"success":false,"message":"Configuration validation failed: ...","error_code":"VALIDATION_ERROR"} |
GET /api/async/status/{task_id} |
{"success":false,"message":"Invalid task ID format","error_code":"INVALID_TASK_ID"} |
GET /api/ai/jobs/{job_id} |
{"success":false,"message":"Insufficient credits","credits_required":220,"credits_remaining":94} (create flow) |
- For async create calls, start polling after 3 to 5 seconds.
- Use backoff: 5s, 8s, 10s, then every 10 to 15 seconds.
- Terminal states: JSON-to-video
completed/failed/cancelled/timeout; AI jobssuccess/failed. - If polling a task id that does not map to your current user, expect auth/ownership protection responses.
FAQ
Can I send media in root JSON without a data object?
Yes. Core JSON-to-video endpoints accept both formats: root fields or nested under data.
How do I create a looping video request correctly?
Use POST /api/function/video-generation/loop-video with top-level type: "LoopVideo" and include both data.media_list and data.background_url.
What transcript format should I send?
Use timed words entries with words, start, and end. Avoid text-only objects without words.
Can I use one key for JSON-to-video and AI video?
Yes. One SamAutomation API key covers all endpoints on this page.
Where do I find AI model-specific options?
Call GET /api/ai/models. The response includes live constraints, options, and credit info per model.