Glossário

A sessão de upload retomável do Instagram e o host rupload

Taras Shynkarenko
Taras Shynkarenko
Atualizado: 10 min de leitura
A sessão de upload retomável do Instagram e o host ruploadA sessão de upload retomável do Instagram e o host rupload

TL;DR, Resposta Rápida

10 min de leitura

Adicionar upload_type=resumable ao POST /<IG_ID>/media devolve um id e um uri em rupload.facebook.com em vez de buscar o seu vídeo por URL. O upload em si é um POST para esse host com os cabeçalhos Authorization OAuth, offset e file_size, ou um cabeçalho file_url para um arquivo já hospedado. A Meta restringe o fluxo a apps que usam Facebook Login for Business, não publica limite de tamanho que o torne obrigatório e não documenta jeito nenhum de retomar uma transferência interrompida.

O que é um upload retomável do Instagram?

A Meta chama isso de upload retomável do Instagram, e é um fluxo de dois hosts: POST /<IG_ID>/media com upload_type=resumable cria o container em graph.facebook.com e devolve um destino de upload, depois os bytes vão para rupload.facebook.com em uma segunda requisição que você controla.

O padrão é o arranjo oposto. Em um upload comum você passa video_url e a Meta busca o arquivo em você: "We will cURL your image using the passed in URL so it must be on a public server." O seu servidor responde a uma requisição do crawler da Meta, e a transferência dá certo ou errado em um lugar que você não enxerga. O retomável inverte isso. Você abre a conexão, você manda os bytes e você recebe uma resposta sobre eles.

A razão declarada da Meta para o fluxo aparece na lista de endpoints do guia de Content Publishing, com erro de digitação e tudo: "upload_type=resumable Create a resumbable upload session to upload large videos from an area with frequent network interruptions or other transmission failures."

O parâmetro em si é documentado como opcional e sensível a maiúsculas na referência de mídia: "An optional parameter for users want to upload video through the rupload protocol, values can be set to lowercase string value: resumable." Minúsculas importam. RESUMABLE não é um valor documentado.

Upload padrão versus upload retomável
Upload padrão
  • Você informa uma video_url e espera o Meta buscá-la
  • Seu servidor responde a uma requisição do rastreador do Meta
  • A transferência dá certo ou falha em um ponto que você não vê
Upload retomável
  • Você mesmo abre a conexão com rupload.facebook.com
  • Você envia os bytes e define os cabeçalhos offset e file_size
  • Você recebe a resposta sobre o upload diretamente
No upload retomável é você quem envia, em vez de esperar o Meta buscar o arquivo.

O que cada etapa do fluxo envia?

Quatro etapas, dois hosts e um esquema de autorização diferente em cada um.

EtapaHostRequisição
1. Abrir a sessãograph.facebook.comPOST /<IG_USER_ID>/media com media_type, upload_type=resumable, access_token
2. Mandar os bytesrupload.facebook.comPOST /ig-api-upload/<API_VERSION>/<IG_CONTAINER_ID> com Authorization, offset, file_size
3. Conferir o containergraph.facebook.comGET /<IG_CONTAINER_ID>?fields=status_code
4. Publicargraph.facebook.comPOST /<IG_ID>/media_publish com creation_id

A etapa um difere da criação de container comum no que ela deixa de fora. Não há video_url, porque ainda não existe nada para a Meta buscar. Uma sessão de reel tem o formato completo assim:

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>

A resposta carrega um segundo campo que um container comum não devolve:

{
  "id": "<IG_CONTAINER_ID>",
  "uri": "https://rupload.facebook.com/ig-api-upload/v25.0/<IG_CONTAINER_ID>"
}

Use o uri que a Meta te entrega em vez de montar o caminho na mão. A etapa dois então posta o arquivo nele:

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"

A Meta documenta os dois cabeçalhos numéricos em uma linha cada. "offset is set to the first byte being upload, generally 0." "file_size is set to the size of your file in bytes." Um arquivo já hospedado pula o corpo por completo e move a origem para um terceiro cabeçalho:

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>"

O sucesso são dois campos: {"success":true,"message":"Upload successful."}.

Por que o cabeçalho de autorização é diferente no rupload?

Porque a Meta o escreve de um jeito em cada host, e os exemplos estão lado a lado na mesma página. Chamadas a graph.facebook.com no guia de Content Publishing usam -H "Authorization: Bearer <ACCESS_TOKEN>". Toda chamada a rupload.facebook.com nessa mesma página usa -H "Authorization: OAuth <ACCESS_TOKEN>".

Mesmo token, nome de esquema diferente. A Meta não dá explicação, e os exemplos de rupload nunca mostram Bearer. Copie o esquema do exemplo que corresponde ao host que você está chamando.

Mais dois detalhes se perdem fácil nos blocos de código. O curl publicado pela Meta para a etapa de rupload contém uma crase perdida dentro da URL, entre o placeholder do ID do container e as aspas de fechamento. É erro de digitação no documento, não parte da sintaxe. E a própria lista de parâmetros do guia de Content Publishing para a etapa de upload para no meio da frase: ela anuncia "the following parameters", imprime access_token e termina em um marcador vazio. A lista completa de cabeçalhos só existe na referência do endpoint de mídia, não no guia.

Quando o retomável é obrigatório em vez de opcional?

A Meta nunca publica um tamanho de arquivo que o torne obrigatório, e a resposta honesta é que a única exigência dura é sobre o seu fluxo de login, não sobre o seu arquivo.

O guia de Content Publishing restringe o fluxo inteiro em uma oração: upload_type=resumable é "Only for apps that have implemented Facebook Login for Business." A tabela de requisitos na mesma página confirma isso ao listar URLs de host por tipo de login. Instagram API com Instagram Login recebe graph.instagram.com. Instagram API com Facebook Login recebe graph.facebook.com e rupload.facebook.com, anotado como "(For resumable video uploads)".

AdaptlyPost
AdaptlyPost

Teste grátis de 7 dias

Análises multiplataforma

Caixa Social

Assistente com IA

Então um app construído sobre o Business Login for Instagram não consegue usar retomável de jeito nenhum. O vídeo tem que chegar por video_url e pela busca da Meta. Essa é uma decisão de arquitetura de login tomada muito antes de alguém subir um arquivo, e não é reversível por requisição.

Onde o retomável está disponível, a orientação da Meta é qualitativa, não numérica. O gatilho é "large videos from an area with frequent network interruptions or other transmission failures", sem nenhum limiar em bytes anexado. Os únicos números relacionados que a Meta publica são os tetos da especificação: reels param em 300 MB e 15 minutos, stories em 100 MB e 60 segundos. Nenhum dos dois é descrito como limiar de retomável.

Leitura prática: use retomável sempre que o seu arquivo de origem for local em vez de já estar em um CDN, porque a alternativa exige que você hospede o arquivo publicamente durante toda a busca da Meta. Isso pesa mais em qualquer coisa longa, que é onde subir vídeo de formato longo para o Instagram fica chato e onde os limites de duração de reel que a Meta vem testando empurram os tamanhos de arquivo para cima.

Um celular no meio de um upload com sinal fraco, a situação para a qual o upload retomável existe.

Como se retoma de fato um upload interrompido?

A Meta não documenta. Essa é a maior lacuna do recurso, e ela fica bem embaixo do nome do recurso.

O cabeçalho offset é o único mecanismo que sugere transferências parciais, e os dois lugares em que a Meta o descreve apontam para o mesmo valor: "offset is set to the first byte being upload, generally 0." Não há tamanho de bloco documentado, nem endpoint que informe quantos bytes o servidor já tem, nem segundo formato de requisição para continuar uma transferência interrompida, nem exemplo em lugar nenhum da documentação da Instagram Platform que passe um offset diferente de zero. Uma sessão de upload "resumable", como está publicada, é um único POST do arquivo inteiro com um campo de offset que é sempre zero nos exemplos.

O que a Meta te dá de fato é um container que sobrevive a uma falha por tempo suficiente para você tentar de novo desde o início. Containers expiram depois de 24 horas, e uma conta pode criar 400 deles em um período móvel de 24 horas. Uma transferência de bytes que falha custa um container dos 400, não uma publicação da sua cota diária, então recomeçar sai barato no orçamento que importa. Qualquer coisa enfileirada com antecedência ainda precisa respeitar os mesmos tetos, e é por isso que posts agendados do Instagram falham na etapa do container mais do que na etapa da publicação.

Como é um upload que falhou?

Uma falha no host rupload não volta como objeto de erro padrão da Graph API. Ela volta como um envelope debug_info com o erro real convertido em string lá dentro:

{
  "debug_info": {
    "retriable": false,
    "type": "ProcessingFailedError",
    "message": "{\"success\":false,\"error\":{\"message\":\"unauthorized user request\"}}"
  }
}

Leia retriable primeiro. É o campo que diz se uma nova tentativa vale o container. false significa que a transferência vai falhar do mesmo jeito de novo, e o exemplo que a Meta escolheu, uma requisição de usuário não autorizada, é exatamente esse tipo de falha.

Falhas que aparecem mais tarde, do lado da Graph API, usam os pares normais de código e subcódigo.

SintomaCódigoSubcódigoMensagem
Upload falhou sem razão declarada-12207053unknown upload error
Container expirou antes da publicação-22207020The media you are trying to access has expired. Please try to upload again.
Container não encontrado na publicação242207008The media builder with creation id = {creation-id} does not exist or has been expired.
Publicado cedo demais90072207027The media is not ready for publishing, please wait for a moment
Formato de vídeo rejeitado3522207026The video format is not supported. Please check spec for supported {video} format

A Meta delimita o 2207053 a esse fluxo em específico: "An unknown error occured during upload. Generate a new container and use it to try again. This should only affect video uploads."

Um painel de status numa tela de sala de servidores, o tipo de visão que um loop de polling consulta.

Quais erros aparecem depois que o upload dá certo?

Os que vêm do processamento, e você só os vê consultando. A Meta é explícita de que um ID de container não prova 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 devolve um entre cinco valores.

status_codeSignificado que a Meta publica
IN_PROGRESSO container ainda está no processo de publicação
FINISHEDO container e o objeto de mídia dele estão prontos para publicar
ERRORO container falhou ao completar o processo de publicação
EXPIREDO container não foi publicado em 24 horas e expirou
PUBLISHEDO objeto de mídia do container foi publicado

FINISHED é seguro para publicar. Pedir o campo status junto com status_code vale o parâmetro extra, porque a Meta o define como a linha de detalhe: "If status_code is ERROR, this value will be an error subcode."

AdaptlyPost
AdaptlyPost

Teste grátis de 7 dias

Análises multiplataforma

Caixa Social

Assistente com IA

A Meta limita o conselho de consulta a uma cadência específica: "We recommend querying a container's status once per minute, for no more than 5 minutes." Um reel longo pode continuar processando depois disso, e a Meta não diz o que fazer em seguida. O padrão que funciona é continuar consultando em intervalo mais lento até o container terminar ou bater na expiração de 24 horas, que também é como agendar reels pela API precisa ser construído e como containers de story se comportam no próprio relógio de 24 horas.

Perguntas frequentes

O que upload_type=resumable faz na Instagram API?

Ele cria um container que espera que você empurre o vídeo para rupload.facebook.com por conta própria, em vez de fazer a Meta buscá-lo em uma video_url que você hospeda. A resposta inclui tanto um id quanto um uri apontando para o host de upload.

Qual host trata os uploads retomáveis do Instagram?

rupload.facebook.com, no caminho /ig-api-upload/<API_VERSION>/<IG_CONTAINER_ID>. Criação de container, checagem de status e publicação ficam todas em graph.facebook.com.

De quais cabeçalhos a requisição ao rupload precisa?

Authorization: OAuth <ACCESS_TOKEN> mais offset e file_size para um arquivo local, ou file_url para um arquivo já hospedado publicamente. Note que os exemplos de rupload usam OAuth onde os exemplos da Graph API usam Bearer.

Apps que usam Instagram Login podem usar uploads retomáveis?

Não. A Meta restringe o upload_type=resumable a apps que implementaram o Facebook Login for Business, e lista rupload.facebook.com apenas sob esse tipo de login.

A partir de que tamanho de arquivo o Instagram exige um upload retomável?

A Meta não publica limiar nenhum. O guia recomenda retomável para "large videos from an area with frequent network interruptions" sem nomear um tamanho, e documenta o próprio parâmetro como opcional.

Como se retoma um upload interrompido do Instagram?

A Meta não documenta procedimento de retomada. O cabeçalho offset existe, mas todo exemplo publicado o define como 0, e nenhum endpoint informa quantos bytes o servidor já recebeu. Gere um container novo e comece de novo.

Por quanto tempo um container de upload do Instagram permanece válido?

Um container expira 24 horas depois de criado, tenha sido publicado ou não. Se essa janela passar, o Meta devolve o código -2, subcódigo 2207020, com a mensagem de que a mídia que você tenta acessar expirou e é preciso tentar o upload de novo. O campo status_code registra o mesmo com o valor EXPIRED.

Com que frequência é preciso consultar o status de um container do Instagram?

O Meta limita a própria recomendação a uma consulta por minuto, por no máximo 5 minutos. Um reel longo ainda pode aparecer como IN_PROGRESS depois desse prazo, e o Meta não documenta o que fazer a seguir. Na prática, o jeito é continuar consultando em intervalos mais espaçados até o container chegar a FINISHED ou vencer as 24 horas de validade.

O que significa o campo retriable em um erro do rupload?

É o primeiro campo a checar no envelope debug_info que o rupload devolve quando falha. Um valor false significa que a requisição vai falhar do mesmo jeito se for reenviada, como no exemplo que o Meta usa de uma requisição de usuário não autorizado. Checar o retriable antes de tentar de novo evita gastar outro container em uma requisição que não tem como dar certo.

O id de um container significa que o upload do Instagram deu certo?

Um id de container sozinho não prova nada. O Meta é claro ao dizer que uploads de vídeo são assíncronos, então receber um id de container não garante que o upload funcionou. A única forma de saber é consultar o container com GET /<IG_CONTAINER_ID>?fields=status_code e esperar o status FINISHED antes de publicar.

Este artigo foi útil para você?

Conte-nos o que você achou!

Veja-nos mais no Google

Um clique marca a AdaptlyPost como fonte preferida e nossos artigos passam a aparecer mais acima nas suas Principais notícias, no modo IA e nas visões gerais com IA.

Antes de ir...

AdaptlyPost

AdaptlyPost

Agende seu conteúdo em todas as plataformas

Gerencie todas as suas contas de redes sociais em um só lugar com o AdaptlyPost.

Análises multiplataforma

Caixa Social

Assistente com IA

Termos relacionados do glossário

Artigos Relacionados