TL;DR, Respuesta Rápida
10 min de lecturaAñadir upload_type=resumable a POST /<IG_ID>/media devuelve un id y una uri en rupload.facebook.com en lugar de ir a buscar tu vídeo por URL. La subida en sí es un POST a ese host con las cabeceras Authorization OAuth, offset y file_size, o una cabecera file_url para un archivo ya alojado. Meta restringe el flujo a las apps que usan Facebook Login for Business, no publica ningún umbral de tamaño que lo haga obligatorio y no documenta forma alguna de reanudar una transferencia rota.
¿Qué es una subida reanudable de Instagram?
Meta lo llama subida reanudable de Instagram, y es un flujo de dos hosts: POST /<IG_ID>/media con upload_type=resumable crea el contenedor en graph.facebook.com y devuelve un destino de subida, y luego los bytes van a rupload.facebook.com en una segunda petición que controlas tú.
Lo normal es la disposición contraria. En una subida estándar pasas video_url y Meta va a buscar el archivo a tu servidor: "We will cURL your image using the passed in URL so it must be on a public server." Tu servidor responde a una petición del rastreador de Meta, y la transferencia sale bien o mal en un sitio que no puedes ver. Reanudable lo invierte. Tú abres la conexión, tú envías los bytes y tú recibes una respuesta sobre ellos.
La razón declarada por Meta para el flujo aparece en la lista de endpoints de la guía de publicación de contenido, con errata incluida: "upload_type=resumable Create a resumbable upload session to upload large videos from an area with frequent network interruptions or other transmission failures."
El parámetro en sí está documentado como opcional y sensible a mayúsculas en la referencia de medios: "An optional parameter for users want to upload video through the rupload protocol, values can be set to lowercase string value: resumable." La minúscula importa. RESUMABLE no es un valor documentado.
- Envías un video_url y esperas a que Meta lo recupere
- Tu servidor responde a una petición del rastreador de Meta
- La transferencia tiene éxito o falla en un punto que no puedes ver
- Abres tú mismo la conexión a rupload.facebook.com
- Envías los bytes y fijas las cabeceras offset y file_size
- Recibes la respuesta sobre la subida directamente
¿Qué envía cada paso del flujo?
Cuatro pasos, dos hosts y un esquema de autorización distinto en cada uno.
| Paso | Host | Petición |
|---|---|---|
| 1. Abrir la sesión | graph.facebook.com | POST /<IG_USER_ID>/media con media_type, upload_type=resumable, access_token |
| 2. Enviar los bytes | rupload.facebook.com | POST /ig-api-upload/<API_VERSION>/<IG_CONTAINER_ID> con Authorization, offset, file_size |
| 3. Comprobar el contenedor | graph.facebook.com | GET /<IG_CONTAINER_ID>?fields=status_code |
| 4. Publicar | graph.facebook.com | POST /<IG_ID>/media_publish con creation_id |
El paso uno se diferencia de una creación de contenedor estándar en lo que omite. No hay video_url, porque todavía no hay nada que Meta pueda ir a buscar. Una sesión de reel tiene esta forma completa:
POST https://graph.facebook.com/v25.0/<YOUR_APP_USERS_INSTAGRAM_USER_ID>/media
?media_type=REELS
&upload_type=resumable
&caption=<IMAGE_CAPTION>
&collaborators=<COLLABORATOR_USERNAMES>
&cover_url=<COVER_URL>
&audio_name=<AUDIO_NAME>
&location_id=<LOCATION_PAGE_ID>
&thumb_offset=<THUMB_OFFSET>
&access_token=<USER_ACCESS_TOKEN>
La respuesta lleva un segundo campo que un contenedor estándar no devuelve:
{
"id": "<IG_CONTAINER_ID>",
"uri": "https://rupload.facebook.com/ig-api-upload/v25.0/<IG_CONTAINER_ID>"
}Usa la uri que Meta te entrega en lugar de montar la ruta tú mismo. El paso dos publica entonces el archivo en ella:
curl -X POST "https://rupload.facebook.com/ig-api-upload/v25.0/<IG_CONTAINER_ID>" \
-H "Authorization: OAuth <USER_ACCESS_TOKEN>" \
-H "offset: 0" \
-H "file_size: Your_file_size_in_bytes" \
--data-binary "@Your_local_file_path.extension"Meta documenta las dos cabeceras numéricas en una línea cada una. "offset is set to the first byte being upload, generally 0." "file_size is set to the size of your file in bytes." Un archivo ya alojado se salta el cuerpo por completo y mueve el origen a una tercera cabecera:
curl -X POST "https://rupload.facebook.com/ig-api-upload/v25.0/<IG_CONTAINER_ID>" \
-H "Authorization: OAuth <USER_ACCESS_TOKEN>" \
-H "file_url: <VIDEO_URL>"El éxito son dos campos: {"success":true,"message":"Upload successful."}.
¿Por qué la cabecera de autorización es distinta en rupload?
Porque Meta la escribe distinta en cada host, y los ejemplos están uno al lado del otro en la misma página. Las llamadas a graph.facebook.com en la guía de publicación de contenido usan -H "Authorization: Bearer <ACCESS_TOKEN>". Todas las llamadas a rupload.facebook.com en esa misma página usan -H "Authorization: OAuth <ACCESS_TOKEN>".
Mismo token, nombre de esquema distinto. Meta no da ninguna explicación, y los ejemplos de rupload nunca muestran Bearer. Copia el esquema del ejemplo que corresponda al host al que estás llamando.
Hay otros dos detalles fáciles de perder entre los bloques de código. El curl publicado por Meta para el paso de rupload contiene una comilla invertida suelta dentro de la URL, entre el marcador del ID de contenedor y la comilla de cierre. Es una errata del documento, no un elemento de sintaxis. Y la propia lista de parámetros del paso de subida en la guía de publicación de contenido se corta a media frase: anuncia "the following parameters", imprime access_token y termina en una viñeta vacía. La lista completa de cabeceras solo existe en la referencia del endpoint de medios, no en la guía.
¿Cuándo es reanudable obligatorio y no opcional?
Meta nunca publica un tamaño de archivo que lo haga obligatorio, y la respuesta honesta es que el único requisito duro tiene que ver con tu flujo de inicio de sesión, no con tu archivo.
La guía de publicación de contenido restringe todo el flujo en una cláusula: upload_type=resumable es "Only for apps that have implemented Facebook Login for Business." La tabla de requisitos de esa misma página lo respalda enumerando las URL de host por tipo de inicio de sesión. Instagram API con Instagram Login recibe graph.instagram.com. Instagram API con Facebook Login recibe graph.facebook.com y rupload.facebook.com, anotado con "(For resumable video uploads)".
AdaptlyPost
Prueba gratis de 7 días
Analíticas multiplataforma
Bandeja Social
Asistente con IA
Así que una app construida sobre Business Login for Instagram no puede usar reanudable en absoluto. El vídeo tiene que llegar por video_url y la descarga de Meta. Esa es una decisión de arquitectura de inicio de sesión tomada mucho antes de que nadie suba un archivo, y no es reversible petición a petición.
Donde reanudable sí está disponible, la orientación de Meta es cualitativa y no numérica. El disparador son "large videos from an area with frequent network interruptions or other transmission failures", sin ningún umbral de bytes asociado. Las únicas cifras relacionadas que Meta sí publica son los techos de la especificación: los reels topan en 300 MB y 15 minutos, y las historias en 100 MB y 60 segundos. Ninguna se describe como umbral de reanudable.
Lectura práctica: usa reanudable siempre que tu archivo de origen sea local en lugar de estar ya en un CDN, porque la alternativa te obliga a alojar el archivo públicamente durante toda la descarga de Meta. Eso importa sobre todo en lo largo, que es donde subir vídeo de formato largo a Instagram se pone incómodo y donde los límites de duración de reels que Meta ha estado probando empujan los tamaños de archivo hacia arriba.

¿Cómo se reanuda de verdad una subida interrumpida?
Meta no lo documenta. Ese es el mayor hueco de la función, y está justo debajo del nombre de la función.
La cabecera offset es el único mecanismo que insinúa transferencias parciales, y los dos sitios donde Meta la describe apuntan al mismo valor: "offset is set to the first byte being upload, generally 0." No hay tamaño de fragmento documentado, ni endpoint que informe de cuántos bytes tiene ya el servidor, ni una segunda forma de petición para continuar una transferencia rota, ni un solo ejemplo en toda la documentación de Instagram Platform que pase un offset distinto de cero. Una sesión de subida "reanudable", tal y como está publicada, es un único POST del archivo entero con un campo de offset que en los ejemplos siempre vale cero.
Lo que Meta sí te da es un contenedor que sobrevive a un fallo el tiempo suficiente para reintentar desde el principio. Los contenedores expiran a las 24 horas, y una cuenta puede crear 400 en un periodo móvil de 24 horas. Una transferencia de bytes fallida cuesta un contenedor de esos 400, no una publicación de tu cuota diaria, así que reiniciar sale barato en el presupuesto que importa. Todo lo que se encola por adelantado tiene que respetar los mismos techos, que es la razón por la que las publicaciones programadas de Instagram fallan en la fase de contenedor más a menudo que en la de publicación.
¿Qué aspecto tiene una subida fallida?
Un fallo en el host rupload no vuelve como un objeto de error estándar de Graph API. Vuelve como un sobre debug_info con el error real convertido a cadena dentro:
{
"debug_info": {
"retriable": false,
"type": "ProcessingFailedError",
"message": "{\"success\":false,\"error\":{\"message\":\"unauthorized user request\"}}"
}
}Analiza retriable primero. Es el campo que te dice si un reintento merece el contenedor. false significa que la transferencia fallará igual otra vez, y el ejemplo que eligió Meta, una petición de usuario no autorizada, es exactamente ese tipo de fallo.
Los fallos que afloran después, del lado de Graph API, usan los pares normales de código y subcódigo.
| Síntoma | Código | Subcódigo | Mensaje |
|---|---|---|---|
| Subida fallida sin motivo declarado | -1 | 2207053 | unknown upload error |
| Contenedor expirado antes de publicar | -2 | 2207020 | The media you are trying to access has expired. Please try to upload again. |
| Contenedor no encontrado al publicar | 24 | 2207008 | The media builder with creation id = {creation-id} does not exist or has been expired. |
| Publicado demasiado pronto | 9007 | 2207027 | The media is not ready for publishing, please wait for a moment |
| Formato de vídeo rechazado | 352 | 2207026 | The video format is not supported. Please check spec for supported {video} format |
Meta acota 2207053 a este flujo en concreto: "An unknown error occured during upload. Generate a new container and use it to try again. This should only affect video uploads."

¿Qué errores aparecen después de que la subida tenga éxito?
Los que vienen del procesado, y solo los ves sondeando. Meta es explícito en que un ID de contenedor no demuestra nada: "Video uploads are asynchronous, so receiving a container ID does not guarantee that the upload was successful."
GET /<IG_CONTAINER_ID>?fields=status_code devuelve uno de cinco valores.
status_code | Significado que publica Meta |
|---|---|
IN_PROGRESS | El contenedor sigue en el proceso de publicación |
FINISHED | El contenedor y su objeto de medios están listos para publicarse |
ERROR | El contenedor no completó el proceso de publicación |
EXPIRED | El contenedor no se publicó en 24 horas y ha expirado |
PUBLISHED | El objeto de medios del contenedor se ha publicado |
Solo FINISHED es seguro para publicar. Pedir el campo status junto a status_code compensa el parámetro extra, porque Meta lo define como la línea de detalle: "If status_code is ERROR, this value will be an error subcode."
AdaptlyPost
Prueba gratis de 7 días
Analíticas multiplataforma
Bandeja Social
Asistente con IA
Meta limita el consejo de sondeo a una cadencia concreta: "We recommend querying a container's status once per minute, for no more than 5 minutes." Un reel largo puede seguir procesándose después de eso, y Meta no dice qué hacer a continuación. El patrón que funciona es seguir sondeando a un intervalo más lento hasta que el contenedor termine o llegue a la expiración de 24 horas, que es también como hay que construir la programación de reels a través de la API y cómo los contenedores de historias se comportan con su propio reloj de 24 horas.
Preguntas frecuentes
¿Qué hace upload_type=resumable en la API de Instagram?
Crea un contenedor que espera que empujes tú el vídeo a rupload.facebook.com, en lugar de que Meta lo vaya a buscar a un video_url que alojas. La respuesta incluye tanto un id como una uri que apunta al host de subida.
¿Qué host gestiona las subidas reanudables de Instagram?
rupload.facebook.com, en la ruta /ig-api-upload/<API_VERSION>/<IG_CONTAINER_ID>. La creación del contenedor, las comprobaciones de estado y la publicación se quedan en graph.facebook.com.
¿Qué cabeceras necesita la petición a rupload?
Authorization: OAuth <ACCESS_TOKEN> más offset y file_size para un archivo local, o file_url para un archivo ya alojado públicamente. Ojo con que los ejemplos de rupload usan OAuth donde los de Graph API usan Bearer.
¿Pueden las apps con Instagram Login usar subidas reanudables?
No. Meta restringe upload_type=resumable a las apps que han implementado Facebook Login for Business, y lista rupload.facebook.com solo bajo ese tipo de inicio de sesión.
¿A partir de qué tamaño de archivo exige Instagram una subida reanudable?
Meta no publica tal umbral. La guía recomienda reanudable para "large videos from an area with frequent network interruptions" sin nombrar un tamaño, y documenta el parámetro en sí como opcional.
¿Cómo se reanuda una subida rota de Instagram?
Meta no documenta ningún procedimiento de reanudación. La cabecera offset existe, pero todos los ejemplos publicados la ponen a 0, y ningún endpoint informa de cuántos bytes recibió ya el servidor. Genera un contenedor nuevo y empieza de cero.
¿Cuánto tiempo permanece válido un contenedor de subida de Instagram?
Un contenedor caduca 24 horas después de crearse, se haya publicado o no. Si se pierde esa ventana, Meta devuelve el código -2, subcódigo 2207020, con el mensaje de que el medio al que intentas acceder ha caducado y debes intentar subirlo de nuevo. El campo status_code refleja lo mismo con el valor EXPIRED.
¿Con qué frecuencia hay que consultar el estado de un contenedor de Instagram?
Meta limita su propia recomendación a una consulta por minuto, durante no más de 5 minutos. Un reel largo puede seguir en IN_PROGRESS pasado ese margen, y Meta no documenta qué hacer después. En la práctica conviene seguir consultando a un ritmo más lento hasta que el contenedor llegue a FINISHED o cumpla las 24 horas de caducidad.
¿Qué significa el campo retriable en un error de rupload?
Es el primer campo que hay que revisar en el sobre debug_info que devuelve rupload al fallar. Un valor false indica que la petición fallará de la misma manera si se reenvía, tal como ocurre en el ejemplo que pone Meta de una petición de usuario no autorizada. Comprobar retriable antes de reintentar evita gastar otro contenedor en una petición que no puede tener éxito.
¿El id de un contenedor significa que la subida a Instagram tuvo éxito?
Un id de contenedor por sí solo no prueba nada. Meta indica claramente que las subidas de vídeo son asíncronas, así que recibir un id de contenedor no garantiza que la subida saliera bien. La única forma de saberlo es consultar el contenedor con GET /<IG_CONTAINER_ID>?fields=status_code y esperar a que aparezca FINISHED antes de publicar.
Ponlo en práctica con AdaptlyPost
¿Te resultó útil este artículo?
¡Cuéntanos qué te parece!
Vernos más en Google
Un clic marca AdaptlyPost como fuente preferida y nuestros artículos aparecen más arriba en tus Noticias destacadas, el modo IA y los resúmenes con IA.
Antes de irte...
AdaptlyPost
Programa tu contenido en todas las plataformas
Gestiona todas tus cuentas de redes sociales en un solo lugar con AdaptlyPost.
Analíticas multiplataforma
Bandeja Social
Asistente con IA
Términos relacionados del glosario


Qué concede realmente el scope instagram_business_content_publish
El scope instagram_business_content_publish permite a una app crear posts orgánicos en Instagram, y depende de instagram_business_basic en cada llamada.


Todos los límites que la API de Reels de Instagram impone a tu vídeo
Meta limita en la API de Reels de Instagram un reel a 15 minutos y 300 MB y solo acepta MOV o MP4. Aquí están todas las especificaciones y sus errores.


Qué devuelve el endpoint content_publishing_limit de Instagram
El endpoint content_publishing_limit de Instagram devuelve quota_usage más un bloque config con quota_total 50 y quota_duration 86400 segundos.
Artículos Relacionados


Meta fija en 1.000 el límite de caracteres de alt_text en la API de Instagram
Meta fija el límite de caracteres de alt_text en la API de Instagram en 1.000 y lo restringe a imágenes fijas. Reels y stories no admiten texto alternativo.


Por qué un token de acceso de LinkedIn caduca a los 60 días
Cada token de acceso de LinkedIn dura 60 días y expires_in devuelve 5184000. Reglas del refresh token, qué lo mata antes y en qué difieren los 60 días de Meta.


Dónde está escrito realmente el límite de caracteres del texto alternativo de LinkedIn
Hay un solo número: el límite de caracteres del texto alternativo de LinkedIn es 4.086 en el campo altText de la API, y la app no publica ninguno.

