Sume SumeMediaFile duration_ms: the 10 percent check and null
In a Sume structured output, a duration_ms must agree with the artifact's recorded length within 10 percent, or the projection fails. A null means not measured.

A duration_ms inside a SumeMediaFile in your structured output is checked against the artifact's recorded length. Where Sume recorded one, the value must agree within 10%, or the projection fails; where it recorded none, nothing is checked and null means "not measured", not zero.
The rules are on Sume's Structured output page under the URL gate. Here is what that means when you read a duration back.
What exactly is checked?
The page says the value comes off the same ledger that fills artifacts[]. A claim outside 10% is described as describing a different file, and it fails the projection rather than reaching you. The failure surfaces as output: null with output_error set; on a run over the API that makes the run failed.
The SumeMediaFile shape has duration_ms as an integer or null, meant for video and audio.
| Ledger has a length? | `duration_ms` in `output` | Result |
|---|---|---|
| Yes | Within 10% of it | Passes |
| Yes | Outside 10% | Projection fails |
| No | Anything | Not checked |
| No | null | Read as not measured |
Can I trust a duration_seconds field I declared myself?
Not in the same way. The page says a duration_seconds number you declared yourself is written by the projection; the duration_ms on the media file is the checked one. Every other value, such as ids, labels, captions and counts, is read out of media metadata and closing text, and is the run's own account of its work rather than a measurement.
How should my code read it?
Use duration_ms from the media object when you need a length to schedule or bill against, and treat null as unknown rather than zero. For a video you are about to publish, the page's own advice is to read the file, not the number beside it: ffprobe on primary_output_url takes about two seconds.
What do I put in the schema?
Reference the built-in shape with { "$ref": "SumeMediaFile#" } rather than writing your own duration_ms field. Sume-hosted media on media.sume.com has expires_at null, which is the normal case.
Sources
Related posts
More in Developers
- Sume media tools: which answer 200 and which answer 202 by default
video-inspect defaults to sync, trim, filter, compose and detach to async, and video-frames always returns 202. Defaults, the 30 s wait, and how to poll each.
- next_poll_after_seconds vs recommended_poll_interval_seconds
Which delay a Sume poller should sleep: next_poll_after_seconds, recommended_poll_interval_seconds, or retry-after. Null rules, a fallback, and read budgets.
- Sume queue capacity: max(3, concurrency x 5), and 7 jobs on Free
Sume's default queue capacity is max(3, concurrency_limit x 5). On Free that is 5 queued plus 1 processing, so a seventh live generation job gets queue_full.
- verifyWebhook returns false during a Sume secret rotation
The npm build of @sume-com/sdk 0.2.0 compares the signature header for equality, so rotation deliveries with two signatures fail. A 21-line fix.
Written by Sume