Facebook Reels API: start, upload, finish and the video_state values

Publishing a Facebook Reel takes three calls: upload_phase start, a file upload to rupload, then finish with video_state PUBLISHED, SCHEDULED or DRAFT.

4 min readSume
All posts

A Facebook Reel goes live through three phases against the Page's video_reels edge: start an upload session, send the file to Meta's rupload host, then finish with a video_state of PUBLISHED, SCHEDULED or DRAFT. A reel that fails at finish is often a spec miss, so check the file before phase one. The checks below can be run against Sume media with an unbilled probe.

The three phases

Facebook Reels publishing guide, read 2026-10-02
PhaseCallNotes
StartPOST /page-id/video_reels with upload_phase: startInitializes the session; returns a video_id and an upload_url
UploadTransfer the file to the rupload.facebook.com endpointPOST the file to the upload_url from start; this call carries no upload_phase
FinishPOST /page-id/video_reels with upload_phase: finishvideo_state: PUBLISHED, SCHEDULED or DRAFT

Spec to check before phase one

Video specification on the same page, read 2026-10-02
ItemValue
Duration3 to 90 seconds
Aspect ratio9 x 16
Resolution1080 x 1920 recommended; 540 x 960 minimum
Frame rate24 to 60 fps
File type.mp4 recommended
CodecH.264, H.265 (VP9, AV1 also supported)
AudioAAC Low Complexity, stereo, 48 kHz, 128 kbps or more

Preflight with Sume

Probe the clip once, then gate the three calls on the result. The probe's duration_seconds, width, height and fps map to the first four rows. The check below uses those fields.

def reel_problems(p):
    w, h = p.get("width") or 0, p.get("height") or 0
    out = []
    if not 3 <= (p.get("duration_seconds") or 0) <= 90:
        out.append("duration outside 3-90 s")
    if w * 16 != h * 9:
        out.append("not 9:16")
    if min(w, h) < 540 or max(w, h) < 960:
        out.append("below 540x960")
    if not 24 <= (p.get("fps") or 0) <= 60:
        out.append("fps outside 24-60")
    return out

print(reel_problems({"duration_seconds": 30, "width": 1080,
                     "height": 1920, "fps": 30}))

If it fails the check

Video trim shortens a clip ($0.02 per job; duration 0.2 to 900 seconds) and, in exact mode, conforms size and rate with output (fps 24, 25, 30 or 60). To go from a 16:9 source to 1080x1920 with a blurred background, Timeline 1.0 renders 1080x1920 by default with fit: "blur" per slot, at $0.10 per output minute.

Limits

The page names no maximum file size. It lists 3 to 90 seconds; that is the only source we read, so confirm the length against a draft before relying on it for a campaign. Use DRAFT while you test: it lets you inspect the result without publishing.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume