{
    "openapi": "3.0.2",
    "info": {
        "title": "JSON2Video API",
        "version": "2.0.0",
        "description": "Create and edit awesome videos programmatically"
    },
    "servers": [
        {
            "url": "https://api.json2video.com/v2",
            "description": "Version 2 endpoint"
        }
    ],
    "paths": {
        "/movies": {
            "get": {
                "operationId": "getMovies",
                "summary": "Get the status of your movies",
                "description": "Get the status of one of your movies by passing its project ID in the <code>project</code> (or <code>id</code>) query parameter, or list your movies within a date range. The project ID is returned in the response of POST /movies.",
                "parameters": [
                    {
                        "name": "project",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "minLength": 16,
                            "maxLength": 16
                        },
                        "description": "16-character project ID returned by POST /movies. When set, returns the status of a single movie."
                    },
                    {
                        "name": "id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "minLength": 16,
                            "maxLength": 16
                        },
                        "description": "Alias for <code>project</code>."
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        },
                        "description": "Start of the date range (ISO 8601). Defaults to the first day of the current month. Max range is 3 months. Alias: <code>date_start</code>."
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        },
                        "description": "End of the date range (ISO 8601). Defaults to the end of the current day. Alias: <code>date_end</code>."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 100
                        },
                        "description": "Maximum number of movies returned per page."
                    },
                    {
                        "name": "next_token",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pagination cursor returned by a previous call."
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "simple"
                            ]
                        },
                        "description": "When set to <code>simple</code>, the per-movie JSON payload is omitted from the response."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Movie status (single project) or paginated list of movies for the given date range.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "from": {
                                            "type": "string",
                                            "format": "date-time"
                                        },
                                        "to": {
                                            "type": "string",
                                            "format": "date-time"
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "limit": {
                                            "type": "integer"
                                        },
                                        "has_next": {
                                            "type": "boolean"
                                        },
                                        "has_prev": {
                                            "type": "boolean"
                                        },
                                        "next_token": {
                                            "type": "string",
                                            "nullable": true
                                        },
                                        "movie": {
                                            "type": "object",
                                            "description": "Present when querying a single project."
                                        },
                                        "movies": {
                                            "type": "array",
                                            "description": "Present when listing movies in a date range.",
                                            "items": {
                                                "type": "object"
                                            }
                                        },
                                        "remaining_quota": {
                                            "type": "object",
                                            "properties": {
                                                "movies": {
                                                    "type": "integer"
                                                },
                                                "drafts": {
                                                    "type": "integer"
                                                },
                                                "time": {
                                                    "type": "integer"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    }
                }
            },
            "post": {
                "operationId": "newMovie",
                "summary": "Create a new movie",
                "description": "Submit a new movie rendering job.",
                "responses": {
                    "200": {
                        "description": "Added"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/movie"
                            }
                        }
                    }
                }
            }
        },
        "/preloads": {
            "post": {
                "operationId": "newPreload",
                "summary": "Pre-generate or download a batch of assets",
                "description": "Asynchronously prepares assets that can be referenced in future movies via their public URL. The pipeline runs prepare-movie + downloads (parallel and AI lanes) and stores the final assets in the global per-client cache (shared with movies). Maximum 10 items per batch.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "preload"
                                ],
                                "properties": {
                                    "preload": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 10,
                                        "description": "Array of assets to pre-generate or download. Each item must have a unique 'id' that the client uses to match results in GET responses.",
                                        "items": {
                                            "$ref": "#/components/schemas/preloadItem"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Batch accepted; the pipeline runs asynchronously. Use GET /preloads/{preload_id} to poll status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "preload_id": {
                                            "type": "string",
                                            "description": "16-char identifier; pass to GET /preloads/{preload_id}"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request (schema error, duplicate id, type not allowed, etc.)"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "402": {
                        "description": "Insufficient credits to generate the AI assets in the batch"
                    }
                }
            }
        },
        "/preloads/{preload_id}": {
            "get": {
                "operationId": "getPreload",
                "summary": "Get the status and results of a preload batch",
                "description": "Returns the consolidated state of a batch submitted via POST /preloads. Items can be pending, running, ready or error; the batch is 'done' when all items reach a terminal state.",
                "parameters": [
                    {
                        "name": "preload_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identifier returned by POST /preloads."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Current state of the batch.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "preload_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "pending",
                                                "running",
                                                "done"
                                            ]
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time",
                                            "nullable": true
                                        },
                                        "ended_at": {
                                            "type": "string",
                                            "format": "date-time",
                                            "nullable": true
                                        },
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string"
                                                    },
                                                    "type": {
                                                        "type": "string"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "pending",
                                                            "running",
                                                            "ready",
                                                            "error"
                                                        ]
                                                    },
                                                    "url": {
                                                        "type": "string",
                                                        "format": "uri",
                                                        "description": "Public URL of the asset. When persistent=true, points to the Media library and never expires. When persistent=false, points to the temporary cache (expires 3 days after generation). This is always the original, full-quality asset; the render pipeline uses this URL."
                                                    },
                                                    "webURL": {
                                                        "type": "string",
                                                        "format": "uri",
                                                        "description": "Browser-playable derivative of the asset, for in-browser preview only (e.g. the web previewer). Present ONLY when the source uses a codec the browser cannot decode natively (e.g. ProRes/HEVC, or any pixel format with alpha): such sources are transcoded to VP9 WebM (alpha sources) or H.264 MP4 (opaque sources). For browser-friendly sources (H.264/VP8/VP9/AV1 without alpha) this field is omitted and clients should fall back to `url`. Also exposed as the template variable {{id_webURL}}. Caveat: VP9-with-alpha proxies do not play in Safari (no cross-browser alpha video codec exists); they render in Chrome/Firefox/Edge. The render pipeline never uses this field — it always renders from `url` at full quality."
                                                    },
                                                    "persistent": {
                                                        "type": "boolean",
                                                        "description": "Whether the asset has been persisted to the client's Media library. True only when the item was requested with save-to-media=true and the persistence succeeded."
                                                    },
                                                    "expires_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "ISO date-time when the URL stops being available. Null when persistent=true. Approximately 3 days after the asset was generated when persistent=false."
                                                    },
                                                    "warning": {
                                                        "type": "string",
                                                        "description": "Optional warning emitted when save-to-media=true could not be honored. Possible values: quota_blocked (Media storage is blocked for the account, the asset is served from the temporary cache instead), persist_failed (unexpected internal error, the asset is still available in the cache).",
                                                        "enum": [
                                                            "quota_blocked",
                                                            "persist_failed"
                                                        ]
                                                    },
                                                    "duration": {
                                                        "type": "number"
                                                    },
                                                    "width": {
                                                        "type": "integer"
                                                    },
                                                    "height": {
                                                        "type": "integer"
                                                    },
                                                    "size": {
                                                        "type": "integer"
                                                    },
                                                    "task": {
                                                        "type": "string"
                                                    },
                                                    "error": {
                                                        "type": "string"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid preload_id format"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "404": {
                        "description": "preload not found (or not owned by this client)"
                    }
                }
            }
        },
        "/templates": {
            "get": {
                "operationId": "getTemplates",
                "summary": "List templates or get a single template",
                "description": "Without query parameters, returns the list of templates owned by the authenticated client. When <code>id</code> is provided, returns a single template. The <code>format</code> parameter can transform the returned movie variables into Make.com field definitions or a JSON Schema.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "LerKrmBfiqaIgBuacLWn"
                        },
                        "description": "Template ID — the random 20-character alphanumeric string returned by <code>POST /templates</code> (not the template name). When set, returns the matching template instead of the list."
                    },
                    {
                        "name": "tag",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Filter the list to templates tagged with this value."
                    },
                    {
                        "name": "scopes",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "movie"
                        },
                        "description": "Comma-separated list of scopes to load for a single template (e.g. <code>movie,prompt</code>). Only applies when <code>id</code> is provided."
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "make",
                                "jsonschema",
                                "summary"
                            ]
                        },
                        "description": "Output format for the template's variables: <code>make</code> returns Make.com field definitions, <code>jsonschema</code> returns a JSON Schema, <code>summary</code> omits the movie payload."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Template or list of templates.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "template": {
                                            "$ref": "#/components/schemas/template"
                                        },
                                        "templates": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/template"
                                            }
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "404": {
                        "description": "Template not found"
                    }
                }
            },
            "post": {
                "operationId": "saveTemplate",
                "summary": "Create, update or duplicate a template",
                "description": "Creates a new template, updates an existing one (when <code>id</code> is provided) or duplicates a template into the current client's account (when <code>action=duplicate</code>). The <code>movie</code> payload accepts either a movie object or a stringified JSON object, and supports referencing another template via <code>{ \"template\": \"<templateId>\" }</code> with optional <code>variables</code> overrides.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "LerKrmBfiqaIgBuacLWn"
                        },
                        "description": "Template ID — the random 20-character alphanumeric string returned by <code>POST /templates</code> (not the template name). Required when updating or duplicating; omit to create a new template (the API will generate a new 20-character ID)."
                    },
                    {
                        "name": "action",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "duplicate"
                            ]
                        },
                        "description": "When set to <code>duplicate</code>, copies the template identified by <code>id</code> into the current client's account."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "Human-readable template name. Used only as a label in the dashboard list — this is <strong>not</strong> the ID. The API generates a random 20-character <code>templateId</code> on creation; that ID (returned in the response) is what must be used to render, fetch, update, or delete the template."
                                    },
                                    "tags": {
                                        "oneOf": [
                                            {
                                                "type": "string",
                                                "description": "Comma-separated list of tags."
                                            },
                                            {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        ]
                                    },
                                    "movie": {
                                        "description": "Movie object, a stringified movie JSON, or a reference to another template via <code>{ \"template\": \"<templateId>\", \"variables\": {...} }</code>.",
                                        "oneOf": [
                                            {
                                                "$ref": "#/components/schemas/movie"
                                            },
                                            {
                                                "type": "string"
                                            }
                                        ]
                                    },
                                    "prompt": {
                                        "type": "string",
                                        "description": "Optional AI prompt associated with the template."
                                    },
                                    "variables": {
                                        "type": "object",
                                        "description": "Only used with <code>action=duplicate</code>: variables deep-merged into the source template's <code>movie.variables</code>."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Template saved or duplicated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "templateId": {
                                            "type": "string",
                                            "description": "Random 20-character alphanumeric ID assigned to the template. Use this value (not <code>name</code>) in the movie's <code>template</code> field when rendering, and in the <code>id</code> query parameter of subsequent template operations.",
                                            "example": "LerKrmBfiqaIgBuacLWn"
                                        },
                                        "name": {
                                            "type": "string",
                                            "description": "The template name as stored (echoed back on duplicate; <code>name</code> + <code>\" (custom)\"</code> when not overridden)."
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid payload (missing fields, bad JSON, etc.)"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions or template not owned by client"
                    },
                    "404": {
                        "description": "Template not found"
                    }
                }
            },
            "delete": {
                "operationId": "deleteTemplate",
                "summary": "Delete a template",
                "description": "Deletes the template owned by the authenticated client. The associated S3 movie file is removed on a best-effort basis.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "LerKrmBfiqaIgBuacLWn"
                        },
                        "description": "Template ID to delete — the random 20-character alphanumeric string returned by <code>POST /templates</code> (not the template name)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Template deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing template ID"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "500": {
                        "description": "Error deleting the template"
                    }
                }
            }
        },
        "/templates/library": {
            "get": {
                "operationId": "getTemplateLibrary",
                "summary": "List the public template library",
                "description": "Returns the curated gallery of ready-to-use templates published by JSON2Video. Each entry includes an example video, a thumbnail and the template's dimensions. Use the returned <code>id</code> to render a template or to copy it into your own account via <code>POST /templates</code> with <code>action=duplicate</code>. The template's <code>movie</code> payload is never returned by this endpoint.",
                "parameters": [
                    {
                        "name": "tags",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Comma-separated list of tags. In addition to every template tagged <code>published</code>, the response includes any template tagged with one of these values."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of library templates.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "count": {
                                            "type": "integer"
                                        },
                                        "templates": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/libraryTemplate"
                                            }
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "404": {
                        "description": "Error retrieving templates"
                    }
                }
            }
        },
        "/media": {
            "get": {
                "operationId": "getMediaStorage",
                "summary": "Get media storage usage",
                "description": "Returns the current storage usage for the authenticated client's media library, including free allowance, weekly credit cost for the overage and whether storage is currently blocked.",
                "responses": {
                    "200": {
                        "description": "Media storage info.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "storage": {
                                            "type": "object",
                                            "properties": {
                                                "used_bytes": {
                                                    "type": "integer"
                                                },
                                                "free_allowance": {
                                                    "type": "integer",
                                                    "description": "Free storage allowance in bytes (50 MB)."
                                                },
                                                "credits_per_week": {
                                                    "type": "integer",
                                                    "description": "Weekly credits charged for storage above the free allowance."
                                                },
                                                "blocked": {
                                                    "type": "boolean"
                                                },
                                                "blocked_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "nullable": true
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    }
                }
            }
        },
        "/media/file": {
            "get": {
                "operationId": "getMediaFile",
                "summary": "Get a single media file",
                "description": "Returns metadata (URL, size, content type, status, thumbnail, etc.) for a single file in the client's media library.",
                "parameters": [
                    {
                        "name": "path",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Path to the file relative to the media root (e.g. <code>folder/subfolder/file.jpg</code> or <code>file.jpg</code>)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "File metadata.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "file": {
                                            "$ref": "#/components/schemas/mediaFile"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid or missing path"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "404": {
                        "description": "File not found"
                    }
                }
            },
            "post": {
                "operationId": "requestMediaUpload",
                "summary": "Request a presigned upload URL",
                "description": "Reserves a slot in the client's media library and returns a short-lived presigned PUT URL the client can use to upload the file directly to S3. Files placed in the <code>temp</code> folder are eligible for automatic lifecycle deletion and do not count towards storage quota.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "name",
                                    "contentType",
                                    "size"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "description": "File name. Non-alphanumeric characters except <code>._-</code> are replaced with <code>_</code>."
                                    },
                                    "contentType": {
                                        "type": "string",
                                        "description": "MIME type of the file (e.g. <code>image/png</code>, <code>video/mp4</code>)."
                                    },
                                    "size": {
                                        "type": "integer",
                                        "description": "File size in bytes. Maximum 500 MB.",
                                        "minimum": 1,
                                        "maximum": 524288000
                                    },
                                    "folder": {
                                        "type": "string",
                                        "description": "Destination folder. Use <code>temp</code> for non-billable temporary uploads. Defaults to the root folder."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Presigned upload URL.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "uploadUrl": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "S3 presigned PUT URL."
                                        },
                                        "fileUrl": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "Public URL where the file will be served once uploaded."
                                        },
                                        "expiresIn": {
                                            "type": "integer",
                                            "description": "Validity of the presigned URL in seconds."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid payload"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions or storage blocked"
                    },
                    "409": {
                        "description": "A file with the same name already exists in the destination folder"
                    },
                    "413": {
                        "description": "File exceeds the maximum allowed size (500 MB)"
                    }
                }
            },
            "put": {
                "operationId": "moveMediaFile",
                "summary": "Move a media file to a different folder",
                "description": "Moves the file from <code>folder</code> to <code>destination</code> within the client's media library, preserving its name. Moving to/from the <code>temp</code> folder updates the billable storage counter accordingly.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "name",
                                    "destination"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "folder": {
                                        "type": "string",
                                        "description": "Source folder. Defaults to the root folder."
                                    },
                                    "destination": {
                                        "type": "string",
                                        "description": "Destination folder. Use an empty string for the root folder."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "File moved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid payload"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "404": {
                        "description": "Source file not found"
                    },
                    "409": {
                        "description": "A file with the same name already exists in the destination folder"
                    }
                }
            },
            "delete": {
                "operationId": "deleteMediaFile",
                "summary": "Delete a media file",
                "description": "Deletes the file from both S3 and the metadata store. If the file was non-temporary and uploaded, the storage counter is decreased accordingly.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "folder": {
                                        "type": "string",
                                        "description": "Folder containing the file. Defaults to the root folder."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "File deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid payload"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    },
                    "404": {
                        "description": "File not found"
                    }
                }
            }
        },
        "/media/folder": {
            "get": {
                "operationId": "getMediaFolder",
                "summary": "List a folder's contents or the folder tree",
                "description": "Returns the contents of a folder (files, sub-folders, paginated, with filters) or, when <code>tree=true</code>, a flat list of folders with aggregated stats.",
                "parameters": [
                    {
                        "name": "path",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "/"
                        },
                        "description": "Folder path. Use <code>/</code> for the root folder. Alias: <code>folder</code>."
                    },
                    {
                        "name": "tree",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        },
                        "description": "When <code>true</code>, returns a flat list of folders with file count and total size instead of the folder contents."
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "image",
                                "video",
                                "audio",
                                "other"
                            ]
                        },
                        "description": "Filter files by media type (derived from the content-type)."
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Case-insensitive substring filter on the file name."
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        },
                        "description": "Zero-based page index for pagination."
                    },
                    {
                        "name": "page_size",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 20
                        },
                        "description": "Page size for pagination."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Folder contents or folder tree.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "type": "object",
                                            "description": "Folder contents (default mode).",
                                            "properties": {
                                                "success": {
                                                    "type": "boolean"
                                                },
                                                "path": {
                                                    "type": "string"
                                                },
                                                "total_size": {
                                                    "type": "integer",
                                                    "description": "Sum of bytes of all direct files in the folder, before filters."
                                                },
                                                "total_files": {
                                                    "type": "integer",
                                                    "description": "Count of all direct files in the folder, before filters."
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "description": "Count of files matching the filters."
                                                },
                                                "page": {
                                                    "type": "integer"
                                                },
                                                "page_size": {
                                                    "type": "integer"
                                                },
                                                "folders": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    }
                                                },
                                                "files": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/mediaFile"
                                                    }
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "description": "Folder tree (when <code>tree=true</code>).",
                                            "properties": {
                                                "success": {
                                                    "type": "boolean"
                                                },
                                                "tree": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "path": {
                                                                "type": "string"
                                                            },
                                                            "files": {
                                                                "type": "integer"
                                                            },
                                                            "size": {
                                                                "type": "integer"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    }
                }
            },
            "post": {
                "operationId": "createMediaFolder",
                "summary": "Create a folder",
                "description": "Creates an empty folder in the client's media library. Folder names are sanitized to alphanumeric characters plus <code>/_-</code>.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "folder"
                                ],
                                "properties": {
                                    "folder": {
                                        "type": "string",
                                        "description": "Folder path (e.g. <code>marketing/2025</code>)."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Folder created (or already existed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "message": {
                                            "type": "string"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid or missing folder name"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    }
                }
            },
            "delete": {
                "operationId": "deleteMediaFolder",
                "summary": "Delete an empty folder",
                "description": "Deletes a folder. The folder must be empty; the special <code>temp</code> folder and the root folder cannot be deleted.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "folder"
                                ],
                                "properties": {
                                    "folder": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Folder deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "timestamp": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid folder, folder not empty, or protected folder (root, temp)"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    },
                    "403": {
                        "description": "Insufficient permissions"
                    }
                }
            }
        },
        "/subtitles": {
            "post": {
                "operationId": "renderSubtitles",
                "summary": "Convert an SRT to a styled ASS subtitle file",
                "description": "Converts a timed SRT into the exact styled ASS file that the render pipeline (<code>render-scenes</code> / <code>render-movie</code>) would burn into a video, using the word-by-word highlighting that drives every subtitle style. Because an SRT only carries per-phrase (cue) timing, per-word timings are <strong>approximated</strong> by splitting each cue's duration across its words proportionally to word length; the result is faithful to the render but is not exact word-level timing. Known behaviours, all matching the render path: (a) on-screen lines are re-grouped using <code>max-words-per-line</code> plus sentence punctuation, so the output does <strong>not</strong> preserve the SRT's own line breaks; (b) the last word of a cue lingers on screen until the first word of the next cue, so subtitles persist across silence gaps between cues; (c) the ASS embeds only the font <em>name</em>, so for a faithful local preview the same fonts must be installed (one of the predefined font families, or a custom font installed under the name <code>CustomFont</code> when a <code>font-url</code> is configured); (d) the SRT must be provided as <strong>inline text</strong>, not a URL, in this version; (e) <code>translate</code> is accepted in the settings but is <strong>not applied</strong> in this version (no audio is transcribed). The returned <code>ass</code> string has no UTF-8 BOM; clients should save the file as UTF-8 (optionally prepending a BOM) before feeding it to libass. This endpoint is pure CPU: it performs no rendering, downloads no fonts and makes no network calls.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                    "srt"
                                ],
                                "properties": {
                                    "srt": {
                                        "type": "string",
                                        "description": "Raw SRT content, inline. Must be the actual subtitle text, not a URL."
                                    },
                                    "resolution": {
                                        "type": "string",
                                        "description": "Sets the canvas size used to compute default font size, margins and <code>PlayResX</code>/<code>PlayResY</code>. Use <code>custom</code> (or omit it) to set a custom size with the <code>width</code> and <code>height</code> properties.",
                                        "default": "full-hd",
                                        "enum": [
                                            "sd",
                                            "hd",
                                            "full-hd",
                                            "squared",
                                            "instagram-story",
                                            "instagram-feed",
                                            "twitter-landscape",
                                            "twitter-portrait",
                                            "4k",
                                            "custom"
                                        ]
                                    },
                                    "width": {
                                        "type": "integer",
                                        "description": "Canvas width in pixels. Used when <code>resolution</code> is <code>custom</code> or omitted.",
                                        "default": 1920,
                                        "minimum": 16,
                                        "maximum": 8192
                                    },
                                    "height": {
                                        "type": "integer",
                                        "description": "Canvas height in pixels. Used when <code>resolution</code> is <code>custom</code> or omitted.",
                                        "default": 1080,
                                        "minimum": 16,
                                        "maximum": 8192
                                    },
                                    "subtitles": {
                                        "type": "object",
                                        "description": "The subtitles element configuration (without <code>type</code>). Provides the styling applied to the generated ASS.",
                                        "additionalProperties": false,
                                        "properties": {
                                            "language": {
                                                "type": "string",
                                                "description": "Accepted for compatibility with the subtitles element but ignored: no transcription happens in this endpoint."
                                            },
                                            "settings": {
                                                "type": "object",
                                                "description": "Subtitle styling settings. These are the same settings as the <code>subtitles</code> movie element's <code>settings</code> object.",
                                                "default": {},
                                                "additionalProperties": false,
                                                "properties": {
                                                    "style": {
                                                        "type": "string",
                                                        "description": "Style of the subtitles. Check the tutorial for more details.",
                                                        "enum": [
                                                            "classic",
                                                            "classic-progressive",
                                                            "classic-one-word",
                                                            "boxed-line",
                                                            "boxed-word"
                                                        ],
                                                        "default": "classic"
                                                    },
                                                    "font-url": {
                                                        "type": "string",
                                                        "description": "URL to the font file to use for the subtitles. The font file must be in TTF format. The <code>font-family</code> property must match the font family name in the font file."
                                                    },
                                                    "font-family": {
                                                        "type": "string",
                                                        "description": "Font family of the subtitles. One of the font families below or a custom font family name if <code>font-url</code> is provided.",
                                                        "default": "Arial",
                                                        "enum": [
                                                            "Arial",
                                                            "Arial Bold",
                                                            "Oswald Bold",
                                                            "NotoSans Bold",
                                                            "Simplified Chinese",
                                                            "Traditional Chinese",
                                                            "Japanese",
                                                            "Korean",
                                                            "Korean Bold",
                                                            "Thai"
                                                        ]
                                                    },
                                                    "font-weight": {
                                                        "type": "string",
                                                        "description": "Font weight of the subtitles. Check the tutorial for more details.",
                                                        "example": "600"
                                                    },
                                                    "font-size": {
                                                        "type": "integer",
                                                        "description": "Font size of the subtitles. Usual sizes are between 90 and 150. Defaults to 5% of the movie width."
                                                    },
                                                    "word-color": {
                                                        "type": "string",
                                                        "description": "Color of the spoken word",
                                                        "default": "#FFFF00"
                                                    },
                                                    "line-color": {
                                                        "type": "string",
                                                        "description": "Color of the rest of words in the line",
                                                        "default": "#FFFFFF"
                                                    },
                                                    "outline-color": {
                                                        "type": "string",
                                                        "description": "Outline color of the subtitles",
                                                        "default": "#000000"
                                                    },
                                                    "outline-width": {
                                                        "type": "integer",
                                                        "description": "Width of the outline",
                                                        "default": 0
                                                    },
                                                    "shadow-color": {
                                                        "type": "string",
                                                        "description": "Shadow color of the subtitles",
                                                        "default": "#000000"
                                                    },
                                                    "shadow-offset": {
                                                        "type": "integer",
                                                        "description": "Offset of the shadow",
                                                        "default": 0
                                                    },
                                                    "box-color": {
                                                        "type": "string",
                                                        "description": "Color of the box behind the subtitles. Depending on the style, it can be the background color of the spoken word or the full line",
                                                        "default": "#000000"
                                                    },
                                                    "position": {
                                                        "type": "string",
                                                        "description": "Position of the subtitles",
                                                        "default": "bottom-center",
                                                        "enum": [
                                                            "top-left",
                                                            "top-center",
                                                            "top-right",
                                                            "center-left",
                                                            "center-center",
                                                            "center-right",
                                                            "bottom-left",
                                                            "bottom-center",
                                                            "bottom-right",
                                                            "mid-bottom-center",
                                                            "mid-top-center",
                                                            "custom"
                                                        ]
                                                    },
                                                    "x": {
                                                        "type": "integer",
                                                        "description": "X coordinate of the subtitles",
                                                        "default": 0
                                                    },
                                                    "y": {
                                                        "type": "integer",
                                                        "description": "Y coordinate of the subtitles",
                                                        "default": 0
                                                    },
                                                    "max-words-per-line": {
                                                        "type": "integer",
                                                        "description": "Maximum number of words per line",
                                                        "default": 4
                                                    },
                                                    "all-caps": {
                                                        "type": "boolean",
                                                        "description": "Makes the subtitles all caps",
                                                        "default": false
                                                    },
                                                    "keywords": {
                                                        "type": "array",
                                                        "description": "Keywords provides additional vocabulary to the transcription process. Use it to improve the accuracy of the transcription of non-standard words or phrases.",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "replace": {
                                                        "type": "object",
                                                        "description": "Replaces words with the specified replacement. Useful to correct the transcription of non-standard words or phrases."
                                                    },
                                                    "translate": {
                                                        "type": "string",
                                                        "description": "Target language code for subtitle translation. Accepted for compatibility with the subtitles element but <strong>not applied</strong> in this version."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The generated styled ASS subtitle file.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "type": "boolean"
                                        },
                                        "width": {
                                            "type": "integer",
                                            "description": "Canvas width used to generate the ASS."
                                        },
                                        "height": {
                                            "type": "integer",
                                            "description": "Canvas height used to generate the ASS."
                                        },
                                        "ass": {
                                            "type": "string",
                                            "description": "ASS file content (no UTF-8 BOM)."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid request (missing or empty SRT, SRT provided as a URL, no valid cues, or invalid width/height)"
                    },
                    "401": {
                        "description": "Invalid or missing API key"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "template": {
                "title": "Template",
                "type": "object",
                "description": "A saved movie template owned by the authenticated client.",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Template ID — a random 20-character alphanumeric string generated by the API at creation time. This is the value to use in the movie's <code>template</code> field when rendering.",
                        "example": "LerKrmBfiqaIgBuacLWn"
                    },
                    "name": {
                        "type": "string",
                        "description": "Human-readable template name. Used only as a label in the dashboard list — it is <strong>not</strong> the ID used when rendering or referencing the template via the API."
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "movie": {
                        "description": "Movie JSON associated with the template. Returned as a string or object depending on storage.",
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/movie"
                            },
                            {
                                "type": "string"
                            }
                        ]
                    },
                    "variables": {
                        "description": "Variables of the template, formatted according to the <code>format</code> query parameter when one is provided.",
                        "oneOf": [
                            {
                                "type": "object"
                            },
                            {
                                "type": "array"
                            }
                        ]
                    },
                    "prompt": {
                        "type": "string",
                        "description": "Optional AI prompt associated with the template."
                    },
                    "ai_prompt": {
                        "type": "string",
                        "description": "Legacy AI prompt field."
                    },
                    "owner": {
                        "type": "boolean",
                        "description": "Whether the authenticated client owns the template."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "libraryTemplate": {
                "title": "Library Template",
                "type": "object",
                "description": "A template from the public library returned by <code>GET /templates/library</code>. Unlike the <code>template</code> schema it never includes the movie payload, and it adds preview media URLs and frame dimensions.",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Template ID — use it to render the template or to duplicate it into your account.",
                        "example": "LerKrmBfiqaIgBuacLWn"
                    },
                    "name": {
                        "type": "string",
                        "description": "Human-readable template name."
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "width": {
                        "type": "integer",
                        "description": "Frame width in pixels."
                    },
                    "height": {
                        "type": "integer",
                        "description": "Frame height in pixels."
                    },
                    "aspect_ratio": {
                        "type": "number",
                        "description": "<code>width / height</code>, rounded to 2 decimals."
                    },
                    "prompt": {
                        "type": "boolean",
                        "description": "Whether the template ships with an AI prompt."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "video_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL of an example render (MP4)."
                    },
                    "thumbnail_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL of a preview thumbnail (JPG)."
                    }
                }
            },
            "mediaFile": {
                "title": "Media File",
                "type": "object",
                "description": "A file in the client's media library.",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "folder": {
                        "type": "string",
                        "description": "Folder containing the file, or <code>/</code> for the root folder."
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "image",
                            "video",
                            "audio",
                            "other"
                        ],
                        "description": "Media type derived from the content type."
                    },
                    "contentType": {
                        "type": "string"
                    },
                    "size": {
                        "type": "integer",
                        "description": "File size in bytes."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "thumbnailUrl": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "uploaded",
                            "error"
                        ],
                        "description": "<code>pending</code> while a presigned upload is awaiting the actual S3 PUT; <code>uploaded</code> once the file is in S3."
                    },
                    "temporary": {
                        "type": "boolean",
                        "description": "True for files in the <code>temp</code> folder; these don't count towards storage quota and may be auto-deleted."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "movie": {
                "title": "Movie",
                "type": "object",
                "description": "Object defining the movie to be rendered",
                "additionalProperties": false,
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Movie ID string. It must be unique per project",
                        "default": "@randomString"
                    },
                    "comment": {
                        "type": "string",
                        "description": "Used for adding your comments"
                    },
                    "draft": {
                        "type": "boolean",
                        "deprecated": true,
                        "description": "Deprecated. This property is ignored and has no effect. Watermarking is now controlled automatically based on the account plan.",
                        "default": true,
                        "enum": [
                            true,
                            false
                        ]
                    },
                    "template": {
                        "type": "string",
                        "description": "ID of the template to be used for the movie. This is the random 20-character alphanumeric ID returned by <code>POST /templates</code> (also exposed as <code>id</code> in <code>GET /templates</code>), <strong>not</strong> the human-readable template name. The template name is only a label shown in the dashboard list.",
                        "example": "LerKrmBfiqaIgBuacLWn"
                    },
                    "variables": {
                        "type": "object",
                        "description": "Variables of the template. Variable names can only contain letters, numbers and underscores",
                        "default": {},
                        "example": {
                            "myVariable": "myValue",
                            "myOtherVariable": true,
                            "myThirdVariable": 123
                        }
                    },
                    "resolution": {
                        "type": "string",
                        "description": "Set the movie size based on common use cases. Use <code>custom</code> to set a custom size with the <code>width</code> and <code>height</code> properties",
                        "default": "custom",
                        "enum": [
                            "sd",
                            "hd",
                            "full-hd",
                            "squared",
                            "instagram-story",
                            "instagram-feed",
                            "twitter-landscape",
                            "twitter-portrait",
                            "custom"
                        ]
                    },
                    "width": {
                        "type": "integer",
                        "description": "Width of the movie. Only applicable if resolution is set to <code>custom</code>",
                        "dependsOn": {
                            "resolution": "custom"
                        },
                        "default": 640,
                        "minimum": 50,
                        "maximum": 3840,
                        "example": 640
                    },
                    "height": {
                        "type": "integer",
                        "description": "Height of the movie. Only applicable if resolution is set to <code>custom</code>",
                        "dependsOn": {
                            "resolution": "custom"
                        },
                        "default": 360,
                        "minimum": 50,
                        "maximum": 3840,
                        "example": 360
                    },
                    "quality": {
                        "type": "string",
                        "description": "Quality of the final rendered movie. Use it for speeding up the rendering process. <code>low</code> is the lowest quality, <code>high</code> is the highest quality",
                        "enum": [
                            "low",
                            "medium",
                            "high"
                        ],
                        "default": "high"
                    },
                    "fps": {
                        "hidden": true,
                        "type": "integer",
                        "description": "Frames per second",
                        "default": 25
                    },
                    "client-data": {
                        "hidden": false,
                        "type": "object",
                        "description": "Key-value pairs that will be included in the response of the GET requests and in the webhook payloads. Client data is intended to pass on information to the following steps of the workflow.",
                        "default": {}
                    },
                    "settings": {
                        "hidden": true,
                        "type": "object",
                        "description": "Deprecated"
                    },
                    "preload": {
                        "type": "array",
                        "description": "Assets to be downloaded before the main elements. Each preload item must have a unique 'id' that can be referenced in elements using template variables like {{id_url}}, {{id_webURL}}, {{id_duration}}, {{id_width}} or {{id_height}}. {{id_webURL}} is only defined when the source uses a codec the browser cannot decode natively (ProRes/HEVC or alpha pixel formats) and resolves to a browser-playable proxy (VP9 WebM for alpha, H.264 MP4 otherwise); for browser-friendly sources it is absent and {{id_url}} should be used. VP9-with-alpha proxies do not play in Safari.",
                        "items": {
                            "$ref": "#/components/schemas/preloadItem"
                        }
                    },
                    "scenes": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/scene"
                        }
                    },
                    "elements": {
                        "type": "array",
                        "items": {
                            "oneOf": [
                                {
                                    "$ref": "#/components/schemas/video"
                                },
                                {
                                    "$ref": "#/components/schemas/image"
                                },
                                {
                                    "$ref": "#/components/schemas/text"
                                },
                                {
                                    "$ref": "#/components/schemas/html"
                                },
                                {
                                    "$ref": "#/components/schemas/component"
                                },
                                {
                                    "$ref": "#/components/schemas/audio"
                                },
                                {
                                    "$ref": "#/components/schemas/voice"
                                },
                                {
                                    "$ref": "#/components/schemas/audiogram"
                                },
                                {
                                    "$ref": "#/components/schemas/subtitles"
                                }
                            ],
                            "discriminator": {
                                "propertyName": "type"
                            }
                        }
                    },
                    "cache": {
                        "type": "boolean",
                        "description": "Use the cached version of the movie if its available",
                        "default": true
                    },
                    "exports": {
                        "type": "array",
                        "description": "You can define different types of exports for your movie. Check the <a href=\"https://json2video.com/docs/tutorial/exports\">documentation</a> for more information",
                        "items": {
                            "export": {
                                "title": "export",
                                "description": "Export type",
                                "type": "object"
                            }
                        }
                    }
                },
                "example": {
                    "comment": "MyProject",
                    "resolution": "full-hd",
                    "scenes": [
                        {
                            "elements": [
                                {
                                    "type": "video",
                                    "src": "https://example.com/path/to/my/video.mp4"
                                }
                            ]
                        }
                    ]
                }
            },
            "scene": {
                "title": "Scene",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "ID of the scene",
                        "default": "@randomString"
                    },
                    "condition": {
                        "type": "string",
                        "description": "OPTIONAL. Condition to be met for the scene to be rendered. If the value is false or empty string, the scene is removed from the movie"
                    },
                    "import": {
                        "type": "string",
                        "description": "ID of the scene to import. The scene will be imported as a new scene and the elements will be added to the current scene",
                        "example": "mySceneTemplate"
                    },
                    "variables": {
                        "type": "object",
                        "description": "Local variables of the scene. Variable names can only contain letters, numbers and underscores",
                        "default": {},
                        "example": {
                            "myVariable": "myValue",
                            "myOtherVariable": true,
                            "myThirdVariable": 123
                        }
                    },
                    "comment": {
                        "type": "string",
                        "description": "Used for adding your comments"
                    },
                    "background-color": {
                        "type": "string",
                        "control": "color",
                        "description": "A hexadecimal representation of a color or 'transparent'",
                        "example": "#FF0000",
                        "default": "#000000"
                    },
                    "duration": {
                        "type": "number",
                        "format": "float",
                        "description": "Sets the scene duration in seconds. A value of -1 means that the scene lasts enough to contain all its elements",
                        "default": -1
                    },
                    "preload": {
                        "type": "array",
                        "description": "Assets to be downloaded before the main elements. Each preload item must have a unique 'id' that can be referenced in elements using template variables like {{id_url}}, {{id_webURL}}, {{id_duration}}, {{id_width}} or {{id_height}}. {{id_webURL}} is only defined when the source uses a codec the browser cannot decode natively (ProRes/HEVC or alpha pixel formats) and resolves to a browser-playable proxy (VP9 WebM for alpha, H.264 MP4 otherwise); for browser-friendly sources it is absent and {{id_url}} should be used. VP9-with-alpha proxies do not play in Safari.",
                        "items": {
                            "$ref": "#/components/schemas/preloadItem"
                        }
                    },
                    "elements": {
                        "type": "array",
                        "items": {
                            "oneOf": [
                                {
                                    "$ref": "#/components/schemas/video"
                                },
                                {
                                    "$ref": "#/components/schemas/image"
                                },
                                {
                                    "$ref": "#/components/schemas/text"
                                },
                                {
                                    "$ref": "#/components/schemas/html"
                                },
                                {
                                    "$ref": "#/components/schemas/component"
                                },
                                {
                                    "$ref": "#/components/schemas/audio"
                                },
                                {
                                    "$ref": "#/components/schemas/voice"
                                },
                                {
                                    "$ref": "#/components/schemas/audiogram"
                                },
                                {
                                    "$ref": "#/components/schemas/subtitles"
                                }
                            ],
                            "discriminator": {
                                "propertyName": "type"
                            }
                        }
                    },
                    "transition": {
                        "type": "object",
                        "hidden": true,
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "default": "xfade",
                                "enum": [
                                    "xfade"
                                ]
                            },
                            "style": {
                                "type": "string",
                                "default": "fade",
                                "example": "circleopen",
                                "enum": [
                                    "fade",
                                    "wipeleft",
                                    "wiperight",
                                    "wipeup",
                                    "wipedown",
                                    "slideleft",
                                    "slideright",
                                    "slideup",
                                    "slidedown",
                                    "circlecrop",
                                    "rectcrop",
                                    "distance",
                                    "fadeblack",
                                    "fadewhite",
                                    "radial",
                                    "smoothleft",
                                    "smoothright",
                                    "smoothup",
                                    "smoothdown",
                                    "circleopen",
                                    "circleclose",
                                    "vertopen",
                                    "vertclose",
                                    "horzopen",
                                    "horzclose",
                                    "dissolve",
                                    "pixelize",
                                    "diagtl",
                                    "diagtr",
                                    "diagbl",
                                    "diagbr",
                                    "hlslice",
                                    "hrslice",
                                    "vuslice",
                                    "vdslice",
                                    "hblur",
                                    "fadegrays",
                                    "wipetl",
                                    "wipetr",
                                    "wipebl",
                                    "wipebr",
                                    "squeezeh",
                                    "squeezev"
                                ]
                            },
                            "duration": {
                                "type": "number",
                                "description": "Duration of the transition in seconds",
                                "format": "float",
                                "example": 1.5
                            }
                        }
                    },
                    "cache": {
                        "type": "boolean",
                        "default": true,
                        "description": "Use the cached version of the scene if its available"
                    }
                }
            },
            "BaseElement": {
                "title": "BaseElement",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "ID of the element",
                        "default": "@randomString"
                    },
                    "condition": {
                        "type": "string",
                        "description": "OPTIONAL. Condition to be met for the element to be rendered. If the value is false or empty string, the element is removed from the scene"
                    },
                    "variables": {
                        "type": "object",
                        "description": "Local variables of the element. Variable names can only contain letters, numbers and underscores",
                        "default": {},
                        "example": {
                            "myVariable": "myValue",
                            "myOtherVariable": true,
                            "myThirdVariable": 123
                        }
                    },
                    "comment": {
                        "type": "string",
                        "description": "Used for adding your comments"
                    },
                    "duration": {
                        "type": "number",
                        "default": -1,
                        "example": 7.3,
                        "format": "float",
                        "description": "Element's duration in seconds. A value of -1 auto calculates the duration based on the asset/file intrinsic length. A value of -2 sets the element duration to the parent scene or element duration"
                    },
                    "start": {
                        "type": "number",
                        "format": "float",
                        "default": 0,
                        "description": "Element's starting time in seconds relative to the container scene or the movie if the element is in the Movie's elements array."
                    },
                    "extra-time": {
                        "type": "number",
                        "default": 0,
                        "example": 0.5,
                        "format": "float",
                        "description": "Element's time span added after the playback."
                    },
                    "z-index": {
                        "type": "number",
                        "default": 0,
                        "minimum": -99,
                        "maximum": 99,
                        "example": 3,
                        "format": "integer",
                        "description": "Element's z-index. Use this property to reorganize the layering of the elements like in HTML"
                    },
                    "cache": {
                        "type": "boolean",
                        "default": true,
                        "example": false,
                        "format": "boolean",
                        "description": "Use the cached version of the element if its available"
                    },
                    "fade-in": {
                        "type": "number",
                        "format": "float",
                        "minimum": 0,
                        "description": "Adds a fade in effect to the element. Value in seconds."
                    },
                    "fade-out": {
                        "type": "number",
                        "format": "float",
                        "minimum": 0,
                        "description": "Adds a fade out effect to the element. Value in seconds."
                    },
                    "save-to-media": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the resulting asset is persisted to the client's Media library (the Drive) as a permanent file accessible at <code>https://media.json2video.com/{client_id}/files/generated/{type}/{name}.{ext}</code>. Only supported on generable element types: <code>image</code>, <code>video</code>, <code>audio</code>, <code>voice</code>, <code>html</code>, <code>component</code>. Silently ignored on non-supported types (e.g. <code>text</code>, <code>subtitles</code>, <code>audiogram</code>). Also accepted on <code>POST /preloads</code> items and on <code>movie.preload[]</code> entries. Default behavior (false): the asset stays in the temporary 3-day cache. See <a href=\"https://json2video.com/docs/v2/guides/advanced/save-to-media\">Persisting generated assets</a>."
                    }
                }
            },
            "AudioElement": {
                "title": "AudioElement",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "muted": {
                        "type": "boolean",
                        "default": false,
                        "description": "Mutes the audio"
                    },
                    "volume": {
                        "type": "number",
                        "description": "Volume gain of the audio. A value of 1 means no gain. Higher values increase the volume. Values lower than 1 decrease the volume",
                        "default": 1,
                        "minimum": 0,
                        "maximum": 10
                    },
                    "speed": {
                        "type": "number",
                        "description": "Playback speed multiplier applied to the asset. A value of 1 plays at normal speed, values greater than 1 play faster (e.g. 1.5 is 50% faster) and values lower than 1 play slower (e.g. 0.5 is half speed). For video the frames are retimed; for audio the tempo is changed while preserving pitch. The element duration shortens or lengthens accordingly. Note: 'seek' is measured in the original asset timeline (it is applied before the speed change).",
                        "default": 1,
                        "minimum": 0.5,
                        "maximum": 4
                    }
                }
            },
            "VisualElement": {
                "title": "VisualElement",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "position": {
                        "type": "string",
                        "description": "Sets the element position in the scene. A value of 'custom' sets a custom position based on the provided 'x' and 'y' properties. Edge and corner positions are offset by a 5% margin from the canvas edges; 'center-center' (alias 'center') is the exact canvas center with no margin.",
                        "enum": [
                            "top-left",
                            "top-center",
                            "top-right",
                            "center-left",
                            "center-center",
                            "center",
                            "center-right",
                            "bottom-left",
                            "bottom-center",
                            "bottom-right",
                            "custom"
                        ],
                        "default": "custom"
                    },
                    "x": {
                        "type": "number",
                        "format": "integer",
                        "dependsOn": {
                            "position": "custom"
                        },
                        "description": "Sets the horizontal position of the element in the scene. The value <code>0</code> is on the left side",
                        "default": 0
                    },
                    "y": {
                        "type": "number",
                        "format": "integer",
                        "dependsOn": {
                            "position": "custom"
                        },
                        "description": "Sets the vertical position of the element in the scene. The value <code>0</code> is on the top side",
                        "default": 0
                    },
                    "resize": {
                        "type": "string",
                        "description": "Sets the resize mode of the element. A value of 'cover' or 'fill' stretches the element to cover the entire movie canvas. A value of 'fit' or 'contain' stretches the element to fit the movie canvas. If set, the 'width' and 'height' properties are ignored",
                        "enum": [
                            "cover",
                            "fill",
                            "fit",
                            "contain"
                        ]
                    },
                    "width": {
                        "type": "integer",
                        "description": "Sets the width of the element, scaling up or down if required. A value of '-1' means to keep the aspect ratio",
                        "minimum": -1,
                        "default": -1
                    },
                    "height": {
                        "type": "integer",
                        "description": "Sets the height of the element, scaling up or down if required. A value of '-1' means to keep the aspect ratio",
                        "minimum": -1,
                        "default": -1
                    },
                    "scale": {
                        "type": "object",
                        "description": "This property is deprecated. Use 'width' and 'height' instead",
                        "additionalProperties": false,
                        "properties": {
                            "width": {
                                "type": "integer",
                                "description": "Sets the width for scaling the element",
                                "minimum": -1,
                                "default": -1
                            },
                            "height": {
                                "type": "integer",
                                "description": "Sets the height for scaling the element",
                                "minimum": -1,
                                "default": -1
                            }
                        }
                    },
                    "rotate": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "angle": {
                                "type": "number",
                                "description": "Sets the angle of rotation",
                                "minimum": -360,
                                "maximum": 360,
                                "default": 0
                            },
                            "speed": {
                                "type": "number",
                                "description": "Sets the time it takes to rotate the provided angle. A zero value means no movement",
                                "minimum": 0,
                                "default": 0
                            }
                        },
                        "required": [
                            "angle"
                        ]
                    },
                    "crop": {
                        "type": "object",
                        "additionalProperties": false,
                        "description": "Crops the element",
                        "properties": {
                            "x": {
                                "type": "integer",
                                "description": "Sets the left point of croping",
                                "default": 0
                            },
                            "y": {
                                "type": "integer",
                                "description": "Sets the top point of croping",
                                "default": 0
                            },
                            "width": {
                                "type": "integer",
                                "description": "Sets the width of the croping"
                            },
                            "height": {
                                "type": "integer",
                                "description": "Sets the height of the croping"
                            }
                        },
                        "required": [
                            "width",
                            "height"
                        ]
                    },
                    "motion-blur": {
                        "type": "number",
                        "description": "Intensity of directional motion blur applied during x/y keyframe motion. 0 disables (default). 1 is the standard (≈ half-frame shutter analog), higher values increase the blur. Auto-detects motion segments from x/y keyframes and applies an avgblur with size derived from per-frame velocity. Only takes effect during motion windows; stationary frames are not blurred. Does not affect renders without keyframes or without 'motion-blur' set.",
                        "minimum": 0,
                        "maximum": 10,
                        "default": 0
                    },
                    "focus": {
                        "type": "string",
                        "description": "When combined with 'width' and 'height', scales the asset preserving its aspect ratio so that it covers the target dimensions, and crops the excess on the side opposite to the focus point. Equivalent to CSS 'object-fit: cover' + 'object-position'. Only applies when both 'width' and 'height' are set to positive values, and only to 'video' and 'image' elements. Ignored if 'resize' is also set. Supports keyframes on 'width' and 'height' (focus is preserved per frame).",
                        "enum": [
                            "center",
                            "top-left",
                            "top-center",
                            "top-right",
                            "center-left",
                            "center-center",
                            "center-right",
                            "bottom-left",
                            "bottom-center",
                            "bottom-right"
                        ]
                    },
                    "zoom": {
                        "type": "integer",
                        "description": "Animates the element from its native size (1×) to a final scale factor of <code>1 + |zoom| × 0.09</code> over the element's duration. So <code>zoom: 10</code> reaches 1.9× (the maximum), <code>zoom: 5</code> reaches 1.45×, <code>zoom: 1</code> reaches 1.09×. The sign controls the direction of the animation: positive values animate from 1× → final (zoom-in), negative values animate from final → 1× (zoom-out); the scale factor never drops below 1×. <code>zoom: 0</code> disables the effect. Combine with the <code>pan</code> property to choose the anchor point of the zoom. For true per-frame zoom (including factors below 1×) use <code>zoom</code> inside <code>keyframes</code> instead.",
                        "minimum": -10,
                        "maximum": 10
                    },
                    "pan": {
                        "type": "string",
                        "description": "Pans the element to the specified direction. If <code>zoom</code> property is not specified, the effect is a non-zooming pan",
                        "enum": [
                            "left",
                            "top",
                            "right",
                            "bottom",
                            "top-left",
                            "top-right",
                            "bottom-left",
                            "bottom-right"
                        ]
                    },
                    "pan-distance": {
                        "type": "number",
                        "format": "float",
                        "description": "Is the distance of the panning effect. A higher value means a larger panning movement (higher speed)",
                        "minimum": 0.01,
                        "default": 0.1,
                        "maximum": 0.5
                    },
                    "pan-crop": {
                        "type": "boolean",
                        "description": "Enable or disable the crop effect when panning",
                        "default": true
                    },
                    "chroma-key": {
                        "type": "object",
                        "description": "Allows to define a color (or a range of colors) that will be converted to transparent",
                        "properties": {
                            "color": {
                                "type": "string",
                                "description": "Set the color for which alpha will be set to 0 (full transparency)",
                                "example": "#00b140"
                            },
                            "tolerance": {
                                "type": "integer",
                                "description": "Makes the selection more or less sensitive to changes in color. A value of 1 will select only the provided color. A value of 100 will select all colors, so the full canvas",
                                "minimum": 1,
                                "maximum": 100,
                                "default": 25
                            }
                        },
                        "required": [
                            "color"
                        ]
                    },
                    "correction": {
                        "type": "object",
                        "description": "Allows to adjust the contrast, brightness, saturation and gamma of the element",
                        "additionalProperties": false,
                        "properties": {
                            "contrast": {
                                "type": "number",
                                "description": "Adjust the contrast",
                                "minimum": -1000,
                                "maximum": 1000,
                                "default": 1
                            },
                            "brightness": {
                                "type": "number",
                                "description": "Adjust the brightness",
                                "minimum": -1,
                                "maximum": 1,
                                "default": 0
                            },
                            "saturation": {
                                "type": "number",
                                "description": "Adjust the saturation",
                                "minimum": 0,
                                "maximum": 3,
                                "default": 1
                            },
                            "gamma": {
                                "type": "number",
                                "description": "Adjust the gamma",
                                "minimum": 0.1,
                                "maximum": 10,
                                "default": 1
                            },
                            "blur": {
                                "type": "number",
                                "description": "Apply gaussian blur. A value of 0 means no blur. A value of 10 means maximum blur.",
                                "minimum": 0,
                                "maximum": 50,
                                "default": 0
                            }
                        }
                    },
                    "flip-horizontal": {
                        "type": "boolean",
                        "description": "Flips the element horizontally",
                        "default": false
                    },
                    "flip-vertical": {
                        "type": "boolean",
                        "description": "Flips the element vertically",
                        "default": false
                    },
                    "mask": {
                        "type": "object",
                        "description": "A predefined mask name or a URL to a PNG or video file defining a mask for the element. For external mask files, black color is transparent, white is solid, and gray tones in between are partially transparent. Predefined masks names are: 'circle'.",
                        "properties": {
                            "src": {
                                "type": "string",
                                "description": "URL to the mask file"
                            },
                            "seek": {
                                "type": "number",
                                "description": "Seek to the specified time in seconds relative to the begining of the asset. Use negative values to seek backwards",
                                "format": "float",
                                "default": 0
                            }
                        }
                    },
                    "keyframes": {
                        "type": "array",
                        "description": "Animates element properties over time. Each keyframe defines a target value at a given time; the engine interpolates between consecutive keyframes using the specified easing function. Animatable properties are: 'x', 'y', 'width', 'height' and 'zoom'. If the first keyframe time is not 0, an implicit keyframe at time 0 is prepended using the element's current values; an implicit keyframe at the element's end time is appended if missing. 'zoom' keyframes are only valid for 'video' and 'image' elements and cannot be combined with 'width'/'height' keyframes or with the 'pan' property.",
                        "items": {
                            "$ref": "#/components/schemas/Keyframe"
                        },
                        "example": [
                            {
                                "time": 0,
                                "x": 0,
                                "easing": "linear"
                            },
                            {
                                "time": 2,
                                "x": 500,
                                "easing": "ease-out-elastic"
                            }
                        ]
                    }
                }
            },
            "Keyframe": {
                "title": "Keyframe",
                "type": "object",
                "additionalProperties": false,
                "description": "A single keyframe defining target values for animatable properties at a given time. Only the properties you want to animate need to be set; unspecified properties inherit from the previous keyframe (or the element's static value for the first keyframe).",
                "properties": {
                    "time": {
                        "oneOf": [
                            {
                                "type": "number",
                                "format": "float"
                            },
                            {
                                "type": "string"
                            }
                        ],
                        "description": "Time of the keyframe in seconds, relative to the element's start. Accepts a number, a negative number (interpreted as seconds before the element ends, e.g. -1 = 1 second before the element ends), or a percentage string (e.g. '50%' = 50% of the element's duration). Times beyond the element's duration are clamped; keyframes with a time earlier than the previous one are skipped.",
                        "example": 1.5
                    },
                    "x": {
                        "type": "number",
                        "description": "Target horizontal position in pixels (only meaningful when 'position' is 'custom' or resolved to custom by an x/y keyframe)."
                    },
                    "y": {
                        "type": "number",
                        "description": "Target vertical position in pixels (only meaningful when 'position' is 'custom' or resolved to custom by an x/y keyframe)."
                    },
                    "width": {
                        "type": "number",
                        "description": "Target width in pixels. A value of -1 preserves the aspect ratio relative to the 'height' keyframe value."
                    },
                    "height": {
                        "type": "number",
                        "description": "Target height in pixels. A value of -1 preserves the aspect ratio relative to the 'width' keyframe value."
                    },
                    "zoom": {
                        "type": "number",
                        "description": "Target per-frame zoom level. Maps to a scale factor of <code>1 + zoom × 0.09</code> applied centered on the element: <code>zoom: 0</code> = 1× (no zoom), <code>zoom: 10</code> = 1.9× (max zoom-in), <code>zoom: -10</code> = 0.10× (max zoom-out). Unlike the static <code>zoom</code> property, negative values here produce a true scale factor below 1×. The crop is always centered — there is no per-keyframe anchor/focus. Only valid for 'video' and 'image' elements and incompatible with 'width'/'height' keyframes and with the 'pan' property.",
                        "minimum": -10,
                        "maximum": 10
                    },
                    "easing": {
                        "type": "string",
                        "description": "Easing function applied to the transition from the previous keyframe to this one. Acts as a default for every animated property in this keyframe; can be overridden per property via 'easing-x', 'easing-y', 'easing-width', 'easing-height' or 'easing-zoom'.",
                        "default": "linear",
                        "enum": [
                            "linear",
                            "ease",
                            "ease-in-sine",
                            "ease-out-sine",
                            "ease-in-out-sine",
                            "ease-in-quad",
                            "ease-out-quad",
                            "ease-in-out-quad",
                            "ease-in-cubic",
                            "ease-out-cubic",
                            "ease-in-out-cubic",
                            "ease-in-quart",
                            "ease-out-quart",
                            "ease-in-out-quart",
                            "ease-in-quint",
                            "ease-out-quint",
                            "ease-in-out-quint",
                            "ease-in-expo",
                            "ease-out-expo",
                            "ease-in-out-expo",
                            "ease-in-circ",
                            "ease-out-circ",
                            "ease-in-out-circ",
                            "ease-in-back",
                            "ease-out-back",
                            "ease-in-out-back",
                            "ease-in-elastic",
                            "ease-out-elastic",
                            "ease-in-out-elastic",
                            "ease-in-bounce",
                            "ease-out-bounce",
                            "ease-in-out-bounce"
                        ]
                    },
                    "easing-x": {
                        "type": "string",
                        "description": "Overrides 'easing' for the 'x' property only. See 'easing' for the list of accepted values."
                    },
                    "easing-y": {
                        "type": "string",
                        "description": "Overrides 'easing' for the 'y' property only. See 'easing' for the list of accepted values."
                    },
                    "easing-width": {
                        "type": "string",
                        "description": "Overrides 'easing' for the 'width' property only. See 'easing' for the list of accepted values."
                    },
                    "easing-height": {
                        "type": "string",
                        "description": "Overrides 'easing' for the 'height' property only. See 'easing' for the list of accepted values."
                    },
                    "easing-zoom": {
                        "type": "string",
                        "description": "Overrides 'easing' for the 'zoom' property only. See 'easing' for the list of accepted values."
                    }
                },
                "required": [
                    "time"
                ]
            },
            "CaptureProperty": {
                "title": "CaptureProperty",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "capture": {
                        "type": "object",
                        "description": "Browser capture settings",
                        "additionalProperties": false,
                        "properties": {
                            "width": {
                                "type": "integer",
                                "description": "Viewport width",
                                "default": 640,
                                "minimum": 50,
                                "maximum": 1920
                            },
                            "height": {
                                "type": "integer",
                                "description": "Viewport height",
                                "default": 360,
                                "minimum": 50,
                                "maximum": 1920
                            },
                            "duration": {
                                "type": "number",
                                "format": "float",
                                "description": "Screen recording duration in seconds. Use 0 to take a screenshot",
                                "default": 0,
                                "minimum": 0,
                                "maximum": 10
                            }
                        },
                        "required": [
                            "width",
                            "height"
                        ]
                    }
                }
            },
            "preloadItem": {
                "title": "Preload Item",
                "description": "A single preload entry: an asset to be downloaded. Allowed types: image, video, audio, voice, text, html, component.",
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/video"
                    },
                    {
                        "$ref": "#/components/schemas/image"
                    },
                    {
                        "$ref": "#/components/schemas/audio"
                    },
                    {
                        "$ref": "#/components/schemas/voice"
                    },
                    {
                        "$ref": "#/components/schemas/text"
                    },
                    {
                        "$ref": "#/components/schemas/html"
                    },
                    {
                        "$ref": "#/components/schemas/component"
                    }
                ],
                "discriminator": {
                    "propertyName": "type"
                }
            },
            "video": {
                "title": "Video",
                "allOf": [
                    {
                        "type": "object",
                        "required": [
                            "type"
                        ],
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "video"
                                ]
                            },
                            "src": {
                                "type": "string",
                                "format": "uri",
                                "description": "URL to the asset file. Videos can be in MP4, MKV, MOV but MP4 is recommended."
                            }
                        }
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "loop": {
                                "type": "integer",
                                "minimum": -1,
                                "example": -1,
                                "description": "Sets the number of loops the video to play. Use -1 for an infinite loop. The default value of 1 plays the video just once."
                            },
                            "seek": {
                                "type": "number",
                                "description": "Seek to the specified time in seconds relative to the begining of the asset. Use negative values to seek backwards",
                                "format": "float",
                                "default": 0
                            }
                        }
                    },
                    {
                        "$ref": "#/components/schemas/AudioElement"
                    }
                ]
            },
            "image": {
                "title": "Image",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "image"
                                ]
                            },
                            "src": {
                                "type": "string",
                                "format": "uri",
                                "description": "URL to the asset file. Images can be in JPG, PNG, GIF or any common image format."
                            }
                        }
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    }
                ]
            },
            "text": {
                "title": "Text",
                "description": "Creates a text element of a given style",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "text"
                                ]
                            },
                            "style": {
                                "type": "string",
                                "control": "component-picker",
                                "description": "Style of the text element. Check all available text style at <a href='https://json2video.com/docs/resources/text/'>https://json2video.com/resources/text/</a>",
                                "example": "003",
                                "default": "001"
                            },
                            "text": {
                                "type": "string",
                                "description": "Text to be printed. The text string does not accept HTML formatting.",
                                "example": "Lorem ipsum dolor sit amet"
                            },
                            "settings": {
                                "type": "object",
                                "control": "component-settings",
                                "dependsOn": {
                                    "style": "__not_empty__"
                                },
                                "description": "Text formatting settings. In general, these are CSS properties such as <code>font-size</code>, <code>colour</code> or <code>font-weight</code>. See the styles to confirm which properties are available.",
                                "default": {},
                                "example": {
                                    "font-size": "60px",
                                    "color": "#FF0000"
                                }
                            },
                            "width": {
                                "type": "integer",
                                "description": "Desired text element width. A value of '-1' inherits movie width",
                                "minimum": -1,
                                "maximum": 1920,
                                "default": -1
                            },
                            "height": {
                                "type": "integer",
                                "description": "Desired text element height. A value of '-1' inherits movie height",
                                "minimum": -1,
                                "maximum": 1080,
                                "default": -1
                            }
                        },
                        "required": [
                            "type",
                            "text"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "duration": {
                                "type": "number",
                                "format": "float",
                                "default": -2,
                                "minimum": -2,
                                "example": -1,
                                "description": "Element's duration in seconds. A value of -1 auto calculates the duration based on the asset/file intrinsic length. A value of -2 sets the element duration to the parent scene or element duration"
                            }
                        }
                    }
                ]
            },
            "component": {
                "title": "Component",
                "description": "Creates an element based on the specified feature",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "component"
                                ]
                            },
                            "component": {
                                "type": "string",
                                "control": "component-picker",
                                "description": "ID of the Component element. Check all available components in the <a href='https://json2video.com/docs/resources/basic/'>library</a>",
                                "example": "basic/001"
                            },
                            "settings": {
                                "type": "object",
                                "control": "component-settings",
                                "dependsOn": {
                                    "component": "__not_empty__"
                                },
                                "description": "Settings to be passed to the component"
                            },
                            "width": {
                                "type": "integer",
                                "description": "Desired component element width. A value of '-1' inherits movie width",
                                "minimum": -1,
                                "maximum": 1920,
                                "default": -1
                            },
                            "height": {
                                "type": "integer",
                                "description": "Desired component element height. A value of '-1' inherits movie height",
                                "minimum": -1,
                                "maximum": 1080,
                                "default": -1
                            }
                        },
                        "required": [
                            "type",
                            "component"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "duration": {
                                "type": "number",
                                "format": "float",
                                "default": -2,
                                "minimum": -2,
                                "example": -1,
                                "description": "Element's duration in seconds. A value of -1 auto calculates the duration based on the asset/file intrinsic length. A value of -2 sets the element duration to the parent scene or element duration"
                            }
                        }
                    }
                ]
            },
            "html": {
                "title": "HTML",
                "description": "Creates a video recording or a screenshot of the provided HTML snippet",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "html"
                                ]
                            },
                            "html": {
                                "type": "string",
                                "description": "HTML snippet to render. Compatible with HTML5, CSS3 and Javascript",
                                "example": "&lt;h1&gt;Hello world&lt;/h1&gt;"
                            },
                            "src": {
                                "type": "string",
                                "description": "URL to the web page"
                            },
                            "wait": {
                                "type": "number",
                                "description": "Time in seconds to wait before taking the screenshot",
                                "default": 2,
                                "maximum": 5,
                                "minimum": 0
                            },
                            "tailwindcss": {
                                "type": "boolean",
                                "description": "Enables usage of TailwindCSS for the HTML snippet",
                                "default": false,
                                "example": true
                            },
                            "width": {
                                "type": "integer",
                                "description": "Desired text element width. A value of <code>-1</code> means inherits scenes or movie width",
                                "minimum": -1,
                                "maximum": 1920,
                                "default": -1
                            },
                            "height": {
                                "type": "integer",
                                "description": "Desired text element height. A value of <code>-1</code> means inherits scenes or movie height",
                                "minimum": -1,
                                "maximum": 1920,
                                "default": -1
                            }
                        },
                        "required": [
                            "type"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "duration": {
                                "type": "number",
                                "format": "float",
                                "default": -2,
                                "minimum": -2,
                                "example": -1,
                                "description": "Element's duration in seconds. A value of -1 auto calculates the duration based on the asset/file intrinsic length. A value of -2 sets the element duration to the parent scene or element duration"
                            }
                        }
                    }
                ]
            },
            "audio": {
                "title": "Audio",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "audio"
                                ]
                            },
                            "src": {
                                "type": "string",
                                "format": "uri",
                                "description": "URL to the asset file. Audios can be in MP3, WAV or any common audio format."
                            }
                        }
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/AudioElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "loop": {
                                "type": "integer",
                                "minimum": -1,
                                "example": -1,
                                "description": "Sets the number of loops the video to play. Use -1 for an infinite loop. The default value of 1 plays the video just once."
                            },
                            "seek": {
                                "type": "number",
                                "description": "Seek to the specified time in seconds relative to the begining of the asset. Use negative values to seek backwards",
                                "format": "float",
                                "default": 0
                            }
                        }
                    }
                ]
            },
            "voice": {
                "title": "Voice",
                "description": "Creates a voice audio element from the provided text",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "voice"
                                ]
                            },
                            "text": {
                                "type": "string",
                                "description": "The sentence or sentences to be converted to voice audio",
                                "control": "voice-generator"
                            },
                            "voice": {
                                "type": "string",
                                "description": "The voice name to be used. Check <a href=\"/docs/tutorial/voice-elements/\">available voices</a>."
                            },
                            "model": {
                                "type": "string",
                                "description": "The text-to-speech model to use (e.g. azure, elevenlabs)."
                            },
                            "connection": {
                                "type": "string",
                                "description": "Connection ID for a third-party TTS provider. If specified, the API Key in the connection will be used. If not specified, the default API Key will be used and credits may be deducted."
                            }
                        },
                        "required": [
                            "type",
                            "text"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/AudioElement"
                    }
                ]
            },
            "audiogram": {
                "title": "Audiogram",
                "description": "Visualizes the audio of the scene or movie as an audiogram",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "audiogram"
                                ]
                            },
                            "color": {
                                "type": "string",
                                "description": "Color of the audiogram waves in hexadecimal format"
                            },
                            "opacity": {
                                "type": "number",
                                "format": "float",
                                "description": "Opacity of the audiogram",
                                "minimum": 0,
                                "maximum": 1,
                                "default": 0.5
                            },
                            "width": {
                                "type": "integer",
                                "description": "Desired audiogram element width. A value of '-1' inherits movie width",
                                "minimum": -1,
                                "maximum": 1920,
                                "default": -1
                            },
                            "height": {
                                "type": "integer",
                                "description": "Desired audiogram element height. A value of '-1' inherits movie height",
                                "minimum": -1,
                                "maximum": 1080,
                                "default": -1
                            },
                            "amplitude": {
                                "type": "number",
                                "format": "float",
                                "description": "Relative amplitude of the audiogram",
                                "minimum": 0,
                                "maximum": 10,
                                "default": 5
                            }
                        },
                        "required": [
                            "type"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/BaseElement"
                    },
                    {
                        "$ref": "#/components/schemas/VisualElement"
                    },
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "duration": {
                                "type": "number",
                                "format": "float",
                                "default": -2,
                                "minimum": -2,
                                "example": -1,
                                "description": "Element's duration in seconds. A value of -1 auto calculates the duration based on the asset/file intrinsic length. A value of -2 sets the element duration to the parent scene or element duration"
                            }
                        }
                    }
                ]
            },
            "subtitles": {
                "title": "Subtitles",
                "description": "Adds subtitles to the scene or movie by transcribing the voice audio.",
                "allOf": [
                    {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "subtitles"
                                ]
                            },
                            "comment": {
                                "type": "string",
                                "description": "Use it for your comments"
                            },
                            "language": {
                                "type": "string",
                                "description": "Language of the audio. Use <code>auto</code> to let the API detect the language automatically.",
                                "default": "auto",
                                "enum": [
                                    "auto",
                                    "en",
                                    "bg",
                                    "ca",
                                    "cs",
                                    "da",
                                    "nl",
                                    "en-AU",
                                    "en-GB",
                                    "en-NZ",
                                    "en-IN",
                                    "en-US",
                                    "et",
                                    "fr",
                                    "fi",
                                    "nl-BE",
                                    "de",
                                    "de-CH",
                                    "el",
                                    "hi",
                                    "hi-Latn",
                                    "hu",
                                    "id",
                                    "it",
                                    "ja",
                                    "ko",
                                    "lv",
                                    "lt",
                                    "ms",
                                    "no",
                                    "pl",
                                    "pt",
                                    "pt-BR",
                                    "ro",
                                    "ru",
                                    "sk",
                                    "es",
                                    "es-419",
                                    "sv",
                                    "th",
                                    "tr",
                                    "uk",
                                    "vi",
                                    "zh",
                                    "zh-TW"
                                ]
                            },
                            "model": {
                                "type": "string",
                                "description": "Model to use for transcription. Accepted values: <code>default</code> (Deepgram), <code>whisper</code> (OpenAI) and <code>elevenlabs</code> (ElevenLabs Scribe). If no model is provided, a default model is used."
                            },
                            "captions": {
                                "type": "string",
                                "description": "Captions to use as subtitles. The string can be a URL to a file with the captions or the actual captions content properly encoded. Supported formats are SRT, VTT or ASS. If this property is ommited, the subtitles will be generated automatically from the audio."
                            },
                            "settings": {
                                "type": "object",
                                "description": "Settings to customize the subtitles.",
                                "default": {},
                                "additionalProperties": false,
                                "properties": {
                                    "style": {
                                        "type": "string",
                                        "description": "Style of the subtitles. Check the tutorial for more details.",
                                        "enum": [
                                            "classic",
                                            "classic-progressive",
                                            "classic-one-word",
                                            "boxed-line",
                                            "boxed-word"
                                        ],
                                        "default": "classic"
                                    },
                                    "font-url": {
                                        "type": "string",
                                        "description": "URL to the font file to use for the subtitles. The font file must be in TTF format. The <code>font-family</code> property must match the font family name in the font file."
                                    },
                                    "font-family": {
                                        "type": "string",
                                        "description": "Font family of the subtitles. One of the font families below or a custom font family name if <code>font-url</code> is provided.",
                                        "default": "Arial",
                                        "enum": [
                                            "Arial",
                                            "Arial Bold",
                                            "Oswald Bold",
                                            "NotoSans Bold",
                                            "Simplified Chinese",
                                            "Traditional Chinese",
                                            "Japanese",
                                            "Korean",
                                            "Korean Bold",
                                            "Thai"
                                        ]
                                    },
                                    "font-weight": {
                                        "type": "string",
                                        "description": "Font weight of the subtitles. Check the tutorial for more details.",
                                        "example": "600"
                                    },
                                    "font-size": {
                                        "type": "integer",
                                        "description": "Font size of the subtitles. Usual sizes are between 90 and 150. Defaults to 5% of the movie width."
                                    },
                                    "word-color": {
                                        "type": "string",
                                        "description": "Color of the spoken word",
                                        "default": "#FFFF00"
                                    },
                                    "line-color": {
                                        "type": "string",
                                        "description": "Color of the rest of words in the line",
                                        "default": "#FFFFFF"
                                    },
                                    "outline-color": {
                                        "type": "string",
                                        "description": "Outline color of the subtitles",
                                        "default": "#000000"
                                    },
                                    "outline-width": {
                                        "type": "integer",
                                        "description": "Width of the outline",
                                        "default": 0
                                    },
                                    "shadow-color": {
                                        "type": "string",
                                        "description": "Shadow color of the subtitles",
                                        "default": "#000000"
                                    },
                                    "shadow-offset": {
                                        "type": "integer",
                                        "description": "Offset of the shadow",
                                        "default": 0
                                    },
                                    "box-color": {
                                        "type": "string",
                                        "description": "Color of the box behind the subtitles. Depending on the style, it can be the background color of the spoken word or the full line",
                                        "default": "#000000"
                                    },
                                    "position": {
                                        "type": "string",
                                        "description": "Position of the subtitles",
                                        "default": "bottom-center",
                                        "enum": [
                                            "top-left",
                                            "top-center",
                                            "top-right",
                                            "center-left",
                                            "center-center",
                                            "center-right",
                                            "bottom-left",
                                            "bottom-center",
                                            "bottom-right",
                                            "mid-bottom-center",
                                            "mid-top-center",
                                            "custom"
                                        ]
                                    },
                                    "x": {
                                        "type": "integer",
                                        "description": "X coordinate of the subtitles",
                                        "default": 0
                                    },
                                    "y": {
                                        "type": "integer",
                                        "description": "Y coordinate of the subtitles",
                                        "default": 0
                                    },
                                    "max-words-per-line": {
                                        "type": "integer",
                                        "description": "Maximum number of words per line",
                                        "default": 4
                                    },
                                    "all-caps": {
                                        "type": "boolean",
                                        "description": "Makes the subtitles all caps",
                                        "default": false
                                    },
                                    "keywords": {
                                        "type": "array",
                                        "description": "Keywords provides additional vocabulary to the transcription process. Use it to improve the accuracy of the transcription of non-standard words or phrases.",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "replace": {
                                        "type": "object",
                                        "description": "Replaces words with the specified replacement. Useful to correct the transcription of non-standard words or phrases."
                                    },
                                    "translate": {
                                        "type": "string",
                                        "description": "Target language code for subtitle translation. The audio will be transcribed in its original language and then the transcription will be translated to this language. Example: <code>es</code> for Spanish, <code>fr</code> for French."
                                    }
                                }
                            }
                        },
                        "required": [
                            "type"
                        ]
                    }
                ]
            }
        }
    }
}
