Highlight Clips
Overview
Highlight clips are short MP4s cut from a hosted video around its most quotable moments. The moments come from the video’s AI insights: each verbatim quote the insights pass picked becomes one clip, padded so no words are cut off.
Highlights are part of the video, like its poster and hover previews. They are listed on Video.highlights, served through the video’s CDN with signed URLs, and deleted with the video. Use them for social posts, newsletter teasers, or a “best moments” row under your player.
Each clip is rendered at the codec and resolution of the video’s top rendition, so a clip never looks better or worse than the video itself. VP9 ladders render their clips as H.264, because MP4 cannot carry VP9.
Two ways to get them
| Path | When the clips are cut |
|---|---|
| GenerateHighlights | On the call. The video needs ready insights. |
highlights on CreateUpload, CreateFromUrl or CreateMultipartUpload | Automatically, once the video’s insights are ready. Requires auto_captions: true and auto_insights: true. |
On an existing video
Call GenerateHighlights on any ready hosted video that has ready insights. If it has none yet, generate insights from its captions first.
{
"id": "vid_a1b2c3d4e5f6g7",
"language": "eng",
"config": { "max_count": 3 }
}The call returns the new highlights, each pending, and lists them on Video.highlights straight away.
At upload time
Ask for highlights on the same request that asks for captions and insights. The clips are cut as soon as the insights are ready, with no second call.
{
"app_id": "app_k1l2m3n4o5",
"url": "https://example.com/talk.mp4",
"auto_captions": true,
"auto_insights": true,
"highlights": { "enabled": true }
}Without auto_insights: true the request is rejected with invalid_argument, code parameter_incompatible on highlights. If you already called GenerateHighlights on the video by the time its insights are ready, the upload-time request is skipped: it never replaces or re-bills a set you made yourself.
In the dashboard, tick Also cut highlight clips under the insights option on the upload and import-from-URL forms. On a video’s page, the Highlights card has a Generate highlights button once the video has ready insights.
Choose the clips
Every field is optional. Omitted fields take their defaults.
| Field | Type | Description |
|---|---|---|
enabled | boolean | Upload-time only: true cuts the highlights automatically once the insights are ready. Ignored by GenerateHighlights, which always cuts them. |
max_count | integer | Maximum number of clips, 1 to 10. Default 5. |
min_seconds | number | Shortest clip in seconds, 1 to 300. Default 8. A video shorter than this yields one clip of the whole video. |
max_seconds | number | Longest clip in seconds, 1 to 300, and not below min_seconds. Default 60. |
padding_seconds | number | Seconds added before and after each quote so words are not cut off, 0 to 10. Default 1.5. |
The clips are chosen the same way every time for the same insights:
- Each quote that lies at least partly inside the video becomes one window.
- The window is padded by
padding_secondson both sides and kept inside the video. - A window shorter than
min_secondsis extended forward tomin_seconds, or backward when it would run past the end. A window longer thanmax_secondsis cut atmax_secondsfrom its start. - Overlapping windows are merged into one clip, titled with the earliest quote.
- If more than
max_countremain, the longest are kept, ties going to the earlier one. A merged window holds several quotes close together, so length is the best signal of a dense moment. - Clips come back in the order they occur in the video.
The highlight object
{
"id": "hl_a1b2c3d4e5f6g7",
"start_seconds": 18.5,
"end_seconds": 31.5,
"title": "Patience is the secret ingredient.",
"status": "ready",
"playback_url": "https://cdn.example.com/outputs/vid_a1b2c3d4e5f6g7/highlights/hl_a1b2c3d4e5f6g7/job_a1b2c3d4e5f6.mp4?token=abc",
"poster_url": "https://cdn.example.com/outputs/vid_a1b2c3d4e5f6g7/highlights/hl_a1b2c3d4e5f6g7/job_a1b2c3d4e5f6_poster_0.jpg?token=abc",
"duration_seconds": 13,
"job_id": "job_a1b2c3d4e5f6",
"language": "eng",
"created_at": "2026-10-31T10:00:00Z"
}status moves from pending to ready or failed. playback_url and poster_url are present only once the clip is ready, and follow the video’s poster_url rules: signed and expiring on token-auth apps, absent for a private video without a signing key, computed per request and never stored. title is the quote, shortened to at most 120 characters. The full attribute list is in The highlight object.
Watch for them or get a webhook
The clips render in the background. Poll Retrieve a video, use Watch, or subscribe to the two webhook events. Exactly one of them fires per set, once every clip is ready or failed:
| Event | When it fires |
|---|---|
video.highlights.ready | At least one clip of the set rendered. |
video.highlights.failed | No clip of the set rendered, or an upload-time request was refused. |
Both carry the Video with its highlights; failed ones carry error_code. Like every Video webhook payload, it leaves out the request-time URLs. Call Retrieve a video for fresh playback_url and poster_url values.
Regenerating
While any highlight of the video is pending, GenerateHighlights returns the current set and bills nothing new. A retry is always safe.
Once every highlight is ready or failed, a new call replaces the set: the old highlights are removed from Video.highlights and their files are deleted. Use this to try different settings, such as a lower max_count or a longer min_seconds.
When a clip fails
A failed highlight carries an error_code:
| Code | Meaning |
|---|---|
highlight_render_failed | The clip job failed or was canceled without its own code, or completed without a usable file. |
highlight_job_refused | The clip job was never created, for a reason that has no public code of its own. |
| The job’s own code | The clip job failed with a code of its own, for example input_not_found. |
| The refusal’s code | Your account refused the clip job, for example queue_limit_exceeded or billing_past_due. |
An upload-time request that is refused outright (a spend limit, no usable moment, hosting turned off) is recorded as one failed highlight with the refusal’s code and start_seconds and end_seconds both 0, and video.highlights.failed fires. The request never fails silently.
GenerateHighlights itself is refused with failed_precondition and:
highlights_require_insightswhen the video has no ready insights in the language,highlights_no_momentswhen the insights picked no quote inside the video,- and also while the video is still processing, or when the app’s managed hosting is off.
When the video has ready insights in several languages, pass language. Without it the call is refused with parameter_required, listing them.
Pricing
Highlights have no price of their own and no processing fee. Each clip bills its rendered (clipped) minutes at your normal per-minute encoding rate, including any custom pricing on your account, and nothing else. A failed clip bills what a failed job bills: nothing. The insights the clips are cut from were billed when they were made.
Each clip is rendered by its own clip job on the video. Those jobs:
- appear in your job list, with
transcodely_kind: video_highlight,transcodely_highlight_idandtranscodely_video_idin theirmetadata, - count toward your app’s concurrency and queue limits,
- pass the same account checks as any job: spend limit, billing standing, a suspended app.
A set larger than your remaining queue gets its tail refused with queue_limit_exceeded. The clips that were admitted still render and bill.
Highlight cost appears in your hosting usage as encoding cost and minutes, and in the video’s total_cost. A regenerate never erases what an earlier set billed.
The transcodely_ metadata prefix is reserved for jobs the platform creates. Your own jobs and ingest rules cannot use it: a key starting with transcodely_ is refused with invalid_argument, code parameter_invalid on metadata.<key>. See Metadata.
From an AI agent
The MCP server exposes the same call as the generate_highlights tool, and get_video returns a video’s highlight clips. Ask “Cut three highlight clips from that video” after its insights are ready.
Related
- Transcripts & Insights: where the quotes come from.
- AI Captions: the captions the insights read.
- Videos API reference
- Pricing