Ir al contenido

API de videos de Twitter: obtén la URL MP4 de cualquier video de X

La URL MP4 de un video de Twitter está en los datos de medios del post: X codifica cada subida en hasta cinco versiones MP4, de 270p a 1080p o más, y lista la URL de cada archivo con su bitrate.

Respuesta corta: Toma el MP4 con el bitrate más alto; un GIF es un MP4 silencioso. La API oficial de X lista las versiones solo con media.fields=variants, a $10.00 por cada 1,000 posts con video desde el 22 de noviembre de 2026. Sorsa API devuelve el enlace de video de cada post con POST /tweet-info-bulk, 100 posts por solicitud desde $0.014 por cada 1,000, y 100 solicitudes gratis cubren los primeros 10K.

Endpoint
POST /tweet-info-bulk
Tamaño de página
100 posts por solicitud
Precio
desde $0.014 por cada 1,000

#Cómo guarda X un video: versiones y bitrates

X nunca sirve el archivo que subió el autor. Recodifica cada video en una escalera de archivos MP4, uno por tamaño, y en una lista de reproducción HLS (un índice .m3u8 que los reproductores de video usan para cambiar de tamaño durante la reproducción). Cada MP4 es un archivo completo con sonido, así que cualquiera de ellos se descarga y se reproduce por sí solo. Para un solo post, el Descargador de videos de Twitter, gratuito, guarda el archivo a partir de un enlace pegado; esta guía es para obtener los archivos en código.

El 2 de noviembre de 2026 leímos las listas de versiones de 23 posts públicos de 2017 a 2026 y medimos los 72 archivos MP4 que X sirvió para ellos. El bitrate que X lista para cada archivo es un techo, y los archivos reales son de tres a cinco veces más livianos:

VersiónTamaño de cuadro, píxelesBitrate que lista XBitrate promedio real
270p480 × 270256 kbpsunos 91 kbps
360p640 × 360832 kbpsunos 233 kbps
720p1280 × 7202,176 kbpsunos 626 kbps
1080p1920 × 108010.4 Mbpsunos 2,172 kbps
  • 270p

    Tamaño de cuadro, píxeles
    480 × 270
    Bitrate que lista X
    256 kbps
    Bitrate promedio real
    unos 91 kbps
  • 360p

    Tamaño de cuadro, píxeles
    640 × 360
    Bitrate que lista X
    832 kbps
    Bitrate promedio real
    unos 233 kbps
  • 720p

    Tamaño de cuadro, píxeles
    1280 × 720
    Bitrate que lista X
    2,176 kbps
    Bitrate promedio real
    unos 626 kbps
  • 1080p

    Tamaño de cuadro, píxeles
    1920 × 1080
    Bitrate que lista X
    10.4 Mbps
    Bitrate promedio real
    unos 2,172 kbps
The four MP4 files X served for one 82-second 1080p video, real size against listed bitrate Un video de 82 segundos: los cuatro MP4 que sirvió X Archivo real Previsto 270p 256 kbps listado 1.1 MB 2.6 MB 360p 832 kbps listado 2.9 MB 8.5 MB 720p 2,176 kbps listado 7.3 MB 22.2 MB 1080p 10.4 Mbps listado 22.2 MB 105.7 MB Solid bar: the file X served. Dashed outline, predicted: listed bitrate × 82 seconds. Medido en video.twimg.com, 2 de noviembre de 2026.
El archivo 1080p de un video de 82 segundos pesó 22.2 MB, cerca de una quinta parte de lo que predice su bitrate listado.

Lo que muestran las mediciones:

  • El bitrate más alto es el mejor archivo. Ordena las entradas MP4 por bitrate y toma la primera. La entrada de la lista de reproducción, de tipo application/x-mpegURL, no trae bitrate y es un índice, no un archivo.
  • El tamaño depende de la forma del cuadro. Los videos verticales reciben de 320 × 568 hasta 1080 × 1920, los cuadrados de 320 × 320 hasta 1080 × 1080, y una subida de 1936 × 1548 recibió un quinto archivo a 25.1 Mbps.
  • No toda subida en 1080p recibe un archivo 1080p. De siete subidas de 1920 × 1080 de 2025 y 2026, dos se quedaron en 720p, y la mayoría de los posts anteriores a 2022 llegan como máximo a 720p.
  • La lista de reproducción separa el sonido de la imagen. Sus flujos de video son silenciosos; el audio llega como pistas separadas a 32, 64 y 128 kbps, con subtítulos en algunos videos.

Un GIF es más simple: X guarda un MP4 silencioso y en bucle al tamaño propio del GIF, sin otras versiones y sin lista de reproducción.

#Obtén la URL MP4 de un video con Sorsa API

Sorsa API, una API y scraper de Twitter (X), devuelve cada post con sus medios adjuntos: cada video, GIF y foto es una entrada en la lista entities del post con un type, un link directo y una imagen preview. Una API key en un encabezado reemplaza la cuenta de desarrollador y el OAuth que pide la API oficial de X.

  1. Obtén una clave. Regístrate y copia la API key desde tu panel. Las primeras 100 solicitudes son gratis, sin tarjeta.

  2. Envía el enlace del post. POST /tweet-info (se abre en una pestaña nueva) admite una URL de post o un ID a secas en tweet_link.

    Terminal
    curl -X POST "https://api.sorsa.io/v3/tweet-info" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"tweet_link":
           "https://x.com/northfield_video_lab/status/1984519203377641472"}'
    
    Response200 OK
    {
      "id": "1984519203377641472",
      "created_at": "2026-10-31T16:04:11Z",
      "full_text": "First ride on the new gravel loop.",
      "entities": [
        {
          "type": "video",
          "link": "https://video.twimg.com/amplify_video/1984519110025023488/vid/avc1/480x270/Qm3vTb8xLwK2pRfA.mp4?tag=21",
          "preview": "https://pbs.twimg.com/amplify_video_thumb/1984519110025023488/img/Hx2LkP9aQwErT0bn.jpg"
        }
      ],
      "user": {
        "username": "northfield_video_lab",
        "display_name": "Northfield Video Lab",
        "media_count": 214
      }
    }
    
  3. Lee las entradas de video. Conserva las entidades cuyo type sea video y cuyo link esté en video.twimg.com. Una ruta /tweet_video/ en el enlace marca un GIF.

  4. Descarga el archivo. El MP4 es un archivo HTTPS simple en los servidores de X: sin clave, sin cookie y sin que se cuente ninguna solicitud.

    import requests
    
    API = "https://api.sorsa.io/v3/tweet-info"
    HEADERS = {"ApiKey": "YOUR_API_KEY"}
    
    
    def video_links(post):
        r = requests.post(API, headers=HEADERS,
                          json={"tweet_link": post}, timeout=60)
        r.raise_for_status()  # 403: no key, or no requests left
        tweet = r.json()
        for e in tweet.get("entities") or []:
            if e.get("type") == "video" and "video.twimg.com" in e["link"]:
                yield tweet["id"], e["link"]
    
    
    links = video_links("1984519203377641472")
    for n, (post_id, link) in enumerate(links, 1):
        with open(f"{post_id}_{n}.mp4", "wb") as f:
            f.write(requests.get(link, timeout=120).content)
    

El link es un MP4 con sonido que se reproduce en cualquier parte. El 2 de noviembre de 2026 pasamos dos videos por nuestro descargador gratuito, que funciona sobre Sorsa API, y ambos enlaces eran la versión 270p de X. Para el de 82 segundos eso significó 1.1 MB: lo bastante liviano para vistas previas, transcripciones, muestreo de cuadros y archivos grandes. El enlace de un GIF es su único archivo, así que llega completo.

El preview sirve también como cuadro a tamaño completo: agrégale ?format=jpg&name=orig (quitando antes el .jpg) y X devuelve el cuadro al tamaño propio de la subida, 1936 × 1548 píxeles en uno de nuestros posts de prueba. Las fotos vienen en la misma lista con type photo; obtener cada una a su tamaño original, de un post o de una cuenta entera, se cubre en la guía del scraper de imágenes de Twitter.

Para una lista de posts, envía hasta 100 enlaces o IDs en tweet_links a POST /tweet-info-bulk (se abre en una pestaña nueva). La respuesta es {"tweets": [...]} con las mismas entities en cada post, y todo el lote es una solicitud: desde $0.014 por cada 1,000 posts.

#Descarga todos los videos de una cuenta o de una búsqueda

La búsqueda encuentra los posts con video por ti. El operador de búsqueda de X filter:native_video conserva los posts con un video subido a X, y card_name:animated_gif conserva los GIF. POST /search-tweets (se abre en una pestaña nueva) devuelve unos 20 posts coincidentes por solicitud, con una búsqueda que llega hasta 2006.

TareaConsulta
Todos los videos de una cuentafrom:northfield_video_lab filter:native_video
Todos los GIF de una cuentafrom:northfield_video_lab card_name:animated_gif
Videos sobre un tema en un mes"gravel racing" filter:native_video since:2026-10-01 until:2026-11-01
Solo videos populares#bikepacking filter:native_video min_faves:1000
Videos y enlaces de YouTubetrail build filter:videos
  • Todos los videos de una cuenta

    Consulta
    from:northfield_video_lab filter:native_video
  • Todos los GIF de una cuenta

    Consulta
    from:northfield_video_lab card_name:animated_gif
  • Videos sobre un tema en un mes

    Consulta
    "gravel racing" filter:native_video since:2026-10-01 until:2026-11-01
  • Solo videos populares

    Consulta
    #bikepacking filter:native_video min_faves:1000
  • Videos y enlaces de YouTube

    Consulta
    trail build filter:videos

Cada operador, con ejemplos, está en la guía de operadores de búsqueda de Twitter. El script de abajo ejecuta una consulta de la primera página a la última.

Downloading every video of an X account with Sorsa API Buscar los posts /search-tweets filter:native_video unos 20 posts por página Leer las entities type: "video" link: MP4, audio /tweet_video/ en el enlace = un GIF Guardar archivos <post id>_1.mp4 directo de video.twimg.com Registrarlo videos.csv id, fecha, tipo, bytes, archivo next_cursor, hasta que vuelva vacío
Una página de búsqueda es una solicitud; los archivos de video vienen directo de los servidores de X y no cuestan solicitudes.
  1. Guarda el script. Recorre la búsqueda con next_cursor, un token que marca dónde empieza la página siguiente, hasta que el cursor llegue vacío. Escribe los videos y GIF de cada post en <post id>_<n>.mp4 y registra cada archivo en videos.csv.

    x_videos.py
    import csv
    import os
    import subprocess
    import sys
    import time
    
    import requests
    
    API = "https://api.sorsa.io/v3/search-tweets"
    HEADERS = {"ApiKey": "YOUR_API_KEY"}
    
    
    def search(body):
        while True:
            r = requests.post(API, headers=HEADERS, json=body, timeout=60)
            if r.status_code == 429:  # over 20 requests a second: wait
                time.sleep(1)
                continue
            r.raise_for_status()  # 403: no key, or no requests left
            return r.json()
    
    
    def videos(tweet):
        """(kind, link) for every video and GIF in a post."""
        for e in tweet.get("entities") or []:
            link = e.get("link") or ""
            if e.get("type") == "video" and "video.twimg.com" in link:
                yield ("gif" if "/tweet_video/" in link else "video"), link
    
    
    def save(link, path):
        with requests.get(link, stream=True, timeout=120) as r:
            r.raise_for_status()
            with open(path, "wb") as f:
                for chunk in r.iter_content(1 << 16):
                    f.write(chunk)
    
    
    def save_hd(post_url, n, path):
        """The post's highest-bitrate MP4 through yt-dlp; False if yt-dlp fails."""
        cmd = ["yt-dlp", "-f", "best[protocol=https]", "--playlist-items", str(n),
               "-o", path, post_url]
        done = subprocess.run(cmd, capture_output=True).returncode == 0
        return done and os.path.exists(path)
    
    
    def run(query, folder, hd=False):
        os.makedirs(folder, exist_ok=True)
        state = os.path.join(folder, "cursor.txt")
        body = {"query": query, "order": "latest"}
        if os.path.exists(state):  # resume a stopped run
            body["next_cursor"] = open(state).read().strip()
        log_path = os.path.join(folder, "videos.csv")
        with open(log_path, "a", newline="", encoding="utf-8") as f:
            log = csv.writer(f)
            while True:
                page = search(body)
                for t in page.get("tweets", []):
                    for n, (kind, link) in enumerate(videos(t), 1):
                        path = os.path.join(folder, f"{t['id']}_{n}.mp4")
                        if os.path.exists(path):
                            continue
                        url = f"https://x.com/{t['user']['username']}/status/{t['id']}"
                        if not (hd and kind == "video" and save_hd(url, n, path)):
                            save(link, path)
                        log.writerow([t["id"], t["created_at"], kind,
                                      os.path.getsize(path), path])
                cursor = page.get("next_cursor")
                if not cursor:
                    break
                body["next_cursor"] = cursor
                with open(state, "w") as s:
                    s.write(cursor)
        if os.path.exists(state):
            os.remove(state)
    
    
    if __name__ == "__main__":
        run(sys.argv[1], sys.argv[2], hd="--hd" in sys.argv[3:])
    
  2. Ejecútalo con una consulta y una carpeta. python x_videos.py "from:northfield_video_lab filter:native_video" northfield guarda los videos de la cuenta en la carpeta northfield. Un 403 significa que falta la clave o que se acabaron las solicitudes; un 429 significa más de 20 solicitudes en un segundo, y el script espera un segundo y reintenta.

  3. Vuelve a ejecutarlo cuando quieras. Los archivos que ya están en disco se omiten y el cursor se guarda después de cada página. Una ejecución detenida retoma donde se quedó, y una nueva ejecución agrega solo los videos nuevos.

Los videos de una cuenta entera toman pocas solicitudes: a unos 20 posts por página, una cuenta con 300 videos son unas 15 solicitudes, porque la búsqueda devuelve solo los posts que llevan uno. Para el texto y todos los demás campos del post en una hoja de cálculo, consulta cómo descargar todos los tweets de un usuario.

#Descarga el archivo 720p o 1080p de un post

Para el archivo 720p o 1080p de un post, pásale su enlace a yt-dlp, el descargador de línea de comandos de código abierto, que lee posts públicos sin iniciar sesión en X. El filtro de formato de abajo elige el MP4 con el bitrate más alto:

Terminal
yt-dlp -f "best[protocol=https]" -o "%(id)s.%(ext)s"   "https://x.com/northfield_video_lab/status/1984519203377641472"

Agrega --hd al script de arriba y hará esto con cada video, con el enlace de la API como respaldo cuando yt-dlp falle. En nuestro video de prueba de 82 segundos, yt-dlp 2026.10.26 eligió el archivo de 1920 × 1080. Su tabla de formatos, ejecutada con -F, mostraba ese archivo con unos 100 MiB, porque la tabla multiplica el bitrate indicado por la duración; la descarga pesó 22.2 MB. yt-dlp descarga un post a la vez desde tu propia dirección IP, así que Sorsa API se encarga de encontrar los videos en bloque y yt-dlp solo de los archivos HD que necesitas.

Para tener en cuenta

La API oficial de X devuelve la lista completa de versiones en una sola respuesta, pero solo si la pides. Agrega expansions=attachments.media_keys y media.fields=variants a una consulta de post, y cada video vuelve en includes.media con un arreglo variants de bit_rate, content_type y url. Necesita una cuenta de desarrollador y OAuth, y desde el 22 de noviembre de 2026 cada objeto multimedia de esa respuesta se cobra a $0.005, además de los $0.005 de la lectura del post.

#Los GIF de Twitter en la API

Un GIF publicado en X vuelve como un MP4, porque X convierte cada GIF en un video corto, silencioso y en bucle cuando se publica. Su enlace está en video.twimg.com/tweet_video/, X no guarda otro tamaño, y ese único archivo es la mejor copia que existe. En los datos de X se tipifica como animated_gif con un bitrate de 0; en las entities de Sorsa API llega como un video cuyo enlace tiene esa ruta /tweet_video/.

Para convertirlo de nuevo en un archivo .gif, ejecuta ffmpeg con una pasada de paleta, que mantiene los colores limpios:

Terminal
ffmpeg -i 1211797914437259264_1.mp4 \
  -vf "fps=15,split[a][b];[a]palettegen[p];[b][p]paletteuse" \
  -loop 0 1211797914437259264.gif

Espera un archivo mucho más grande: en nuestra prueba un MP4 de 83 KB se convirtió en un GIF de 1.76 MB con los mismos 498 × 272 píxeles, 21 veces el tamaño. Conserva el MP4 para almacenar y para los reproductores, y crea el GIF solo donde una página o un chat lo necesite. Para un solo GIF sin código, el Descargador de GIF de Twitter, gratuito, lo guarda a partir del enlace de un post.

#Cuánto cuesta, en solicitudes y en almacenamiento

En Sorsa API un post cuesta lo mismo sea cual sea el medio que lleve. Los posts consultados por ID cuestan desde $0.014 por cada 1,000, 100 por solicitud, y los posts encontrados por búsqueda desde $0.07 por cada 1,000, unos 20 por solicitud. Los archivos de video se descargan de los servidores de X y no cuestan solicitudes. En la API oficial de X cada video llega por la expansión de medios, y desde el 22 de noviembre de 2026 X cobra los objetos de expansión (se abre en una pestaña nueva) a la tarifa estándar. Un post con video cuesta entonces $0.005 por el post más $0.005 por sus medios: $10.00 por cada 1,000.

Forma de obtener los enlaces de videoQué necesitaCosto por cada 1,000 posts con video
Sorsa API, posts por IDUna API keydesde $0.014
Sorsa API, búsquedaUna API keydesde $0.07
API oficial de XCuenta de desarrollador y OAuth$10.00 desde el 22 de nov de 2026
  • Sorsa API, posts por ID

    Qué necesita
    Una API key
    Costo por cada 1,000 posts con video
    desde $0.014
  • Sorsa API, búsqueda

    Qué necesita
    Una API key
    Costo por cada 1,000 posts con video
    desde $0.07
  • API oficial de X

    Qué necesita
    Cuenta de desarrollador y OAuth
    Costo por cada 1,000 posts con video
    $10.00 desde el 22 de nov de 2026
Posts con video

API oficial de X

$10,000

para 1M posts con video

$0.010 por post con video, desde el 22 de nov

Sorsa API

desde$14

para 1M posts con video

desde $0.014 por cada 1,000

714 veces más barato

El pago por uso (se abre en una pestaña nueva) de la API oficial de X también se detiene en 3M de lecturas de posts por ciclo de facturación, y por encima de eso X vende solo contratos Enterprise. Sorsa API corre a 20 solicitudes por segundo en todos los planes, así que los lotes de 100 posts consultan 2,000 posts con video por segundo, y las solicitudes fallidas nunca se cobran.

El almacenamiento es la factura más grande de un archivo de videos, y depende de la versión mucho más que de la cantidad. Con los bitrates promedio reales que medimos, 1,000 videos de treinta segundos ocupan unos 0.3 GB en 270p, 2.3 GB en 720p y 8.1 GB en 1080p. Fija tu propia duración y cantidad:

segundos
videos
VersiónPor videoTodos los videosTope
270p0.34 MB341 MB0.96 MB
360p0.87 MB874 MB3.1 MB
720p2.3 MB2.3 GB8.2 MB
1080p8.1 MB8.1 GB38.9 MB

Por video: la mediana del bitrate real por versión (91, 233, 626 y 2,172 kbps). Tope: el bitrate que X indica (256, 832 y 2,176 kbps, y 10.4 Mbps) multiplicado por la duración.

Los tamaños por video salen de los bitrates promedio reales de 63 archivos MP4 medidos en los servidores de X el 2 de noviembre de 2026; el tope usa el bitrate que indica X.

#Empieza a obtener videos de X en código

Para obtener en código las URL MP4 de videos y GIF de X, usa Sorsa API: una solicitud devuelve hasta 100 posts con el enlace de cada video, desde $0.014 por cada 1,000. La búsqueda encuentra todos los videos de una cuenta o de un tema hasta 2006, y tu cuenta de X nunca interviene. Copia el script, agrega tu clave, y tus 100 solicitudes gratis devuelven los enlaces de tus primeros 10K posts con video.

#Preguntas frecuentes

¿La API oficial de X puede devolver URLs de videos de Twitter?

Sí. Agrega expansions=attachments.media_keys y media.fields=variants a una consulta o búsqueda de posts, y cada video en includes.media lista sus versiones MP4 con bit_rate y url; toma la de mayor bitrate. Sin esos dos parámetros obtienes solo una imagen de vista previa. Requiere una cuenta de desarrollador y OAuth, y desde el 22 de noviembre de 2026 cada objeto de medios suma $0.005 a los $0.005 de la lectura del post.

¿Qué API debo usar para obtener URLs de videos de Twitter?

Usa Sorsa API. POST /tweet-info-bulk devuelve hasta 100 posts por solicitud con el enlace MP4 y la vista previa de cada video, desde $0.014 por cada 1,000 posts. La API oficial de X cobra $10.00 por cada 1,000 posts con video desde el 22 de noviembre de 2026. Sorsa API necesita una API key en lugar de una cuenta de desarrollador y OAuth, encuentra videos por búsqueda hasta 2006 y corre a 20 solicitudes por segundo en todos los planes.

¿Por qué se ve borroso el video de Twitter que descargué?

Lo más probable es que hayas guardado una de las versiones más pequeñas. X guarda cada video como hasta cinco archivos MP4, de 270p a 1080p o más, y algunas herramientas y API entregan la primera o la más liviana. Elige el MP4 con el bitrate más alto de la lista. Si el mejor archivo sigue siendo 720p, la subida no recibió una versión 1080p: dos de las siete subidas 1080p de 2025 y 2026 que revisamos se quedaron en 720p.

¿Puedo descargar videos de cuentas privadas o de posts eliminados?

No. Los posts de una cuenta protegida solo los ven los seguidores que ella aprueba, así que ninguna API devuelve sus videos, Sorsa API incluida, y una solicitud por ellos nunca se cobra. Los posts eliminados desaparecen de la búsqueda y las consultas de X, así que ninguna API puede listarlos tampoco; solo una copia guardada antes de la eliminación conserva el video.

Sí. Guardar videos públicos para investigación, moderación o un archivo es legal y habitual. Los derechos de autor siguen siendo de quien hizo cada video, así que pide permiso al dueño antes de publicar o revender los archivos. Sorsa API lee posts públicos con su propia API, así que tu cuenta de X no participa.

#Cómo lo verificamos

El 2 de noviembre de 2026 leímos las listas de versiones que X publica para 23 posts públicos con videos y GIF de 2017 a 2026 y medimos 72 de sus 75 archivos MP4 que sirvió video.twimg.com. De un video leímos además su lista de reproducción HLS y listamos sus formatos con yt-dlp 2026.10.26, sin iniciar sesión. Pasamos tres de los posts por nuestro descargador gratuito, que funciona sobre Sorsa API, para ver los enlaces que devuelve. El script se ejecutó contra un sustituto de la API que servía esos enlaces reales, y la línea de ffmpeg se ejecutó con un archivo GIF real. Los endpoints y campos salen de la referencia de API en vivo de Sorsa API; los campos de medios y los precios de X salen de docs.x.com y del aviso de X del 23 de octubre de 2026, leídos el mismo día.

Por el equipo de Sorsa API. Creamos y operamos Sorsa API, la API y scraper de Twitter/X de solo lectura, en producción desde 2022 (antes TweetScout API) y con más de 6 mil millones de solicitudes procesadas. Acerca de Sorsa API

Qué cambió
  • Reescrito desde cero: versiones medidas y bitrates reales de 72 archivos MP4, la ruta de Sorsa API para un post, una lista y una cuenta entera con un script probado, los GIF como MP4, una calculadora de almacenamiento y costos que incluyen el cobro de medios de X del 22 de noviembre.
  • Primera publicación.