JSON schema for AI video output: 5 templates to copy
Copyable JSON Schemas for AI video output on Sume: one video, video plus copy, a poster, aspect ratios, and caption cues, all in the strict subset.

A JSON Schema for AI video output on Sume is an output_schema you bind to a Format run: the finished run's output comes back in that shape, with each media file typed as { "$ref": "SumeMediaFile#" } and checked against the media the run made. The 5 templates below fit Sume's strict subset, so they pass the check at submit.
Each template follows the rules in Sume's Structured output docs, read on 2026-09-27. Send one as output_schema on POST /v1/formats/{handle}/{slug}/runs, or nest it under json_schema in the OpenAI-shaped response_format alias with "type": "json_schema"; sending both is 400 invalid_request. Sume Format structured output explains the rules; this post gives schemas to copy.
How do I get back one finished video?
The smallest useful schema: one required media file. Send it with "primary_output_key": "video" and primary_output_url on the receipt is that file's URL. SumeMediaFile covers image, video, audio, and file, so the key name does not force a video: read type when you use it. A run that generated no media cannot fill the key, so over the API it ends failed rather than completed with an empty output.
{
"name": "acme/video-only/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["video"],
"properties": {
"video": { "$ref": "SumeMediaFile#" }
}
}
}How do I get the video plus its post copy?
Copy fields are nullable on purpose. If the run does not submit the object itself, a projection pass fills it from only two facts: the run's generated media and its closing text. It never sees your input or instruction, so prose that depends on your brief can come back null there. hashtags has no minItems, so an empty list is still legal. maxItems and pattern are enforced like every keyword you write: an eleventh hashtag, or one without #, does not satisfy the schema.
{
"name": "acme/video-with-copy/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["video", "title", "caption", "hashtags"],
"properties": {
"video": { "$ref": "SumeMediaFile#" },
"title": { "type": ["string", "null"] },
"caption": {
"type": ["string", "null"],
"description": "Post caption written for the video"
},
"hashtags": {
"type": "array",
"maxItems": 10,
"items": { "type": "string", "pattern": "^#[A-Za-z0-9_]+$" }
}
}
}
}How do I ask for a poster frame that may not exist?
A media file that may be missing is an anyOf of SumeMediaFile# and null. Put any constraint inside a branch, never next to the anyOf: siblings of anyOf and $ref carry no meaning. The URL gate admits only media the run generated, so a file the run merely uploaded fails the projection. Keep uploads out of the schema.
{
"name": "acme/video-with-poster/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["video", "poster"],
"properties": {
"video": { "$ref": "SumeMediaFile#" },
"poster": {
"anyOf": [{ "$ref": "SumeMediaFile#" }, { "type": "null" }]
}
}
}
}How do I get several aspect ratios from one run?
Name one key per ratio and share a definition through $defs, which must sit at the root of the schema. The schema only shapes how a finished run is read back, so ask for the three ratios in your instruction. Pair it with "primary_output_key": "vertical": a run that satisfies the schema but leaves that key null ends failed with primary_output_missing, while the other two may be null.
{
"name": "acme/aspect-set/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["vertical", "square", "landscape"],
"properties": {
"vertical": { "$ref": "#/$defs/maybe_video" },
"square": { "$ref": "#/$defs/maybe_video" },
"landscape": { "$ref": "#/$defs/maybe_video" }
},
"$defs": {
"maybe_video": {
"anyOf": [{ "$ref": "SumeMediaFile#" }, { "type": "null" }]
}
}
}
}How do I get timed caption lines with the video?
Objects inside arrays and inside $defs need additionalProperties: false too. Know what is checked: URLs, duration_ms on media files (within 10% of the file's recorded length), and the shape. Caption text and cue times are the run's own account of its work, grounded in what it reported but not verified against the file.
{
"name": "acme/video-with-cues/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["video", "cues"],
"properties": {
"video": { "$ref": "SumeMediaFile#" },
"cues": { "type": "array", "items": { "$ref": "#/$defs/cue" } }
},
"$defs": {
"cue": {
"type": "object",
"additionalProperties": false,
"required": ["start_ms", "end_ms", "text"],
"properties": {
"start_ms": { "type": "integer", "minimum": 0 },
"end_ms": { "type": "integer", "minimum": 0 },
"text": { "type": "string" }
}
}
}
}
}Which template should I start from?
Pick by what your record needs, then rename the keys. If an edit leaves the strict subset, the create fails with 400 output_schema_invalid and nothing is charged; the violations guide maps each details.violations[] rule to a fix.
| Template | Required keys | May be null or empty | Other keywords used |
|---|---|---|---|
| One finished video | video | Nothing | None |
| Video plus post copy | video, title, caption, hashtags | title and caption may be null; hashtags may be [] | description, maxItems, pattern |
| Optional poster frame | video, poster | poster may be null | anyOf |
| Several aspect ratios | vertical, square, landscape | All three may be null, but a null vertical fails the run when it is the primary_output_key | $defs, anyOf |
| Timed caption cues | video, cues | cues may be [] | $defs, minimum |
What if a finished run cannot fill the schema?
Over the API the run fails: status is failed, output_error says why, and artifacts[] still lists every file the run made, as Sume Format run failure codes explains code by code.
Sources
Related posts
More in Formats
- Ready-made Formats for product video: the Sume Format catalog
Sume ships ready-made Formats for product and UGC-style video and images, each callable from your backend with one HTTP request at the reserved sume handle.
- What is a Sume Format? Turn an agent thread into one API call
A Sume Format is a saved video recipe your backend calls by handle and slug. One POST runs it in a fresh sandbox and returns media plus optional typed JSON.
- How to embed AI video generation in your product with Sume Formats
To embed AI video generation, your server holds one Sume API key and runs a Format per customer, with a derived Idempotency-Key, spend cap, and webhook.
- Sume Format bulk runs: queue up to 100 renders in one request
A Sume bulk request queues 1 to 100 ordinary Format runs on the server and keeps 1 to 16 in flight. Poll one queue URL; read each child as a normal run.
Written by Sume