Tema
Idioma

Files API y PDF

Files API de GetVibe API compatible con OpenAI y entrada de PDF: base64, un enlace o un file_id en chat/completions, responses y messages; qué modelos ven las imágenes dentro de un PDF, límites y errores.

Files API compatible con OpenAI para cargar, leer y eliminar archivos. Cada operación requiere una clave de API; solo la misma cuenta cliente que cargó un archivo puede acceder a él.

Subir un archivo

POSThttps://getvibeapi.com/v1/files

Envía multipart/form-data con los campos obligatorios file y purpose. Propósitos permitidos: assistants, batch, fine-tune, vision y user_data. El tamaño máximo del archivo es de 50 MiB (52 428 800 bytes); superarlo devuelve 413.

curl -X POST https://getvibeapi.com/v1/files \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -F "purpose=user_data" \
  -F "file=@./report.pdf"

Obtener metadatos, contenido o eliminar

GEThttps://getvibeapi.com/v1/files/{file_id}
GEThttps://getvibeapi.com/v1/files/{file_id}/content
DELETEhttps://getvibeapi.com/v1/files/{file_id}

La carga devuelve un objeto file con un id opaco, name, size, purpose y hora de creación. GET sin /content devuelve estos metadatos; GET /content descarga los bytes sin procesar. Después de un DELETE correcto, ambas solicitudes GET devuelven 404. Un archivo existente de otra cuenta devuelve 403, y un identificador desconocido devuelve 404.

Flujo de trabajo seguro

  1. Sube el archivo y conserva solo el file_id devuelto.
  2. Verifica los metadatos con la misma clave; cuando trabajes con Responses, pasa este id. en input_file.file_id.
  3. No subas secretos y elimina el archivo después de terminar. Un archivo eliminado no se puede restaurar.

PDF en solicitudes a modelos

Todos los modelos de texto aceptan PDF en los tres formatos de API. En resumen: envía el archivo de cualquiera de las tres formas que se indican a continuación; de forma predeterminada, extraemos el texto gratis y se lo pasamos al modelo. El modelo lee el texto y las tablas, pero no las imágenes dentro del PDF ni los escaneos. Cuando importen las imágenes, el diseño o un escaneo, elige un modelo de la tabla de abajo y desactiva la extracción de texto. Todo lo que aparece en esta página se verificó con solicitudes reales el 2 de noviembre de 2026, usando un PDF de tres páginas con texto, una tabla y una imagen.

Tres formas de enviar un PDF

MétodoCómoCuándo usarlo
base64 en la solicitudChat: {"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":"…"}}Un documento para usar una sola vez. Funciona en los tres endpoints. Archivos de hasta 20 MiB.
Enlace públicoChat: "file":{"file_url":"https://…"}; Responses: {"type":"input_file","file_url":"https://…"}; Messages: "source":{"type":"url","url":"https://…"}El archivo ya está en línea. Lo descargamos nosotros: solo HTTPS, sin usuario ni contraseña, el servidor debe responder con application/pdf, hasta 20 MiB, en un plazo de 10 segundos y con un máximo de 3 redirecciones.
file_id después de subirloSube el archivo con POST /v1/files y purpose=user_data y luego usa: Chat "file":{"file_id":"file-pv-…"}, Responses {"type":"input_file","file_id":"file-pv-…"}, Messages "source":{"type":"file","file_id":"file-pv-…"}Un documento para varias solicitudes: no hace falta volver a enviar megabytes cada vez y el prefijo idéntico de la solicitud se almacena en caché. El archivo se conserva durante 7 días y solo está visible para tu cuenta.

Ejemplos listos para ejecutar

La clave se lee de la variable de entorno GETVIBE_API_KEY. Los ejemplos de Python usan los SDK oficiales openai y anthropic sin modificaciones; solo cambia la dirección.

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

Qué ve el modelo: el texto o el archivo en sí

De forma predeterminada, se extrae el texto. Tomamos la capa de texto del PDF y se la pasamos al modelo en lugar del archivo. Es gratis y funciona con cualquier modelo, incluso con uno que no admite PDF. El modelo ve palabras y números, incluidas las tablas (sin bordes, pero con los valores correctos). Lo que no ve: imágenes, gráficos, sellos, firmas, colores y diseño. Se pasan hasta 60,000 caracteres de texto por solicitud (unas 28 páginas densas); el resto se recorta y se le indica al modelo que el documento se truncó. El encabezado de respuesta x-pv-document-shim indica qué ocurrió: applied:text_extracted significa que el modelo recibió el texto; not-needed:lane_reads_pdf, que recibió el archivo.

El archivo en sí. Para que el modelo vea páginas completas, con imágenes y diseño, agrega "plugins":[{"id":"documents","enabled":false}] al cuerpo de la solicitud (el encabezado entonces muestra not-needed:disabled_by_client). Hazlo solo con los modelos marcados como «sí» en la tabla: los demás responden con 400 o indican que no ven ningún archivo, y los tokens de entrada del archivo se siguen facturando.

# 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}]},
)
ModeloDe forma predeterminadaVe el archivo en sí (extracción desactivada)
gpt-6.1-solel archivo en sísí — en /chat/completions y /responses
gpt-6-lunatextsí — en /chat/completions y /responses
gpt-5.6-soltextno confirmado — mantén el valor predeterminado
claude-sonnet-5.5, claude-opus-5.5textno — el modelo no puede ver el archivo, así que extraemos el texto incluso con el plugin desactivado (encabezado x-getvibe-warnings: plugin_overridden:documents); para el archivo en sí, usa gpt-6.1-sol
claude-haiku-5.5textno — el modelo no ve el archivo
gemini-4-argon, gemini-3.8-flashtextno — el modelo no ve el archivo, o 400
qwen3.8-flashtextsí — en /chat/completions; 400 en /responses
deepseek-v4.1-flash, glm-5.3, kimi-k3textno — 400

Cómo hicimos las pruebas: se le pidió al modelo una palabra de la página 1, un número de una celda de la tabla y una descripción de una imagen (formas, colores y un número dibujado como imagen). «Texto» significa que identificó correctamente la palabra y el número, y dijo que no podía ver la imagen. «Sí» significa que también describió correctamente la imagen. Envía PDF a los modelos GPT, Gemini y Qwen mediante /v1/chat/completions o /v1/responses: con /v1/messages no pueden ver el archivo en sí.

Escaneos. Un escaneo no tiene capa de texto, así que no hay nada que extraer y el modelo recibe el archivo original (encabezado not-needed:no_text_layer_unmeasured_lane). En ese caso, depende del modelo: gpt-6.1-sol y qwen3.8-flash leen nuestro escaneo; los modelos DeepSeek responden con 400. Si tu modelo no puede leer un escaneo, ejecuta OCR por tu cuenta y envía el texto, o envía las páginas como imágenes PNG/JPEG mediante image_url a un modelo que acepte imágenes.

Límites, tokens y tiempo

QuéLímite
Un PDF en una solicitud al modelo (base64, enlace o file_id)hasta 20 MiB por archivo; el archivo debe comenzar con %PDF-
Subir a POST /v1/fileshasta 50 MiB (52,428,800 bytes), pero solo se puede incluir en una solicitud al modelo un PDF de hasta 20 MiB
file_id lifetime7 días (el campo expires_at); después, el archivo se elimina
Páginassin límite aparte; con extracción de texto, hasta 60,000 caracteres por solicitud; con el archivo en sí, hasta el tamaño de la ventana de contexto del modelo
Descargar mediante enlacehasta 10 segundos y hasta 3 redirecciones

Cómo se cuentan los tokens. Un PDF se factura como tokens de entrada normales del modelo elegido, según su precio; no hay un cargo aparte por el archivo ni por extraer el texto. Esto es lo que cuesta (medido, incluida una pregunta breve):

  • Texto extraído: aproximadamente 700 tokens por página de texto denso (10 páginas: 7,300 tokens; 40 páginas recortadas a 60,000 caracteres: 20,300 tokens). Una página con una tabla breve: 100–200 tokens.
  • El archivo en sí, en modelos GPT: unos 600–700 tokens por página (10 páginas — 5,900; 40 — 23,300); en gemini-4-argon, unos 1,200 por página; en Claude, unos 1,600 por página. Una página escaneada en gpt-6.1-sol: unos 5,800 tokens.
  • Si repites el mismo documento, se aprovecha la caché cuando el inicio de la solicitud no cambia: en una segunda solicitud con el mismo file_id, se leyeron 7,168 de 7,309 tokens desde la caché.

Tiempo. La extracción de texto tarda una fracción de segundo; una respuesta sobre un documento de 40 páginas llegó en 4–12 segundos. Para documentos grandes y respuestas largas, usa stream: true y configura el tiempo de espera del cliente en al menos 300 segundos.

Errores y cómo solucionarlos

RespuestaCausaQué hacer
400 invalid_pdfThe PDF must start with the %PDF- signature.No es un PDF o el base64 está dañado. Asegúrate de codificar el archivo en sí, no su ruta, y de que el tipo sea application/pdf.
400 invalid_pdfThe PDF size must not exceed 20 MiB.Divide el documento o comprime las imágenes que contiene.
413 invalid_request_errorEn POST /v1/files: el archivo supera los 52,428,800 bytesEl archivo supera los 50 MiB: divídelo.
400 invalid_request_errorEl file_id no está disponibleEl archivo se eliminó, venció (7 días), lo subió otra cuenta o el id pertenece a otro servicio. Vuelve a subir el archivo con la misma clave.
400 invalid_pdfThe PDF URL must be a public HTTPS URL without credentials.El enlace usa http://, incluye un usuario y una contraseña, usa un puerto no estándar o apunta a un dominio inexistente. Proporciona un enlace HTTPS público o envía base64.
400 invalid_pdfCould not safely fetch the PDF from the URL.El enlace devuelve 404, una página de inicio de sesión, HTML en vez de un PDF, o el servidor no respondió en 10 segundos. Abre el enlace en una ventana de navegación privada; si el archivo no se descarga de inmediato, envía base64.
400 unsupported_inputEl modelo no puede leer PDFs y el archivo no contiene texto (es un escaneo).Usa un modelo que pueda leer escaneos (consulta arriba) o ejecuta OCR por tu cuenta.
400 invalid_request_errorInvalid request… con la extracción de texto desactivada o con un escaneo.El modelo no acepta archivos PDF. Elimina plugins documents enabled:false para que el modelo reciba el texto, o elige un modelo marcado con "yes" en la tabla.
200, pero «No veo ningún archivo»La extracción está desactivada y el modelo o canal no puede leer el archivo.Vuelve a la extracción de texto predeterminada o elige un modelo marcado como «sí» en la tabla.

Prácticas recomendadas

  • ¿Necesitas usar el documento en varias solicitudes? Súbelo una vez y pasa el file_id: la solicitud es más pequeña y el prefijo repetido se almacena en caché, lo que reduce el costo.
  • Coloca el PDF y las instrucciones permanentes al principio del mensaje, y la pregunta que cambia al final: así se aprovecha la caché con más frecuencia.
  • Divide por capítulos los documentos de más de ~28 páginas densas: con la extracción de texto, todo lo que supere los 60,000 caracteres nunca llega al modelo.
  • Para contratos, informes y exportaciones con una capa de texto, basta con extraer el texto: es la opción más económica con cualquier modelo, incluido deepseek-v4.1-flash.
  • ¿Necesitas gráficos, sellos o escaneos? Desactiva la extracción y usa un modelo marcado como «sí» en la tabla, por ejemplo gpt-6.1-sol.
  • El texto no latino (ruso, chino y otros idiomas) de un PDF se lee sin cambiar ninguna configuración. Quita la contraseña del PDF antes de enviarlo.
  • Elimina los archivos subidos con DELETE /v1/files/{file_id} cuando ya no los necesites.
Files API no garantiza que cualquier ruta de modelo elegida acepte archivos. Si una ruta no admite un archivo, corrige la estructura de la solicitud o elige un modelo compatible; no reemplaces el file_id devuelto con un identificador de terceros.
GetVibe API Files API y PDF: sube archivos y envía PDF a los modelos | GetVibe API