---
title: "Render a video mockup"
method: POST
path: "/api/v1/renders/video"
tags: ["Video mockups"]
---

# Render a video mockup

`POST /api/v1/renders/video`

## Request

- Base URL: `https://api.sudomock.com`
- URL: `https://api.sudomock.com/api/v1/renders/video`
- Auth: API key in header `x-api-key`

Animates a mockup: produces a still render from the given smart objects, then animates it. Returns 202 with a job_id to poll (GET /api/v1/jobs/{job_id}).

## Request body

- VideoRenderRequest: Request body for POST /api/v1/renders/video. Supply exactly one of two input modes. Render mode (mockup_uuid and smart_objects, optionally export_options) mirrors a still render: the still is produced first, then animated. Raw-image mode (image_url) animates a public https png or jpg directly with no render step, and the render fields are ignored. Both modes take the video animation options and an optional completion webhook. The call always queues a job; poll GET /api/v1/jobs/{job_id} for the result. Sending both modes, or neither, returns 400.
  - `mockup_uuid` string, nullable: RENDER MODE: UUID of the mockup to animate (from GET /api/v1/psd-mockups or POST /api/v1/psd/upload). Required in render mode; omit in raw-image mode.
  - `smart_objects` SmartObjectInput[], nullable: RENDER MODE: smart objects with their assets, identical to a still render (at least 1 required). Required in render mode; omit in raw-image mode.
    - `uuid` string, required: UUID of the smart object to render
    - `asset` AssetInput: The image to place into a smart object, and how it should sit there. Image source priority: base64 > url (including data: URLs) - base64: Raw base64 string (no data: prefix). Suits small images already in memory. - url: HTTP/HTTPS URL or data:image/...;base64,... URL. Suits large files.
      - `url` string, nullable: URL to the user's image (HTTP/HTTPS or data: URL). Either url or base64 must be provided. The server fetches the image, so the request stays small: the right choice for large files.
      - `base64` string, nullable: Raw base64-encoded image bytes (no data: prefix). Either url or base64 must be provided. Saves the server-side fetch for small images already in memory. Base64 adds about a third to the file size and the whole request must finish uploading within 60 seconds, so send large files by url.
      - `content_type` string, nullable: MIME type when using base64 field. Supported: image/png, image/jpeg, image/webp, image/gif. Defaults to image/png if omitted.
      - `fit` 'fill' | 'fit' | 'crop': How the artwork meets the smart object area. 'fit' scales it until it fits inside, keeping proportions, which can leave empty space. 'fill' stretches it to the bounds and does not keep its proportions. 'crop' covers the area and cuts the overflow, keeping proportions. 'contain' and 'cover' are the older names for 'fit' and 'crop' and are still accepted. Defaults to 'fit': a caller who says nothing is not asking to have their artwork distorted, and a silently stretched design is a defect the caller cannot see.
      - `size` AssetSize: How large the artwork is drawn inside the smart object. Fractional pixels are accepted.
        - `width` number, nullable: Custom width in pixels
        - `height` number, nullable: Custom height in pixels
      - `position` AssetPosition: Where the artwork sits inside the smart object. Fractional pixels are accepted.
        - `top` number, nullable: Top offset in pixels
        - `left` number, nullable: Left offset in pixels
      - `rotate` number: Rotation angle in degrees (clockwise positive). Applied to the artwork before it is fitted, so the turned artwork, corners included, is what fit places inside the still axis-aligned size box at position.
      - `flip_horizontal` boolean: Flip artwork horizontally (left-right mirror)
      - `flip_vertical` boolean: Flip artwork vertically (top-bottom mirror)
      - `remove_background` boolean: Remove the image background before placing the artwork; the subject is isolated onto a clean transparent cutout. Adds 25 credits per artwork to the render cost.
    - `color` ColorOverlay: A colour laid over the smart object, with a blending mode.
      - `hex` string, nullable: Hex color code (e.g., '#FF5733'). Send this or 'label'.
      - `label` string, nullable: One of the colours saved on this mockup, by the name you gave it. Send this instead of 'hex' to keep calling a colour what your own catalogue calls it. Names match exactly, and are set with PATCH /api/v1/psd-mockups/{uuid}.
      - `blending_mode` string: Blend mode for color overlay. Common values: 'normal', 'multiply' (fabric/textile mockups), 'screen', 'overlay', 'soft_light'. All 27 Photoshop blend modes supported.
    - `adjustment_layers` AdjustmentLayers: Image adjustment parameters applied to the user's artwork before blending into the mockup. Applied after fit transformation, does not affect PSD-level adjustments.
      - `brightness` integer: Brightness adjustment (-150 to 150). 0=no change.
      - `contrast` integer: Contrast adjustment (-100 to 100). 0=no change.
      - `opacity` integer: Artwork opacity (0=fully transparent, 100=fully opaque). Default 100.
      - `saturation` integer: Saturation adjustment (-100 to 100). 0=no change, -100=grayscale.
      - `vibrance` integer: Vibrance adjustment (-100 to 100). Similar to saturation but preserves skin tones.
      - `blur` number: Gaussian blur amount (0=sharp, 100=max blur). Useful for background effects.
  - `export_options` ExportOptions: Format, size and quality of the rendered file.
    - `image_format` 'png' | 'jpg' | 'webp': Output format: 'webp' (30-70% smaller, recommended), 'png' (lossless), 'jpg' (smallest, no transparency)
    - `image_size` union: Output width in pixels (100-10000), or "original" to render a PSD template at its own size and resolution: the template's own width and, unless dpi is set, the resolution the PSD was saved with. Height auto-calculated from the source aspect ratio. Renders on an account in trial are capped at 1024: a larger width is rejected with error_code OUTPUT_RESOLUTION_LIMIT (HTTP 402) and is never silently downscaled. Add a payment method to render at full width.
      - integer
      - 'original'
    - `quality` integer: Compression quality for JPG/WebP (1-100). Ignored for PNG (always lossless). Default: 90.
    - `dpi` integer, nullable: Resolution tag stamped into the output file metadata (JPG/WebP via Exif XResolution, PNG via pHYs), e.g. 300 for print. This is metadata only: it does NOT change the pixels. Pixel dimensions are controlled by image_size: set image_size = print_size_inches * dpi for a true print-ready file (e.g. 12 in * 300 = 3600 px). Range 72-2400. Default: null (opt-in). Omitting it does not leave the file untagged: the encoder writes a default ~25.4 DPI (1 px/mm) tag. With image_size "original" and no dpi, the file carries the PSD's own resolution. All three formats carry the tag, but for maximum print-tool compatibility prefer jpg or png, because WebP stores resolution in Exif and not every viewer surfaces it.
  - `image_url` string, nullable: RAW-IMAGE MODE: a public https png/jpg URL to animate directly (general image-to-video, no render). Supply this OR (mockup_uuid + smart_objects), never both.
  - `video` VideoOptions: Animation options for a POST /renders/video request. The still is produced from the same mockup_uuid + smart_objects payload as a normal render, then animated into a short video. SudoMock picks the best video model for the image automatically; `advanced_model` is an optional override. You choose `duration_seconds` and `audio`, and the credit cost scales with both. `duration_seconds` must be one of the chosen model's allowed durations, or the endpoint returns 400 INVALID_VIDEO_DURATION otherwise. The 1..15 range here is a coarse guard; the exact allowed set depends on the model.
    - `duration_seconds` integer: Clip length in seconds chosen by the customer. Must be one of the supported durations; the endpoint rejects an unsupported value with 400. The credit cost scales with this value.
    - `audio` boolean: Generate sound with the clip. Default OFF (muted clips are cheaper). Audio increases the credit cost on models that charge an audio premium. Note: motion='showcase' always includes sound, so the endpoint treats it as audio=true and prices it accordingly.
    - `motion` 'ambient' | 'showcase': 'ambient' = subtle looping hero motion that keeps the print readable (muted unless audio=true); 'showcase' = one deliberate cinematic camera/product move, always with sound (priced as audio=true).
    - `advanced_model` string, nullable: Advanced override for the automatic quality selection. Unsupported values are rejected. null = automatic (recommended).
  - `webhook` object, nullable: Completion events (video.succeeded, video.failed) are delivered to the webhook endpoints on your account that subscribe to them. GET /api/v1/jobs/{job_id} stays the source of truth.

## Response `202`

Successful Response

- VideoRenderAcceptedResponse: Acknowledgement that a video mockup was accepted and is being produced.
  - `job_id` string, required: Identifier of the accepted job, used to poll its status.
  - `kind` 'video', required: The kind of work accepted, which is always a video.
  - `status` 'queued' | 'dispatched' | 'running' | 'succeeded' | 'failed' | 'cancelled', required: State of the job when this response was returned.
  - `status_url` string, required: Path to poll for this job's status.
  - `model` string, required: The video model chosen for this clip.
  - `outcome_tier` string, required: The quality level this clip is produced at.
  - `estimated_credits` integer, nullable: Credits this clip costs, which is null only when an accepted job's original quote is no longer known.
  - `duration_seconds` integer, required: Length of the clip in seconds.
  - `audio` boolean, required: Whether the clip is produced with sound.

---

[API](https://skmtc.dev/sudomock/apis/sudomock-api.md) · [All operations](https://skmtc.dev/sudomock/apis/sudomock-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sudomock/apis/sudomock-api/revisions/c1cc24006c60?raw)
