Trim 50 ads to 15 seconds for Reddit: the batch costs $1.00

Fifty finished ads cut to 15 seconds with /v1/video-trim at $0.02 a job is $1.00 before retries. A Python loop with one idempotency key per ad.

5 min readSume
All posts

Cutting 50 finished ads to 15 seconds costs 50 x $0.02 = $1.00 on Sume, because each cut is one video trim job at the $0.02 public rate. That is the whole cost of retargeting an existing library at Reddit's 15-second Engaged Video Views bid, which a trade tracker lists as a public beta from 2026-09-01 (read 2026-10-06). The clips must already be on media.sume.com; trim does not pull from other hosts.

Pricing is from Video trim: cut a range from one Sume-hosted clip and should be confirmed in GET /v1/catalog; the Reddit fact is from the Social media platform updates, October 2026 (read 2026-10-06).

Why batch the cut instead of editing each ad?

A library of old 30-second ads is mostly a list of start times. If the hook of each ad sits at second 0, the same call works for all of them: start: 0, duration: 15. If a few ads have a slow intro, give those their own start in the list and keep the rest on the default. The loop below does exactly that, and its Idempotency-Key is derived from the ad id, so rerunning the script after a crash does not pay twice for ads that already went through.

The batch script

The script reads a dict of ad id, source URL and optional start, submits one trim per ad and prints the job ids. It uses only the standard library. It sends all jobs and polls nothing; fetch results later from GET /v1/jobs/{id}/result or take a webhook.

import json, os, urllib.request

ADS = {
    "spring-a": ("https://media.sume.com/artifacts/artf_demo/spring-a.mp4", 0),
    "spring-b": ("https://media.sume.com/artifacts/artf_demo/spring-b.mp4", 2.5),
}

def trim(ad_id, url, start):
    req = urllib.request.Request(
        "https://api.sume.com/v1/video-trim",
        data=json.dumps({"video_url": url, "start": start, "duration": 15}).encode(),
        headers={
            "Authorization": "Bearer " + os.environ["SUME_API_KEY"],
            "Content-Type": "application/json",
            "Idempotency-Key": "reddit15-" + ad_id,
        },
    )
    with urllib.request.urlopen(req) as r:
        return json.load(r)

for ad_id, (url, start) in ADS.items():
    print(ad_id, trim(ad_id, url, start).get("request_id"))

How do you handle retries and failures in a batch?

A batch is only cheap if a rerun is safe. The Idempotency-Key header is what makes it safe: the same key with the same body returns the original job instead of queueing a new one. Build the key from something stable, like the ad id plus the cut you asked for, and not from a timestamp or a random value. If you change start for an ad, change the key too (for example reddit15-spring-b-s2.5), because the body is different.

Failures come back as stable codes rather than prose. source_not_found means the URL is dead or belongs to another workspace; unsupported_media_source means it is not on the Sume media host; source_duration_exceeded means the source is over 1,800 seconds. None of these is worth retrying unchanged. Log the code next to the ad id and fix the input.

Because the default mode is async, a submit returns quickly with a job. Read GET /v1/jobs/{id}/status until it is terminal, or give the submit a webhook_url and let Sume call you. Webhooks are signed; see the Webhooks page for the signature headers.

What does the arithmetic include and leave out?

The $1.00 covers accepted trim jobs only. It does not include any retry you send under a new idempotency key, and it assumes every ad is 15 seconds or longer; a shorter source clamps and is still a billed job. Captions are a separate $0.20 job per video up to 60 seconds, so adding them to all 50 would be $10.00 more.

Batch arithmetic from Sume's video trim and video captions pages, read 2026-10-06.
StepJobsRateTotal
Trim 50 ads to 15 s50$0.02$1.00
Caption the 50 cuts (optional)50$0.20$10.00
Both100mixed$11.00

What should you check before you upload?

Open two or three of the cuts and look at the last second. A hard cut at 15.0 s can land on half a word. If it does, lower duration a little for that ad and rerun it with a new key. Everything else in the batch can stay as it is.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume