O upload de arquivos via API é uma necessidade técnica comum que os desenvolvedores enfrentam ao chamar interfaces para geração de vídeo por IA, processamento de imagens, entre outros. Este artigo explicará sistematicamente como funciona o método de codificação multipart/form-data e usará a API de imagem para vídeo do Sora 2 como exemplo para ajudar você a dominar essa habilidade essencial.
Valor central: Ao final deste artigo, você entenderá completamente o mecanismo interno do multipart/form-data, aprenderá a usar o comando curl -F para upload de arquivos e será capaz de implementar de forma independente a função de upload de imagens para APIs de IA como a do Sora 2.

Conhecimentos essenciais sobre upload de arquivos via API
Antes de mergulharmos no código, precisamos entender por que o upload de arquivos via API exige um método de codificação especial.
Por que precisamos do multipart/form-data?
Quando você envia dados de texto comuns via API, pode usar a codificação simples application/x-www-form-urlencoded. No entanto, esse método apresenta problemas sérios ao lidar com arquivos:
| Tipo de Codificação | Cenário de Uso | Capacidade de Arquivos | Eficiência |
|---|---|---|---|
application/x-www-form-urlencoded |
Pares chave-valor simples | ❌ Não adequado | Requer escape de URL para binários, baixa eficiência |
application/json |
Dados estruturados | ⚠️ Requer Base64 | O volume aumenta em 33% |
multipart/form-data |
Upload de arquivos | ✅ Suporte nativo | Sem codificação necessária, eficiente |
O multipart/form-data é uma solução proposta pelo padrão RFC 2388 em 1998, projetada especificamente para resolver o problema de envio misto de dados de texto e binários no protocolo HTTP.
Como funciona o multipart/form-data
A ideia central do multipart/form-data é dividir o corpo de uma requisição HTTP em várias "partes" (parts) independentes, onde cada parte pode ter seu próprio tipo de conteúdo.

Detalhamento da estrutura de dados
Uma requisição multipart/form-data típica contém a seguinte estrutura:
POST /v1/videos HTTP/1.1
Host: api.apiyi.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxk
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="prompt"
Ela se vira e sorri
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="model"
sora-2-pro
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="input_reference"; filename="sample.jpeg"
Content-Type: image/jpeg
[Dados binários da imagem]
------WebKitFormBoundary7MA4YWxk--
| Componente | Função | Exemplo |
|---|---|---|
| Boundary | Identificador único que separa as partes de dados | ----WebKitFormBoundary7MA4YWxk |
| Content-Disposition | Descreve os metadados daquela parte | form-data; name="prompt" |
| Content-Type | O tipo MIME daquela parte | image/jpeg |
| Corpo (Body) | O conteúdo real dos dados | Texto ou dados binários |
🎯 Ponto técnico: O Boundary deve ser uma string única que não apareça no corpo da requisição. O servidor usa o boundary para analisar e separar cada parte dos dados.
Guia do comando curl -F: Prática de Upload de Arquivos via API
O curl é a ferramenta de linha de comando mais utilizada como cliente HTTP, e seu parâmetro -F é projetado especificamente para requisições multipart/form-data.
Sintaxe Básica do curl -F
curl -F "nome_do_campo=valor" URL
curl -F "campo_do_arquivo=@caminho/do/arquivo/local" URL
| Forma do Parâmetro | Descrição | Exemplo |
|---|---|---|
-F "key=value" |
Envia um campo de texto comum | -F "prompt=Olá" |
-F "key=@file" |
Faz o upload de um arquivo local | -F "[email protected]" |
-F "key=@file;type=mime" |
Especifica o tipo MIME do arquivo | -F "[email protected];type=image/jpeg" |
-F "key=@file;filename=novo.jpg" |
Personaliza o nome do arquivo no upload | -F "[email protected];filename=upload.jpg" |
Diferença entre curl -F e outros parâmetros
Muitos desenvolvedores confundem o uso de -F, -d e -X POST:
# ❌ Errado: -d é usado para x-www-form-urlencoded, não é adequado para upload de arquivos
curl -X POST -d "[email protected]" https://api.example.com/upload
# ❌ Errado: Especificar o Content-Type manualmente mas usar -d
curl -X POST -H "Content-Type: multipart/form-data" -d "..." https://api.example.com/upload
# ✅ Correto: O uso de -F define automaticamente o Content-Type e o boundary corretos
curl -F "[email protected]" https://api.example.com/upload
Explicação Técnica: Ao usar
-F, o curl automaticamente:
- Define o método da requisição como POST
- Define
Content-Type: multipart/form-data- Gera um
boundaryúnico- Formata o corpo da requisição de acordo com os padrões RFC
Prática de Upload de Arquivos com a API do Sora 2
O Sora 2 é o modelo de geração de vídeo lançado pela OpenAI, que permite o upload de imagens de referência via API para gerar vídeos. Este é um cenário típico de aplicação do multipart/form-data.
Parâmetros da API de Imagem-para-Vídeo do Sora 2
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
prompt |
string | ✅ | Texto descritivo do vídeo (comando) |
model |
string | ❌ | Seleção do modelo: sora-2 ou sora-2-pro |
size |
string | ❌ | Resolução: 1280x720, 720x1280, 1024x1792, 1792x1024 |
seconds |
integer | ❌ | Duração: 4, 8, ou 12 segundos |
input_reference |
file | ❌ | Imagem de referência, usada como o primeiro frame do vídeo |

Comparativo de Modelos Sora 2
| Característica | sora-2 | sora-2-pro |
|---|---|---|
| Qualidade de Geração | Boa | Excelente |
| Velocidade de Renderização | Rápida | Lenta |
| Cenário de Uso | Protótipos, Prova de Conceito | Saída de nível profissional |
| Preço | Padrão | Alto |
| Plataformas Disponíveis | APIYI (apiyi.com), API Oficial | APIYI (apiyi.com), API Oficial |
Exemplo Completo de Upload de Arquivo no Sora 2
Abaixo está um exemplo completo de como usar o curl para chamar a API do Sora 2 para gerar um vídeo a partir de uma imagem:
curl -X POST "https://api.apiyi.com/v1/videos" \
-H "Authorization: Bearer $APIYI_KEY" \
-H "Content-Type: multipart/form-data" \
-F prompt="She turns around and smiles, then slowly walks out of the frame." \
-F model="sora-2-pro" \
-F size="1280x720" \
-F seconds="8" \
-F input_reference="@sample_720p.jpeg;type=image/jpeg"
Análise do Comando
| Parte | Descrição |
|---|---|
curl -X POST |
Especifica o método de requisição POST |
"https://api.apiyi.com/v1/videos" |
Endpoint de geração de vídeo do Sora 2 na APIYI |
-H "Authorization: Bearer $APIYI_KEY" |
Usa uma variável de ambiente para passar a chave da API |
-H "Content-Type: multipart/form-data" |
Declara o tipo de conteúdo (o curl -F adiciona isso automaticamente) |
-F prompt="..." |
Comando descritivo para o vídeo |
-F model="sora-2-pro" |
Seleciona o modelo de alta qualidade |
-F size="1280x720" |
Resolução 720p (widescreen) |
-F seconds="8" |
Duração de 8 segundos |
-F input_reference="@sample_720p.jpeg;type=image/jpeg" |
Faz o upload da imagem de referência |
🚀 Início Rápido: Recomendamos usar a plataforma APIYI (apiyi.com) para testar rapidamente a API do Sora 2. A plataforma oferece interfaces prontas para uso, permitindo a integração sem configurações complexas.
Observações sobre o Upload de Imagens
Ao fazer o upload de imagens de referência para a API do Sora 2, atente-se aos seguintes pontos:
| Requisito | Descrição |
|---|---|
| Correspondência de Resolução | A resolução da imagem deve coincidir com o parâmetro size do vídeo alvo |
| Formatos Suportados | image/jpeg, image/png, image/webp |
| Tamanho do Arquivo | Recomendado não exceder 10MB |
| Qualidade da Imagem | Imagens nítidas e com boa composição produzem resultados melhores |
Implementação de upload multipart/form-data com Python
Além do curl, no desenvolvimento real é muito mais comum usar linguagens de programação para realizar o upload de arquivos. Abaixo, mostramos como fazer isso com Python.
Exemplo minimalista
import requests
# Usando a interface unificada da APIYI
url = "https://api.apiyi.com/v1/videos"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
# Preparando os dados multipart
files = {
"input_reference": ("sample.jpeg", open("sample_720p.jpeg", "rb"), "image/jpeg")
}
data = {
"prompt": "She turns around and smiles, then slowly walks out of the frame.",
"model": "sora-2-pro",
"size": "1280x720",
"seconds": "8"
}
response = requests.post(url, headers=headers, data=data, files=files)
print(response.json())
Ver código completo (incluindo tratamento de erro e polling)
import requests
import time
import os
class Sora2Client:
"""Cliente API Sora 2 - Suporta upload de arquivos multipart/form-data"""
def __init__(self, api_key: str, base_url: str = "https://api.apiyi.com/v1"):
self.api_key = api_key
self.base_url = base_url
self.headers = {"Authorization": f"Bearer {api_key}"}
def create_video(
self,
prompt: str,
model: str = "sora-2",
size: str = "1280x720",
seconds: int = 8,
input_reference: str = None
) -> dict:
"""
Cria uma tarefa de geração de vídeo
Args:
prompt: Descrição do vídeo (comando)
model: Escolha do modelo (sora-2 ou sora-2-pro)
size: Resolução
seconds: Duração (4, 8, 12)
input_reference: Caminho da imagem de referência (opcional)
Returns:
Dicionário com informações da tarefa
"""
url = f"{self.base_url}/videos"
data = {
"prompt": prompt,
"model": model,
"size": size,
"seconds": str(seconds)
}
files = None
if input_reference and os.path.exists(input_reference):
# Determina o tipo MIME com base na extensão do arquivo
ext = os.path.splitext(input_reference)[1].lower()
mime_types = {
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".webp": "image/webp"
}
mime_type = mime_types.get(ext, "application/octet-stream")
files = {
"input_reference": (
os.path.basename(input_reference),
open(input_reference, "rb"),
mime_type
)
}
try:
response = requests.post(
url,
headers=self.headers,
data=data,
files=files,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {"error": str(e)}
finally:
if files and "input_reference" in files:
files["input_reference"][1].close()
def get_video_status(self, video_id: str) -> dict:
"""Consulta o status de geração do vídeo"""
url = f"{self.base_url}/videos/{video_id}"
response = requests.get(url, headers=self.headers, timeout=30)
return response.json()
def wait_for_completion(self, video_id: str, poll_interval: int = 10) -> dict:
"""Realiza polling e aguarda a conclusão da geração do vídeo"""
while True:
status = self.get_video_status(video_id)
if status.get("status") in ["completed", "failed"]:
return status
print(f"Status: {status.get('status')}... aguardando {poll_interval}s")
time.sleep(poll_interval)
# Exemplo de uso
if __name__ == "__main__":
client = Sora2Client(api_key=os.getenv("APIYI_KEY"))
# Criar tarefa de imagem para vídeo
result = client.create_video(
prompt="She turns around and smiles, then slowly walks out of the frame.",
model="sora-2-pro",
size="1280x720",
seconds=8,
input_reference="sample_720p.jpeg"
)
if "id" in result:
print(f"Tarefa criada: {result['id']}")
final_result = client.wait_for_completion(result["id"])
print(f"URL do Vídeo: {final_result.get('video_url')}")
else:
print(f"Erro: {result}")
Sugestão: Obtenha créditos de teste gratuitos em APIYI apiyi.com para validar rapidamente a funcionalidade de geração de vídeo a partir de imagem.
Processamento multipart da biblioteca requests
Pontos-chave do processamento de multipart/form-data na biblioteca requests do Python:
| Parâmetro | Finalidade | Descrição |
|---|---|---|
data |
Campos comuns do formulário | Formato de dicionário: {"key": "value"} |
files |
Campos de arquivo | Formato de tupla: {"name": (filename, file_obj, content_type)} |
⚠️ Atenção: Ao usar os parâmetros
dataandfilessimultaneamente, o requests configurará automaticamente oContent-Typee o boundary corretos, sem necessidade de especificação manual.
Solução em JavaScript/Node.js
Ambiente de navegador (API FormData)
const formData = new FormData();
formData.append('prompt', 'She turns around and smiles');
formData.append('model', 'sora-2-pro');
formData.append('size', '1280x720');
formData.append('seconds', '8');
formData.append('input_reference', fileInput.files[0]);
fetch('https://api.apiyi.com/v1/videos', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
// Atenção: Não defina o Content-Type manualmente
},
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
Ambiente Node.js
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
const form = new FormData();
form.append('prompt', 'She turns around and smiles');
form.append('model', 'sora-2-pro');
form.append('size', '1280x720');
form.append('seconds', '8');
form.append('input_reference', fs.createReadStream('sample_720p.jpeg'), {
contentType: 'image/jpeg'
});
axios.post('https://api.apiyi.com/v1/videos', form, {
headers: {
...form.getHeaders(),
'Authorization': 'Bearer YOUR_API_KEY'
}
})
.then(response => console.log(response.data));
💡 Dica importante: Ao usar FormData no navegador, não defina manualmente o header
Content-Type. O navegador adicionará automaticamente o parâmetro boundary correto.
Solução de problemas comuns com multipart/form-data
Motivos comuns para falhas no upload
| Problema | Sintoma | Solução |
|---|---|---|
| Boundary ausente | O servidor retorna 400 | Não defina o Content-Type manualmente; deixe a ferramenta gerá-lo automaticamente |
| Erro no tipo MIME | Arquivo rejeitado | Use ;type=image/jpeg para especificar claramente |
| Erro no caminho do arquivo | Arquivo não encontrado | Certifique-se de que o caminho após o @ esteja correto; suporta caminhos relativos/absolutos |
| Resolução incompatível | Erro na API do Sora | A resolução da imagem deve corresponder ao parâmetro size |
| Arquivo muito grande | Tempo limite esgotado ou rejeitado | Comprima a imagem ou faça o upload em partes (multipart) |
Dicas de depuração
Use o parâmetro -v do curl para visualizar a requisição completa:
curl -v -F "[email protected]" https://api.example.com/upload
Isso exibirá:
- Cabeçalhos da requisição (incluindo o Content-Type e boundary gerados automaticamente)
- Estrutura do corpo da requisição
- Resposta do servidor
Perguntas Frequentes
Q1: O que é melhor: multipart/form-data ou codificação Base64?
O multipart/form-data é mais indicado para uploads de arquivos. A codificação Base64 aumenta o tamanho do arquivo em cerca de 33%, o que eleva o tempo de transmissão na rede e a carga de processamento do servidor. O multipart/form-data transmite dados binários diretamente, sendo muito mais eficiente.
No entanto, em alguns cenários específicos (como WebSockets ou APIs JSON de campo único), o Base64 pode ser a única opção. Ao chamar APIs através da plataforma APIYI (apiyi.com), priorize o uso de multipart/form-data para obter uma melhor performance.
Q2: Por que meu upload com curl -F falhou?
Os motivos mais comuns incluem:
- Problemas no caminho do arquivo: Verifique se o símbolo
@está seguido pelo caminho correto do arquivo. - Problemas de permissão: Verifique se você tem permissão de leitura para o arquivo.
- Tipo MIME: Algumas APIs exigem que você especifique o content-type correto.
Sugerimos validar o formato da requisição no ambiente de testes da APIYI (apiyi.com), onde a plataforma fornece mensagens de erro detalhadas para ajudar a localizar o problema rapidamente.
Q3: Quais formatos de imagem a API do Sora 2 suporta?
A API do Sora 2 suporta os seguintes formatos de imagem para o input_reference:
- JPEG (
.jpg,.jpeg) – Recomendado, possui boa taxa de compressão. - PNG (
.png) – Suporta canal alfa (transparência). - WebP (
.webp) – Formato moderno com tamanho de arquivo reduzido.
Lembre-se: a resolução da imagem deve ser idêntica ao parâmetro size do vídeo de destino. Por exemplo, se estiver usando a resolução 1280x720, a imagem de referência também deve ter 1280×720.
Q4: Como lidar com uploads de arquivos muito grandes?
Para lidar com arquivos grandes, você pode considerar:
- Upload em partes (Chunked upload): Dividir o arquivo em pequenos blocos e enviá-los sequencialmente.
- Otimização de compressão: Comprimir o arquivo o máximo possível sem comprometer a qualidade necessária.
- Retomada de upload (Resumable upload): Implementar suporte para continuar o upload de onde parou em caso de falha.
O multipart/form-data suporta transmissão via stream (fluxo), permitindo que o servidor processe os dados enquanto os recebe, o que é ideal para cenários de arquivos grandes.
Resumo
Neste artigo, exploramos em detalhes a tecnologia principal para upload de arquivos via API: o multipart/form-data.
Revisão dos pontos-chave:
| Ponto Principal | Descrição |
|---|---|
| Princípios de Codificação | Uso de boundary para separar as partes dos dados; cada parte possui seu próprio Content-Type. |
Comando curl -F |
-F "key=value" para enviar texto, -F "key=@file" para fazer upload de arquivos. |
| Sora 2 na prática | Uso do parâmetro input_reference para enviar imagens de referência; a resolução deve ser compatível. |
| Implementação Multilinguagem | Python requests / JavaScript FormData. |
| Dicas de Depuração | Use curl -v para visualizar todos os detalhes da requisição. |
Dominar o multipart/form-data é uma habilidade fundamental para o desenvolvimento de APIs de IA. Seja para a geração de vídeos no Sora 2, compreensão de imagens no GPT-4 Vision ou qualquer outra API que exija upload de arquivos, os princípios fundamentais são os mesmos.
Recomendamos utilizar o APIYI (apiyi.com) para validar rapidamente as funções de upload de arquivos e experimentar uma interface de API unificada com suporte técnico detalhado.
Autor: Equipe APIYI | Focada em compartilhar tecnologia de APIs de Modelos de Linguagem Grande (LLM)
Troca de Conhecimento: Acesse apiyi.com para obter mais recursos de desenvolvimento de API
Referências
-
RFC 2388: Especificação padrão do multipart/form-data
- Link:
tools.ietf.org/html/rfc2388
- Link:
-
Documentação Oficial do curl: Multipart Formposts
- Link:
everything.curl.dev/http/post/multipart
- Link:
-
MDN Web Docs: Usando Objetos FormData
- Link:
developer.mozilla.org/pt-BR/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects
- Link:
-
Documentação da API OpenAI Sora: Guia de Geração de Vídeo
- Link:
platform.openai.com/docs/guides/video-generation
- Link:
