Saltar al contenido principal
Esta guía le ayudará a realizar sus primeras solicitudes para cargar contenido multimedia utilizando los endpoint de carga de medios de X API v2. En esta guía se utilizan los endpoint segmentados POST /2/media/upload para cargar un video, lo que requiere un flujo de trabajo distinto al de las cargas de una sola imagen. Para las cargas de video o segmentadas, debe:
  1. Inicializar la carga con el comando INIT
  2. Cargar cada segmento de bytes con el comando APPEND
  3. Completar la carga con el comando FINALIZE
Nota: Consulte este código de muestra para ver un ejemplo escrito en Python.

Autenticación

Para ejecutar los ejemplos de esta guía, debe utilizar la autenticación OAuth 2. Puede encontrar sus CONSUMER_KEY, CONSUMER_SECRET, ACCESS_KEY y ACCESS_TOKEN en la App dentro de su Project en el panel del portal de desarrolladores.

Paso 1: POST media/upload (INIT)

La solicitud del comando INIT se usa para iniciar una sesión de carga de archivos. Devuelve un media_id que debe utilizarse en todas las solicitudes posteriores. El paso siguiente tras una respuesta correcta del comando INIT es el comando APPEND. Consulta las mejores prácticas para conocer las restricciones y requisitos de los archivos multimedia. Ejemplo de solicitud
curl --location 'https://api.x.com/2/media/upload' \
    --header 'Authorization: Bearer <TU_TOKEN_DE_ACCESO>' \
    --header 'Content-Type: multipart/form-data' \
    --form 'command=INIT' \
    --form 'media_type=video/mp4' \
    --form 'total_bytes=1024' \
    --form 'media_category=amplify_video'
Nota: Al realizar solicitudes HTTP sin procesar, la solicitud debe usar el método POST con los formatos multipart/form-data o application/x-www-form-urlencoded.
Ejemplo de respuesta
{
    "data":
    {
        "id":"1880028106020515840",
        "media_key":"13_1880028106020515840",
        "expires_after_secs":1295999
    }
}
La respuesta proporciona los identificadores de medios id (cadena) y media_key (cadena). Se debe cargar el archivo completo antes de que transcurran expires_after_secs segundos.

Paso 2: POST media/upload (APPEND)

El comando APPEND se usa para cargar un fragmento (intervalo consecutivo de bytes) del archivo multimedia. Por ejemplo, un archivo de 3 MB podría dividirse en 3 fragmentos de 1 MB y cargarse mediante 3 solicitudes del comando APPEND. Una vez que se haya cargado el archivo completo, el siguiente paso es llamar al comando FINALIZE.
Cargar un archivo multimedia en fragmentos pequeños tiene varias ventajas:
  • Mayor confiabilidad y tasas de éxito en condiciones de red con poco ancho de banda
  • Las cargas se pueden pausar y reanudar
  • Los fragmentos del archivo se pueden reintentar individualmente
  • Posibilidad de ajustar el tamaño de los fragmentos para adaptarse a las condiciones cambiantes de la red, p. ej., en clientes móviles
Ejemplo de solicitud
curl --location 'https://api.x.com/2/media/upload' \
    --header 'Authorization: Bearer <TU_TOKEN_DE_ACCESO>' \
    --header 'Content-Type: multipart/form-data' \
    --form 'command=APPEND' \
    --form 'media_id=1880028106020515840' \
    --form 'segment_index=0' \
    --form 'media=@/ruta/a/tu/archivo/multimedia/archivo.mp4'
segment_index es un índice ordenado del fragmento de archivo. Debe estar entre 0 y 999, inclusive. El primer segmento tiene el índice 0, el segundo tiene el índice 1, y así sucesivamente. Continúa subiendo los fragmentos del archivo hasta que todos se hayan subido.
Nota: Al realizar solicitudes HTTP sin procesar, la solicitud debe estar en formato POST multipart/form-data.
Nota: En caso de carga exitosa, se devolverá un HTTP 2XX con un cuerpo de respuesta vacío.

Paso 3 : POST media/upload (FINALIZE)

El comando FINALIZE debe invocarse después de cargar el archivo multimedia completo mediante los comandos APPEND. Si, y solo si, la respuesta del comando FINALIZE contiene un campo processing_info, también puede ser necesario usar un comando STATUS y esperar a que indique éxito antes de proceder a la creación del Post. Ejemplo de solicitud
curl --location --request POST 'https://api.x.com/2/media/upload' \
    --header 'Authorization: Bearer <TU_TOKEN_DE_ACCESO>' \
    --header 'Content-Type: multipart/form-data' \
    --form 'command=FINALIZE' \
    --form 'media_id=1880028106020515840'
Nota: Al realizar solicitudes HTTP sin procesar, la solicitud debe estar en formato POST multipart/form-data o application/x-www-form-urlencoded.
Ejemplo de respuesta
{
    "data": {
        "id": "1880028106020515840",
        "media_key": "13_1880028106020515840",
        "size": 1024,
        "expires_after_secs": 86400,
        "processing_info": {
            "state": "pending",
            "check_after_secs": 1
        }
    }
}
La respuesta proporciona un identificador de medios en los campos media_id (entero de 64 bits) y media_id_string (cadena). Usa el media_id_string suministrado en la respuesta de la API desde JavaScript y otros lenguajes que no pueden representar con precisión un entero largo. El media_id devuelto solo es válido durante expires_after_secs segundos. Cualquier intento de usar media_id después de ese período en otras llamadas a la API dará como resultado una respuesta Bad Request (HTTP 4xx). Si la respuesta contiene un campo processing_info, usa el comando STATUS para consultar el estado de la operación FINALIZE. El enfoque de finalización asíncrona se utiliza en los casos en que el procesamiento de medios requiere más tiempo. En el futuro, todo el procesamiento de video y GIF animados solo será compatible mediante finalización asíncrona. Este comportamiento se habilita si una sesión de carga se inicializó con el parámetro media_category, y cuando el tipo de medio es video o GIF animado.
Nota: Si NO se devuelve el campo processing_info en la respuesta, entonces media_id está listo para usarse en otros endpoints de la API.

Paso 4: GET media/upload (STATUS)

El comando STATUS se utiliza para sondear periódicamente el estado de la operación de procesamiento de medios. Una vez que la respuesta del comando STATUS indique succeeded, puede pasar al siguiente paso, que normalmente es crear un Post con media_id.
Nota: El comando STATUS debe usarse si y (solo si) la respuesta del comando FINALIZE o de un comando STATUS anterior contenía un campo processing_info.

Ejemplo de solicitud

curl --location --request GET 'https://api.x.com/2/media/upload?command=STATUS&media_id=1880028106020515840' \
    --header 'Authorization: Bearer <TU_TOKEN_DE_ACCESO>'

Ejemplo de respuesta

{
    "data":{
        "id":"1880028106020515840",
        "media_key":"13_1880028106020515840",
        "processing_info":{
            "state":"uploading" // el flujo de transición de estados es pending -> in_progress -> [failed|succeeded]
        }
    }
}
El cuerpo de la respuesta contiene el campo processing_info, que proporciona información sobre el estado actual de la operación de procesamiento de medios. Incluye un campo state con el siguiente flujo de transición: pending -> in_progress -> [failed | succeeded]. No puede usar el media_id para crear un Post u otras entidades hasta que el campo state esté establecido en succeeded.

Paso 5: Publicar un Tweet con contenido multimedia

Crea un Post utilizando el endpoint POST /2/tweets, incluyendo el media_id en nombre de un usuario autenticado. Ejemplo de solicitud
curl --location 'https://api.x.com/2/tweets' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>'
--data '{
    "text": "¡Hice un Post con contenido multimedia!",
     "media": {
       "media_ids": [
            "1880028106020515840"
        ]
    }
}'

Ejemplo de respuesta
{
    "data": {
        "edit_history_tweet_ids": [
            "1880028106020515840"
        ],
        "id": "1880028106020515840",
        "text": "¡Hice un post con contenido multimedia! https://t.co/DqNyXX"
    }
}

Solución de problemas

Si tienes problemas con las Media APIs, consulta la categoría Media API en los foros de desarrolladores para encontrar una respuesta.
I