Chat

Entrada de imagemns, PDFs, áudio e vídeo

Inclua imagens, PDFs, áudio e vídeo em uma mensagem para os modelos que conseguem lê-los. Envie o próprio arquivo (base64) ou um link: nós buscamos os links, então qualquer link https público para um arquivo de até 20 MB funciona.

Visão geral

Para enviar/v1/chat/completions (every model)/v1/messages (Claude)Formatos
Uma imagemParte image_urlBloco imagePNG, JPEG, WebP, GIF
Um PDFParte fileBloco documentPDF
Uma gravaçãoParte input_audioClaude não ouve áudioWAV, MP3
Um vídeoParte video_urlClaude não assiste a vídeosMP4, MOV, WebM
Texto, código, CSV, Word, ExcelO próprio texto, na mensagemUm bloco text, ou um document em texto simplesTexto

Cada parte aceita um link https público ou o próprio arquivo como uma data URL em base64, como data:application/pdf;base64,JVBERi0.... Você pode enviar vários arquivos em uma mensagem, combinando os tipos que o modelo lê.

O que cada modelo lê

Todo modelo de chat lê texto. Esta tabela é atualizada em tempo real: ela mostra o que cada modelo lê hoje. Se um modelo receber algo que não lê, a solicitação é recusada imediatamente com unsupported_content, para que ele nunca responda sobre um arquivo que não viu.

Imagens

Adicione uma parte image_url com um link ou uma data URL. PNG, JPEG, WebP e GIF. Todos os modelos que leem imagens aceitam várias imagens na mesma mensagem.

import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
response = client.chat.completions.create(
model="gemini-3.7-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "What's in this picture? One sentence."
},
{
"type": "image_url",
"image_url": {
"url": "https://zurelay.com/examples/gpt-image-2.5-flare/watch-800.webp"
}
}
]
}
],
)
print(response.choices[0].message.content)

Para enviar um arquivo do disco, codifique-o em base64 em uma data URL:

import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
with open("receipt.jpg", "rb") as f:
data_url = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="claude-sonnet-5-5",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What's the total on this receipt?"},
{"type": "image_url", "image_url": {"url": data_url}},
],
}],
)
print(response.choices[0].message.content)

detail (low, high, auto) é repassado aos modelos que o utilizam.

PDFs

Adicione uma parte file com o PDF como data URL em file_data e o nome do arquivo. Os modelos leem o texto e, quando possível, as páginas como imagens (gráficos, digitalizações, tabelas). Um link público também funciona em file_data.

import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
with open("contract.pdf", "rb") as f:
pdf = "data:application/pdf;base64," + base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gemini-3.7-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Who are the parties, and how can the contract be ended?"},
{"type": "file", "file": {"filename": "contract.pdf", "file_data": pdf}},
],
}],
)
print(response.choices[0].message.content)

PDFs longos consomem tokens de entrada por página (veja a seção de cobrança abaixo), então envie apenas as páginas de que você precisa. Para perguntar sobre vários documentos de uma vez, adicione uma parte file para cada um, com nomes que permitam distingui-los.

Word, Excel, texto e código

Os modelos leem PDFs, não arquivos do Word, Excel ou PowerPoint. Coloque texto, CSV, JSON, Markdown ou código diretamente na mensagem como texto: a cobrança é feita como tokens de entrada comuns, e é o formato que o modelo lê melhor. Quando o layout importar (tabelas, gráficos, digitalizações), exporte o arquivo para PDF e envie esse PDF. Uma data URL de qualquer outro tipo, como text/plain, é recusada com um erro que explica o motivo.

import os
from pathlib import Path
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
notes = Path("meeting-notes.md").read_text()
sales = Path("sales.csv").read_text()
response = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=[{
"role": "user",
"content": f"Summarize the notes, then total the sales by region.\n\n"
f"<notes>\n{notes}\n</notes>\n\n<sales>\n{sales}\n</sales>",
}],
)
print(response.choices[0].message.content)

Áudio

Para modelos que ouvem (veja a tabela): uma parte input_audio com o áudio em base64 e seu formato, wav ou mp3. input_audio recebe o próprio áudio; para enviar um link, use uma parte file com o link em file_data. Gravações feitas no navegador geralmente são WebM, que é lido como vídeo: converta-as para MP3 ou WAV para modelos que só ouvem.

import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
with open("call.mp3", "rb") as f:
audio = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gemini-3.7-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Transcribe this call, then list the action items."},
{"type": "input_audio", "input_audio": {"data": audio, "format": "mp3"}},
],
}],
)
print(response.choices[0].message.content)

Vídeo

Para modelos que assistem a vídeos: uma parte video_url com um link ou uma data URL (uma parte file também funciona). MP4, MOV e WebM. Modelos com suporte a som também leem a faixa de áudio, então você pode perguntar o que foi dito.

import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
response = client.chat.completions.create(
model="gemini-3.7-flash",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Describe what happens, and transcribe anything that's said."
},
{
"type": "video_url",
"video_url": {
"url": "https://example.com/clip.mp4"
}
}
]
}
],
)
print(response.choices[0].message.content)

Um vídeo do disco é enviado da mesma forma, como uma data URL:

Python
with open("clip.mp4", "rb") as f:
video = "data:video/mp4;base64," + base64.b64encode(f.read()).decode()
content = [
{"type": "text", "text": "What happens in this clip?"},
{"type": "video_url", "video_url": {"url": video}},
]

Um formato na entrada, o formato certo na saída

Cada laboratório recebe mídia em formatos diferentes (um vídeo pode ser uma parte video_url, image_url ou file, dependendo da documentação que você consultar). Envie qualquer um deles: entregamos a mídia a cada modelo no formato que ele lê.

Vários arquivos em uma mensagem

Adicione uma parte para cada arquivo, na ordem em que você quer que sejam lidos, e faça referência a eles no texto pela ordem ou pelo nome (“a segunda imagemm”, “contract.pdf”). Você pode combinar imagens, PDFs, áudio e vídeo, desde que o modelo leia cada tipo. Partes de texto podem ficar entre os arquivos para identificá-los.

  • Os links devem ser URLs https públicas. Seguimos até três redirecionamentos e esperamos até 20 segundos.
  • Um link que não permite baixar o arquivo é recusado imediatamente com invalid_url e o status retornado, antes de qualquer modelo ser chamado.
  • Links assinados (S3, Cloud Storage, nossos próprios links de imagem) funcionam enquanto forem válidos.

Formato da Anthropic

Em /v1/messages, os modelos Claude aceitam os blocos da Anthropic: image e document, com uma origem base64 ou url. Alguns modelos Claude leem PDFs apenas por /v1/chat/completions; se você enviar um para /v1/messages, o erro informa para onde enviá-lo.

Blocos de conteúdo
[
{ "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgo..." } },
{ "type": "document", "source": { "type": "url", "url": "https://example.com/report.pdf" } },
{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": "JVBERi0..." } },
{ "type": "text", "text": "Compare the chart with the report's conclusion." }
]

Limites

LimiteValor
Um arquivo20 MB
Todas as mídias em uma requisição30 MB
Corpo da requisição (base64 acrescenta cerca de um terço)25 MB
Partes de mídia por requisição100
Links por requisição20

Para arquivos maiores, envie um link: ele não conta para o tamanho do corpo da requisição. Arquivos enviados à Files API do próprio laboratório (file_id) não podem ser usados; envie o arquivo ou um link.

Erros

StatusErroQuando
400unsupported_contentO modelo não lê esse tipo de arquivo. Escolha um que leia na tabela acima.
400invalid_urlNão foi possível baixar um link. A mensagem informa o motivo (status, tempo limite excedido ou conteúdo que não é um arquivo de mídia).
400invalid_request_errorUma parte não é uma URL de dados nem um link https, está vazia ou é de um tipo que os modelos não leem (Word, texto simples).
413invalid_request_errorUm arquivo com mais de 20 MB, mais de 30 MB de mídia ou um corpo de requisição com mais de 25 MB.

Os dois primeiros são o code do erro; os demais são o type, com uma mensagem que informa o que mudar. Todos são retornados antes de qualquer modelo ser chamado, então não têm custo. Veja os demais em Erros.

Como a mídia é cobrada

Os modelos convertem mídia em tokens de entrada, cobrados pelo preço de entrada do modelo. Cada laboratório conta de um jeito; estes são valores típicos que medimos:

ClaudeGPTGemini
Uma imagem de 1024 × 1024cerca de 1,400 tokenscerca de 1,250 a 1,650cerca de 1,100
Uma foto grande (12 MP)até cerca de 4,800varia conforme os pixelscerca de 1,100 a 1,200
Uma página de PDFcerca de 1,600 a 2,500o texto da páginacerca de 560
Um segundo de áudionão lênão lêcerca de 25
Um segundo de vídeonão lênão lêcerca de 100 a 300

Seu registro de requisições mostra exatamente o que foi contabilizado em cada uma. Reduzir as imagemns ao tamanho que você precisa é a forma mais fácil de economizar: a maioria dos modelos lê uma imagem de 1024 px tão bem quanto uma de 4000 px.

Você envia a mesma imagemm ou documento em várias requisições? Coloque no início da conversa e mantenha esse prefixo igual: modelos com cache de prompt cobram a entrada repetida pelo preço de cache.

Tem dúvidas ou falta algo? Fale com nossa equipe de suporte e responderemos por e-mail, geralmente em até um minuto.