X Ads API media upload: simple for images, chunked for all media

X's Ads API lists POST media/upload for images only and a chunked upload for all media. Use the chunked route for video you render with Sume.

4 min readSume
All posts

X's Creatives documentation lists POST media/upload for images only and POST media/upload (chunked) for all media. Sume returns media as media.sume.com URLs, so the handoff is: download the finished file, then send it to X with the route that fits its type.

Which route for which file

Endpoints from X's Creatives documentation (read 2026-10-05)
EndpointCovers
POST media/uploadImages only
POST media/upload (chunked)All media
POST accounts/:account_id/cardsCreate a card
POST accounts/:account_id/tweetsCreate a Tweet

Fetch the Sume file and size-check it

The upload call itself needs OAuth 1.0a signing against X, which this post does not cover. The script prepares the file and picks the route from the extension and size, using the 3 MB image cap and 500 MB video cap from the same page. Replace the URL with a Sume media URL from a finished job.

import os, requests

def fetch(url: str, path: str) -> int:
    data = requests.get(url, timeout=120).content
    open(path, "wb").write(data)
    return len(data)

def route(path: str, size: int) -> str:
    ext = path.rsplit(".", 1)[-1].lower()
    if ext in {"bmp", "jpeg", "jpg", "png"}:
        return "media/upload" if size <= 3 * 1024 * 1024 else "too large for an image card"
    if ext in {"mp4", "mov"}:
        return "media/upload (chunked)" if size <= 500 * 1024 * 1024 else "over 500 MB"
    return "unsupported type"

url = os.environ.get("SUME_MEDIA_URL")
if not url:
    raise SystemExit("set SUME_MEDIA_URL to a media.sume.com file URL")
path = "creative." + url.rsplit(".", 1)[-1]
print(route(path, fetch(url, path)))

Before you upload

  • Video: the page gives a 10-minute and 500 MB ceiling, mp4 or mov.
  • Trim long clips first with Sume's video trim if they run past a card's length limit.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume