Course intro video output_schema: optional fields must be nullable
Bind a strict output_schema to a course-intro Format run so the intro and title card come back as typed fields. Optional keys must allow null.

For a course intro, bind an output_schema to the run so that the video and the title card come back as named fields in output, not as a list you have to sort. With strict: true, every key you do not require must still be listed and must accept null, which is why the voiceover text in the example below is typed ["string", "null"]. If the result does not fit the schema, the run can finish with media but a null output.
The schema
This is the output_schema for a course intro. SumeMediaFile# is the reference to a media file object, the same one the live-commerce example in the call docs uses. The name is yours to choose; a versioned name such as acme/course-intro/v1 lets you change the schema later without confusing old receipts.
{
"name": "acme/course-intro/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["intro_video", "title_card"],
"properties": {
"intro_video": { "$ref": "SumeMediaFile#" },
"title_card": { "$ref": "SumeMediaFile#" },
"voiceover_text": { "type": ["string", "null"] }
}
}
}What happens when the shape does not fit
A run can make real media and still not satisfy your schema. In that case it finishes completed, artifacts[] holds the files, output is null and output_error explains why. Webhook outcome is degraded. Branch on output_error before you read output, and fall back to artifacts[] and primary_output_url if your product can use a file without the field names.
primary_output_key names which key in output supplies primary_output_url. Name a key that is not in the schema or not a media field and you can end up with a primary_output_missing failure, so keep the key and the schema in step.
| Field | Type in the schema | Handling |
|---|---|---|
intro_video | SumeMediaFile#, required | Use as primary_output_key |
title_card | SumeMediaFile#, required | Show on the course page |
voiceover_text | string or null, optional | Store when present, ignore when null |
output_error | On the receipt, not in the schema | Check first; non-null means output is null |
Send it with the run
Put the schema in the body as output_schema, with primary_output_key set to intro_video. Send response_format instead only if you prefer the OpenAI-shaped alias; sending both gives 400 invalid_request. A schema outside the supported subset returns 400 output_schema_invalid with every problem in details.violations[], so you find out at create time and not after a run.
Remember that input does not reach output. If you need your course id in the result, keep it on your side next to the run id, or put it in the Idempotency-Key.
Why optional means nullable
The structured-output docs use strict mode, in which every property that appears in properties must also be required, or allowed to be null. The common mistake is to write an optional field as a plain string and leave it out of required. The schema is then outside the supported subset, and the create call fails with output_schema_invalid. Writing ["string", "null"] says the key is always present and may hold no value.
Plan for the null in your code. When voiceover_text is null, hide the transcript box and do not treat the run as failed. Test the schema with a cheap run first and look at output_schema.source on the receipt: it reads request_override when your schema was used.
Sources
Related posts
More in Formats
- Fix one wrong number: Claude Motion edit vs a Sume Format retake
Claude Motion edits a number in place. In a Sume Format run a changed word or number means a new production; a look change is a retry at about 1/20 the cost.
- Format API: webhook or polling for a run that takes 15-30 minutes
A Sume Format run returns 202 and finishes in minutes, not seconds. Take the result by signed format.run.terminal webhook or poll the run; no SSE stream.
- Spreadsheet to Format bulk queue in Node: 100-row limit and key rules
Turn a CSV of products into one bulk-runs request in Node. Items are capped at 100, concurrency at 16, and the Idempotency-Key must be new for each batch.
- Queue 100 Format runs at concurrency 16: 7 waves, one idempotency key
Sume bulk runs accept 1 to 100 items and a concurrency window of 1 to 16. The queue has no webhook, and completed does not mean all succeeded.
Written by Sume