SudoMock
POST

Render Video

Turn a mockup into a short, shareable product video. Pick a duration, optionally add audio, and SudoMock produces a CDN-hosted clip you can drop into ads, listings, and social posts.

POST/api/v1/renders/video
always async

Always asynchronous

Video generation runs in the background. This endpoint always responds with 202Accepted and a render_uuid, never an inline video. Track it with GET /api/v1/jobs/{render_uuid} or a webhook. There is no is_async flag to set.

Request

Headers

x-api-keystring

Your SudoMock API key starting with sm_. Required unless using Bearer token authentication.

Content-TypestringRequired

Must be application/json

Idempotency-Keystring

Optional. Makes retried submits safe: a duplicate key returns the original job's 202 and is not charged twice.

Request Body

Supply exactly one input mode. In render mode the mockup and artwork are described exactly as in a standard render: a mockup_uuid plus a smart_objects array. In raw image mode you pass a single image_url to animate directly (see below). The video-specific options live in a video object either way.

mockup_uuidstring

Render mode only. UUID of the mockup to animate, from the upload, list, or get-mockup response. Required in render mode; omit it in raw image mode. Mutually exclusive with image_url.

smart_objectsarray

Render mode only. Array of smart object configurations, identical to the render endpoint. Must contain at least 1 item. Required in render mode; omit it in raw image mode.

image_urlstring

Raw image mode only. A public https URL ending in .png/.jpg/.jpeg/.webp to animate directly, with no render step. Mutually exclusive with mockup_uuid + smart_objects (provide exactly one mode).

videoobject

Video options: duration_seconds, audio, and advanced_model. Each field has a default, so the object is optional.

webhookobject

Optional per-request webhook, e.g. { "url": "https://..." }. Notified when this job finishes, in addition to any account-level webhooks. Best-effort; polling stays the source of truth.

Video Options

video.duration_secondsinteger= 4

Length of the clip in whole seconds. Each model allows its own set of durations, and a value the chosen model does not allow is rejected (the error lists the allowed durations). Longer clips cost more credits.

video.audioboolean= false

Whether to include a generated audio track. Off by default; turning it on can cost more credits.

video.advanced_modelstring

Optional override that pins a specific model instead of the auto-router. Omit it to let SudoMock pick the best model for your tier automatically (recommended). An unrecognized value is rejected with 400.

Let the auto-router choose

Leave advanced_model out and SudoMock picks the best model for your plan and mockup automatically. The 202 reports the resolved model (the identifier of the model that ran the job) and the estimated_credits for the clip. Read model only if you want to know exactly which model ran.
Request Body Example
1{
2 "mockup_uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
3 "smart_objects": [
4 {
5 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",
6 "asset": {
7 "url": "https://your-domain.com/design.png",
8 "fit": "cover"
9 }
10 }
11 ],
12 "video": {
13 "duration_seconds": 4,
14 "audio": false
15 }
16}

Raw image mode

To animate an image you already have, pass image_url instead of mockup_uuid and smart_objects. There is no render step: the URL is animated directly. The two modes are mutually exclusive (XOR) so provide exactly one. The image must be a public, directly reachable https URL ending in .png, .jpg, .jpeg, or .webp; a URL that fails the safety and reachability check is rejected with INVALID_IMAGE_URL (400).

Raw image mode body
1{
2 "image_url": "https://your-domain.com/scene.png",
3 "video": {
4 "duration_seconds": 4,
5 "audio": false
6 }
7}

Per-request webhook

Add a top-level webhook object (for example { "url": "https://your-domain.com/hooks/video" }) to be notified for this one job when it finishes. It is best-effort; polling stays the source of truth if a delivery is missed. This is in addition to any account-level webhooks you have registered.

Code Examples

Render Video
bash
1# 1) Request the video -> 202 Accepted (always async)
2curl -X POST "https://api.sudomock.com/api/v1/renders/video" \
3 -H "Content-Type: application/json" \
4 -H "x-api-key: sm_your_api_key" \
5 -d '{
6 "mockup_uuid": "c315f78f-d2c7-4541-b240-a9372842de94",
7 "smart_objects": [{
8 "uuid": "128394ee-6758-4f2f-aa36-e2b19b152bd9",
9 "asset": { "url": "https://your-domain.com/design.png", "fit": "cover" }
10 }],
11 "video": { "duration_seconds": 4, "audio": false }
12 }'
13
14# 2) Poll the job until status is succeeded (result_url holds the video)
15curl "https://api.sudomock.com/api/v1/jobs/9d4e2b51-0c7a-4f8e-bb1c-2a6f9e3d8c10" \
16 -H "x-api-key: sm_your_api_key"

Response

202Accepted

The endpoint queues the job and returns immediately. The body echoes the resolved options so you can confirm the cost and settings before the video is ready.

Response 202 Accepted
1{
2 "render_uuid": "9d4e2b51-0c7a-4f8e-bb1c-2a6f9e3d8c10",
3 "kind": "video",
4 "status": "queued",
5 "status_url": "/api/v1/jobs/9d4e2b51-0c7a-4f8e-bb1c-2a6f9e3d8c10",
6 "model": "veo-3.1-fast",
7 "estimated_credits": 949,
8 "duration_seconds": 4,
9 "audio": false
10}

Response Fields

render_uuidstringRequired

The job identifier. Poll GET /api/v1/jobs/{render_uuid} for the finished video.

kindstringRequired

Always "video" for this endpoint.

statusstringRequired

Always "queued" on submission.

status_urlstringRequired

Relative path to poll for this job, in the form /api/v1/jobs/{render_uuid}.

modelstring

The identifier of the model that ran the job, for example veo-3.1-fast. Resolved by the auto-router unless you pin one with advanced_model.

estimated_creditsnumber

The credit cost for this clip, known up front. It is deducted once at submit and never re-priced while the job runs; the finished job reports the same amount as credits_charged.

duration_secondsinteger

Resolved clip length in seconds.

audioboolean

Whether the clip will include an audio track.

Credits

Videos render at 720p. Video jobs draw on the same credit balance as a still render, scaled by your duration, tier, and audio choices. The estimated_credits field in the 202 response tells you the exact cost up front, and the finished job reports the matching credits_charged (with a payg breakdown when billed via pay-as-you-go). Failed and cancelled jobs are not charged.

Retrieving the result

Poll the job until the status is succeeded. The finished video URL is in result_url (a video job behaves like a render here, not an upload).

StatusWhat to do
queued / dispatched / runningKeep polling with a capped backoff.
succeededRead result_url for the video. Read credits_charged for the cost.
failed / cancelledStop. Read error. Nothing was charged.

Errors

402Payment Required

Insufficient credits and no available pay-as-you-go. The response includes actionable links and credit reset timing.

json
1{
2 "error": "credits_exhausted",
3 "message": "You've run out of credits for this billing period.",
4 "actions": [
5 { "label": "Enable Pay-As-You-Go", "url": "https://sudomock.com/dashboard/billing?action=enable-payg" },
6 { "label": "Upgrade Plan", "url": "https://sudomock.com/pricing" }
7 ],
8 "credits_reset_at": "2026-07-01T00:00:00Z"
9}
400Bad Request

A field is well-formed but not accepted: a duration_seconds the chosen model does not allow (the response lists the allowed durations), an unknown video.advanced_model, a mockup_uuid that is not a valid UUID, or a raw-mode image_url that fails the URL safety and reachability check (INVALID_IMAGE_URL).

json
1{
2 "error_code": "INVALID_VIDEO_DURATION",
3 "message": "4s is not supported by the selected model 'best'.",
4 "allowed_durations": [5, 10],
5 "suggestion": "Choose a duration from allowed_durations (default 5s).",
6 "detail": "4s is not supported by the selected model 'best'.",
7 "success": false
8}
404Not Found

The specified mockup_uuid does not exist or does not belong to your account.

json
1{
2 "error_code": "MOCKUP_NOT_FOUND",
3 "message": "Mockup 'c315f78f-d2c7-4541-b240-a9372842de94' was not found.",
4 "suggestion": "It may have been deleted or expired (free-tier TTL). List your mockups via GET /api/v1/mockups.",
5 "detail": "Mockup 'c315f78f-d2c7-4541-b240-a9372842de94' was not found.",
6 "success": false
7}
422Validation Error

Request body fails schema validation (for example an empty smart_objects array, or a smart object missing both asset and color).

json
1{
2 "detail": "Validation error",
3 "errors": [
4 {
5 "field": "body -> smart_objects",
6 "message": "Invalid value for field: body -> smart_objects"
7 }
8 ],
9 "success": false
10}

A video job that fails after acceptance

If a video is accepted (202) but cannot be produced, the failure surfaces on the job, not on this request. Poll the job and handle status: "failed" with its error, or receive the video.failed webhook. See Error Handling for the full reference.

SDKs cover video

The sudomock npm (npmjs.com/package/sudomock) and sudomock PyPI (pypi.org/project/sudomock) packages cover renders, async, video, jobs, and webhooks, so you can request a video and await the finished clip in a single call.
Render Video Endpoint | SudoMock Docs