Instagram Reels thumb_offset is in milliseconds: pick the frame first

thumb_offset takes milliseconds, defaults to 0, and loses to cover_url. Preview candidate frames with Sume video_frames before you publish the Reel.

5 min readSume
All posts

thumb_offset on an Instagram Reels container is a number of milliseconds into the video, and the default 0 means the first frame. So for a cover at 2.4 seconds you send thumb_offset=2400, not 2.4. Sume's video_frames lets you pull stills at the seconds you name, so you can look at the candidates and multiply the winner by 1000 before the container call.

This post uses Meta's IG User Media reference, read 2026-10-02, and Sume's video frames page. Sume does not publish to Instagram; it produces the clip and the stills, and your publisher sends the container request.

What exactly does thumb_offset take?

Meta describes it as the location, in milliseconds, of the video or reel frame used as the cover thumbnail, default 0, for videos and reels. The seconds-versus-milliseconds slip is the usual bug: thumb_offset=3 points at the third millisecond, which is effectively the first frame, and nothing errors.

If a Reel request also sends cover_url, Meta says it uses cover_url and ignores thumb_offset. The which one wins post covers that rule; here the question is how to choose the number.

thumb_offset facts from Meta's reference, read 2026-10-02
FieldValueNote
UnitMilliseconds2.4 s is 2400
Default0First frame of the video
Applies toVideos and reelsCover thumbnail frame
With cover_urlcover_url winsthumb_offset ignored on reels

How do I see candidate frames before publishing?

Import the clip to Sume first, then ask video_frames for explicit seconds. It takes 1 to 24 values in at[] and returns durable image artifacts at source size. Submit is always 202, so read the resource when it is ready. The page lists it as unbilled.

Each returned frame carries t, so the number you want is already in the response. Every t must be at least 0 and below the clip's duration, or the worker fails with frame_time_out_of_range and names the duration it probed.

curl -X POST https://api.sume.com/v1/video-frames \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reel-cover-candidates-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/reel.mp4",
    "at": [0.5, 1.2, 2.4, 3.6, 5.0]
  }'

curl https://api.sume.com/v1/video-frames/$REQUEST_ID \
  -H "Authorization: Bearer $SUME_API_KEY"

Which frame makes a good cover?

Pick a frame that reads without sound and without the video moving: a face with an open expression, a product held toward the lens, or the first frame of on-screen text. Avoid a frame mid-transition or mid-blink, which video_frames will show you exactly because it decodes to the instant you ask for.

If you only want a quick skim of the whole clip, video inspect returns eight mid-bin stills by default and can use seek: fast, which snaps to a keyframe at or before the instant. For a cover you should keep the default precise seek, because the stated time must match what you publish.

  • Ask for 5 to 8 times spread across the first half of the Reel, since most feed grids show the cover small.
  • Open each returned still at phone size, not on a monitor.
  • Write down the winning t, then compute round(t * 1000) in your publisher, not by hand.
  • If the best frame is not in the video at all, design a separate cover image and send cover_url instead.

How do I wire the chosen frame into the container?

Your publisher sends media_type=REELS, video_url, and thumb_offset as an integer of milliseconds. Keep the same video file you inspected: if you re-trim the clip afterwards the frame moves, and the offset is stale.

One honest limit: Sume gives you stills to choose from, not a guarantee of how Instagram crops them in a given surface. The cover rules, including the 9:16 recommendation, are in Reels cover photo size.

curl -X POST "https://graph.instagram.com/v26.0/$IG_USER_ID/media" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d "media_type=REELS" \
  -d "video_url=https://media.sume.com/artifacts/artf_demo/reel.mp4" \
  -d "thumb_offset=2400"

What are the common mistakes?

Four slips account for most bad covers. First, passing seconds instead of milliseconds. Second, sending both cover_url and thumb_offset and expecting the offset to count. Third, picking the frame from a draft and then re-trimming the video, which shifts every timestamp. Fourth, choosing a frame at a transition because the preview looked fine at full size but reads as a blur at thumbnail size.

A small guard in your publisher helps: reject any thumb_offset that is below 100 for a clip longer than a few seconds unless you meant the first frame, and refuse to send an offset past the clip's duration. The video_frames response also tells you source_duration_seconds, so the guard can compare against what the worker actually probed.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume