Clipping Engine
Cut clips, build highlight reels, and transcribe video — what you can do and how each job runs.
The Clipping Engine is the video half of the Mager API. It is the same engine behind Mager Klip: give it a long video, and it finds the parts worth keeping.
What you can do
| You want | Call | You get |
|---|---|---|
| Short vertical clips from a long video, ready for Shorts, TikTok or Reels | POST /clips | A list of clips with titles, timings and video URLs |
| A sports highlight reel from match footage | POST /highlights | One stitched reel, optionally rendered with a template |
| Word-level captions for a video or audio file | POST /transcriptions | Segments and per-word timestamps |
| To know whether any of the above has finished | GET /jobs/{jobId} | Status, progress, and the finished payload |
All three are asynchronous. You get a job id straight away and the work happens in the background — these are video jobs, not image generations.
Everything needs the CLIPPING scope on your API key. Keys issued before the Clipping Engine
existed do not carry it, and the call fails with 403. Create a new key to use it.
Cutting clips
Give it a video and the range to look at. The AI reads the transcript and the footage, picks the strongest moments, and renders each one vertically with subtitles burned in.
curl https://api.mageran.ai/api/v1/clips \
--header 'x-mager-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"start_time": "00:00:00",
"end_time": "00:20:00",
"clip_count": 3,
"clip_length": "30-90s",
"target_resolution": "1080p",
"video_duration_seconds": 3120,
"callback_url": "https://client.example.com/webhooks/mager"
}'clip_count is how many clips to cut, clip_length the target duration of each. user_prompt
steers the selection — "prefer moments with a strong opening line" is the kind of direction that
works.
Subtitles are on by default. The subtitle object controls the font style, size, placement, colours
and how many words appear at once, plus allowed_editing_styles — the framing presets the renderer
may choose from (STATIC_CROP, DYNAMIC_CROP, BLURRED_WINGS, and others).
video_duration_seconds is required: it is how the engine sizes the job before touching the video.
Building a highlight reel
Point it at match footage. The AI scores the moments, stitches the best of them into one reel, and —
if you pass a template_id — renders that reel with a template.
curl https://api.mageran.ai/api/v1/highlights \
--header 'x-mager-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Persija vs Persib",
"category": "soccer",
"duration": "5400",
"start_time": "00:00:00",
"end_time": "01:00:00",
"layout": "SQUARE_BLUR",
"target_resolution": "1080p"
}'Analysis is capped at the first hour of footage. A longer source is accepted; only the first hour is scored.
The finished job returns both videos: rawVideoUrl is the stitched reel, templatedVideoUrl the
templated render. Without a template_id, only the raw reel is produced.
Transcribing
Transcription is available on its own, without cutting anything.
curl https://api.mageran.ai/api/v1/transcriptions \
--header 'x-mager-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"start_time": "00:00:00",
"end_time": "00:10:00"
}'Pass either video_url for a YouTube video or s3_key for media already in Mager storage —
exactly one, never both.
Checking on a job
Every create call returns the same envelope:
{
"task_id": "cmclip01hxyz123",
"status": "running",
"billing": { "base_moods": 1, "charged_moods": 2, "extra_moods_charged": 2 },
"output": null,
"result": []
}One endpoint reads them all back, whichever call created the job:
curl https://api.mageran.ai/api/v1/jobs/cmclip01hxyz123 \
--header 'x-mager-api-key: YOUR_API_KEY'Statuses are the same four as generation tasks: queued,
running, finished, failed. The last two are terminal.
Reading the output
Video jobs return data, not files, so results arrive on output rather than result. It is
null until the job finishes.
{
"task_id": "cmclip01hxyz123",
"status": "finished",
"output": {
"segments": 128,
"captions": [
{
"text": "the first thing we got wrong was pricing",
"start": 12.4,
"end": 15.1,
"words": [{ "word": "the", "start": 12.4, "end": 12.55, "score": 0.99 }]
}
]
}
}What is inside depends on what you asked for:
- clips — the clip list, each with its title, timings, virality score and video URL
- highlights —
rawVideoUrlandtemplatedVideoUrl - transcriptions —
segmentsandcaptions
Timing, and why you want webhooks
A transcription of ten minutes of audio takes minutes. A clip job on a two-hour source takes considerably longer — the video has to be downloaded, transcribed, analysed, then rendered.
Set callback_url and let the webhook tell you. Deliveries are signed
exactly like generation task webhooks, so the same verification code handles both.
If you do poll, poll every 15–30 seconds. Every three seconds burns your rate limit on a number that has not moved.
Caching
Transcribing the same video, range and quality twice is much faster the second time — the result is cached and shared with the clip pipeline. A clip job on a video you already transcribed skips that step entirely.
What it costs
Every operation costs a flat number of moods multiplied by your account's price multiplier. The default is 1 mood per operation, regardless of how long the video is. See Moods and billing for how the multiplier works.
"billing": { "base_moods": 1, "charged_moods": 2, "extra_moods_charged": 2 }A job that never starts, or that fails permanently, is refunded in full. Unlike generation tasks, nothing is retained.
Pass idempotency_key on any create call to make a retry safe: the repeat returns the original job
instead of running and charging a second time.