API de arquivos e PDFs
A API Files do GetVibe API, compatível com OpenAI, e a entrada de PDFs: base64, um link ou um file_id em chat/completions, responses e messages; quais modelos veem as imagens dentro de um PDF, limites e erros.
Files API compatível com OpenAI para enviar, ler e excluir arquivos. Toda operação requer uma chave de API; um arquivo só pode ser acessado pela mesma conta de cliente que o enviou.
Fazer upload de um arquivo
Envie multipart/form-data com os campos obrigatórios file e purpose. Finalidades permitidas: assistants, batch, fine-tune, vision e user_data. O tamanho máximo do arquivo é 50 MiB (52 428 800 bytes); excedê-lo retorna 413.
curl -X POST https://getvibeapi.com/v1/files \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-F "purpose=user_data" \
-F "file=@./report.pdf"Obter metadados, conteúdo ou excluir
O upload retorna um objeto file com um id opaco, nome, tamanho, finalidade e horário de criação. GET sem /content retorna esses metadados; GET /content baixa os bytes brutos. Após um DELETE bem-sucedido, ambos os GETs retornam 404. O arquivo existente de outra conta retorna 403, e um identificador desconhecido retorna 404.
Fluxo de trabalho seguro
- Faça upload do arquivo e mantenha apenas o
file_idretornado. - Verifique os metadados com a mesma chave; ao trabalhar com Responses, passe este ID em
input_file.file_id. - Não envie segredos e exclua o arquivo depois de terminar. Um arquivo excluído não pode ser restaurado.
PDF em solicitações a modelos
Todos os modelos de texto aceitam PDFs nos três formatos de API. Em resumo: envie o arquivo de qualquer uma das três maneiras abaixo — por padrão, extraímos o texto gratuitamente e o enviamos ao modelo. O modelo lê o texto e as tabelas, mas não as imagens dentro do PDF nem os documentos digitalizados. Quando imagens, layout ou documentos digitalizados forem importantes, escolha um modelo da tabela abaixo e desative a extração de texto. Tudo nesta página foi verificado com solicitações reais em November 2, 2026, usando um PDF de três páginas com texto, uma tabela e uma imagem.
Três maneiras de enviar um PDF
| Método | Como | Quando usar |
|---|---|---|
| base64 na solicitação | Chat: {"type":"file","file":{"filename":"report.pdf","file_data":"data:application/pdf;base64,…"}}; Responses: {"type":"input_file","filename":"report.pdf","file_data":"data:…"}; Messages: {"type":"document","source":{"type":"base64","media_type":"application/pdf","data":"…"}} | Um documento para uso pontual. Funciona nos três endpoints. Arquivos de até 20 MiB. |
| Link público | Chat: "file":{"file_url":"https://…"}; Responses: {"type":"input_file","file_url":"https://…"}; Messages: "source":{"type":"url","url":"https://…"} | O arquivo já está online. Nós mesmos fazemos o download: somente HTTPS, sem login ou senha, o servidor deve responder com application/pdf, até 20 MiB, em até 10 segundos e com no máximo 3 redirecionamentos. |
file_id após o envio | Envie com POST /v1/files e purpose=user_data, depois: Chat "file":{"file_id":"file-pv-…"}, Responses {"type":"input_file","file_id":"file-pv-…"}, Messages "source":{"type":"file","file_id":"file-pv-…"} | Um documento em várias solicitações: não é necessário reenviar megabytes todas as vezes, e um prefixo de solicitação idêntico é armazenado em cache. O arquivo é mantido por 7 dias e fica visível somente para sua conta. |
Exemplos prontos para executar
A chave é lida da variável de ambiente GETVIBE_API_KEY. Os exemplos em Python usam os SDKs oficiais openai e anthropic sem alterações — apenas o endereço é diferente.
/v1/chat/completions
# PDF inline (base64); jq builds the body so a large file does not hit the command-line length limit
# macOS: replace base64 -w0 report.pdf with base64 -i report.pdf
jq -n --rawfile b64 <(base64 -w0 report.pdf) '{model: "deepseek-v4.1-flash", messages: [{role: "user", content: [
{type: "text", text: "Summarise the document"},
{type: "file", file: {filename: "report.pdf", file_data: ("data:application/pdf;base64," + $b64)}}]}]}' |
curl https://getvibeapi.com/v1/chat/completions \
-H "Authorization: Bearer $GETVIBE_API_KEY" -H "Content-Type: application/json" -d @-/v1/responses
# FILE_ID comes from the upload, see the "curl · file_id" tab above
curl https://getvibeapi.com/v1/responses \
-H "Authorization: Bearer $GETVIBE_API_KEY" -H "Content-Type: application/json" \
-d '{"model":"gpt-6.1-sol","input":[{"role":"user","content":[
{"type":"input_text","text":"What were the sales in Kazan in August?"},
{"type":"input_file","file_id":"'"$FILE_ID"'"}]}]}'
# base64 instead of file_id:
# {"type":"input_file","filename":"report.pdf","file_data":"data:application/pdf;base64,…"}/v1/messages
curl https://getvibeapi.com/v1/messages \
-H "x-api-key: $GETVIBE_API_KEY" -H "anthropic-version: 2023-06-01" -H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-5.5","max_tokens":1024,"messages":[{"role":"user","content":[
{"type":"document","source":{"type":"file","file_id":"'"$FILE_ID"'"}},
{"type":"text","text":"Summarise the document"}]}]}'
# other sources:
# "source":{"type":"base64","media_type":"application/pdf","data":"<base64>"}
# "source":{"type":"url","url":"https://example.com/report.pdf"}O que o modelo vê: texto ou o próprio arquivo
Por padrão, o texto extraído. Extraímos a camada de texto do PDF e a enviamos ao modelo em vez do arquivo. Isso é grátis e funciona com qualquer modelo, até mesmo um sem suporte a PDF. O modelo vê palavras e números, incluindo tabelas (sem bordas, mas com os valores corretos). O que ele não vê: imagens, gráficos, carimbos, assinaturas, cores e layout. Até 60,000 caracteres de texto por solicitação são enviados (cerca de 28 páginas densas); o restante é cortado, e o modelo é informado de que o documento foi truncado. O cabeçalho de resposta x-pv-document-shim informa o que aconteceu: applied:text_extracted significa que o modelo recebeu o texto; not-needed:lane_reads_pdf significa que recebeu o próprio arquivo.
O próprio arquivo. Para que o modelo veja as páginas inteiras, incluindo imagens e layout, adicione "plugins":[{"id":"documents","enabled":false}] ao corpo da solicitação (o cabeçalho então será not-needed:disabled_by_client). Faça isso somente com modelos marcados como “yes” na tabela: os outros respondem 400 ou dizem que não veem nenhum arquivo, e os tokens de entrada do arquivo ainda são cobrados.
# curl: add the field to the request body
"plugins": [{"id": "documents", "enabled": false}]
# Python (openai SDK)
r = client.chat.completions.create(
model="gpt-6.1-sol",
messages=[...],
extra_body={"plugins": [{"id": "documents", "enabled": False}]},
)| Modelo | Por padrão | Vê o próprio arquivo (extração desativada) |
|---|---|---|
gpt-6.1-sol | o próprio arquivo | sim — em /chat/completions e /responses |
gpt-6-luna | text | sim — em /chat/completions e /responses |
gpt-5.6-sol | text | não confirmado — mantenha o padrão |
claude-sonnet-5.5, claude-opus-5.5 | text | não — o modelo não consegue ver o arquivo, então, mesmo com o plugin desativado, extraímos o texto (cabeçalho x-getvibe-warnings: plugin_overridden:documents); para o arquivo em si, use gpt-6.1-sol |
claude-haiku-5.5 | text | não — o modelo não vê o arquivo |
gemini-4-argon, gemini-3.8-flash | text | não — o modelo não vê o arquivo ou 400 |
qwen3.8-flash | text | sim — em /chat/completions; 400 em /responses |
deepseek-v4.1-flash, glm-5.3, kimi-k3 | text | não — 400 |
Como testamos: pedimos ao modelo uma palavra da página 1, um número de uma célula da tabela e a descrição de uma imagem (formas, cores e um número desenhado como imagem). “Text” significa que ele identificou corretamente a palavra e o número e disse que não conseguia ver a imagem. “Yes” significa que também descreveu a imagem corretamente. Envie PDFs aos modelos GPT, Gemini e Qwen por meio de /v1/chat/completions ou /v1/responses: em /v1/messages eles não veem o próprio arquivo.
not-needed:no_text_layer_unmeasured_lane). A resposta depende do modelo: gpt-6.1-sol e qwen3.8-flash leem nosso documento digitalizado; os modelos DeepSeek respondem 400. Se o seu modelo não consegue ler documentos digitalizados, execute o OCR do seu lado e envie o texto ou envie as páginas como imagens PNG/JPEG por meio de image_url para um modelo que aceite imagens.Limites, tokens e tempo
| O quê | Limite |
|---|---|
| Um PDF em uma solicitação ao modelo (base64, link ou file_id) | até 20 MiB por arquivo; o arquivo deve começar com %PDF- |
Enviar para POST /v1/files | até 50 MiB (52,428,800 bytes), mas apenas um PDF de até 20 MiB pode ser incluído em uma solicitação ao modelo |
file_id lifetime | 7 dias (o campo expires_at); depois, o arquivo é excluído |
| Páginas | sem limite separado; com extração de texto, até 60,000 caracteres por solicitação; com o próprio arquivo, até o limite da janela de contexto do modelo |
| Baixar por link | até 10 segundos e até 3 redirecionamentos |
Como os tokens são contabilizados. Um PDF é cobrado como tokens de entrada comuns do modelo escolhido, pelo preço dele; não há cobrança separada pelo arquivo nem pela extração de texto. Veja quanto isso representa (medido, incluindo uma pergunta curta):
- Texto extraído: cerca de 700 tokens por página densa de texto (10 páginas — 7,300 tokens; 40 páginas cortadas em 60,000 caracteres — 20,300 tokens). Uma página com uma tabela pequena — 100–200 tokens.
- O próprio arquivo em modelos GPT: cerca de 600–700 tokens por página (10 páginas — 5,900; 40 — 23,300); em
gemini-4-argon, cerca de 1,200 por página; em Claude, cerca de 1,600 por página. Uma página digitalizada emgpt-6.1-sol— cerca de 5,800 tokens. - A repetição do mesmo documento aproveita o cache quando o início da solicitação não muda: em uma segunda solicitação com o mesmo
file_id, 7,168 de 7,309 tokens foram lidos do cache.
Tempo. A extração de texto leva uma fração de segundo; uma resposta sobre um documento de 40 páginas chegou em 4–12 segundos. Para documentos grandes e respostas longas, use stream: true e defina o tempo limite do cliente como pelo menos 300 segundos.
Erros e como corrigi-los
| Resposta | Causa | O que fazer |
|---|---|---|
400 invalid_pdf | The PDF must start with the %PDF- signature. | O arquivo não é um PDF ou o base64 está corrompido. Verifique se você está codificando o próprio arquivo, e não o caminho dele, e se o tipo é application/pdf. |
400 invalid_pdf | The PDF size must not exceed 20 MiB. | Divida o documento ou comprima as imagens contidas nele. |
413 invalid_request_error | Em POST /v1/files: o arquivo é maior que 52,428,800 bytes | O arquivo tem mais de 50 MiB: divida-o. |
400 invalid_request_error | O file_id está indisponível | O arquivo foi excluído, expirou (7 dias), foi enviado por outra conta ou o ID é de outro serviço. Envie o arquivo novamente com a mesma chave. |
400 invalid_pdf | The PDF URL must be a public HTTPS URL without credentials. | O link usa http://, contém login e senha, usa uma porta não padrão ou aponta para um domínio inexistente. Forneça um link HTTPS público ou envie o conteúdo em base64. |
400 invalid_pdf | Could not safely fetch the PDF from the URL. | O link retorna 404, uma página de login, HTML em vez de um PDF, ou o servidor não respondeu em até 10 segundos. Abra o link em uma janela de navegação privada; se o arquivo não for baixado imediatamente, envie o conteúdo em base64. |
400 unsupported_input | O modelo não consegue ler PDFs e o arquivo não contém texto (é uma digitalização). | Use um modelo que leia digitalizações (veja acima) ou execute OCR do seu lado. |
400 invalid_request_error | Invalid request… com a extração de texto desativada ou com um documento digitalizado. | O modelo não aceita arquivos PDF. Remova plugins documents enabled:false para que o modelo receba o texto ou escolha um modelo marcado como "yes" na tabela. |
| 200, mas “não vejo nenhum arquivo” | A extração está desativada, e o modelo ou canal não lê o arquivo. | Volte à extração de texto padrão ou escolha um modelo marcado como “yes” na tabela. |
Práticas recomendadas
- Precisa usar o documento em várias solicitações? Envie-o uma vez e passe o
file_id: a solicitação fica menor, e o prefixo repetido é armazenado em cache e custa menos. - Coloque o PDF e as instruções permanentes no início da mensagem e a pergunta variável no final: assim, o cache é aproveitado com mais frequência.
- Divida por capítulo documentos com mais de ~28 páginas densas: com a extração de texto, qualquer conteúdo além de 60,000 caracteres nunca chega ao modelo.
- Para contratos, relatórios e exportações com uma camada de texto, a extração de texto é suficiente — é a opção mais barata em qualquer modelo, incluindo
deepseek-v4.1-flash. - Precisa de gráficos, carimbos ou documentos digitalizados? Desative a extração e use um modelo marcado como “yes” na tabela, por exemplo
gpt-6.1-sol. - Textos não latinos (russo, chinês e outros) em PDFs são lidos sem nenhuma configuração. Remova a senha de um PDF antes de enviá-lo.
- Exclua os arquivos enviados com
DELETE /v1/files/{file_id}quando não precisar mais deles.
file_id retornado por um identificador de terceiros.