Files API et PDF
L’API Files de GetVibe API, compatible avec OpenAI, et l’entrée PDF : base64, lien ou file_id sur chat/completions, responses et messages, modèles capables de voir les images dans un PDF, limites et erreurs.
API Files compatible avec OpenAI pour téléverser, lire et supprimer des fichiers. Chaque opération nécessite une clé API ; un fichier n’est accessible qu’au même compte client que celui qui l’a téléversé.
Téléverser un fichier
Envoyez multipart/form-data avec les champs file et purpose requis. Usages autorisés : assistants, batch, fine-tune, vision et user_data. La taille maximale du fichier est de 50 MiB (52 428 800 octets) ; son dépassement renvoie 413.
curl -X POST https://getvibeapi.com/v1/files \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-F "purpose=user_data" \
-F "file=@./report.pdf"Obtenir les métadonnées ou le contenu, ou supprimer
Le téléversement renvoie un objet file avec un id opaque, le nom, la taille, le purpose et l’heure de création. GET sans /content renvoie ces métadonnées ; GET /content télécharge les octets bruts. Après un DELETE réussi, les deux requêtes GET renvoient 404. Le fichier existant d’un autre compte renvoie 403, et un identifiant inconnu renvoie 404.
Flux de travail sécurisé
- Téléversez le fichier et conservez uniquement le
file_idrenvoyé. - Vérifiez les métadonnées avec la même clé ; lorsque vous utilisez Responses, transmettez cet identifiant dans
input_file.file_id. - Ne téléversez pas de secrets et supprimez le fichier une fois terminé. Un fichier supprimé ne peut pas être restauré.
PDF dans les requêtes aux modèles
Tous les modèles de texte acceptent les PDF dans les trois formats d’API. En bref : envoyez le fichier de l’une des trois manières ci-dessous ; par défaut, nous en extrayons gratuitement le texte et le transmettons au modèle. Le modèle lit le texte et les tableaux, mais pas les images contenues dans le PDF ni les scans. Lorsque les images, la mise en page ou un scan sont importants, choisissez un modèle dans le tableau ci-dessous et désactivez l’extraction de texte. Tout ce qui figure sur cette page a été vérifié au moyen de requêtes en direct le November 2, 2026, à l’aide d’un PDF de trois pages contenant du texte, un tableau et une image.
Trois façons d’envoyer un PDF
| Méthode | Comment | Quand l’utiliser |
|---|---|---|
| base64 dans la requête | 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":"…"}} | Un document ponctuel. Fonctionne avec les trois points de terminaison. Fichiers jusqu’à 20 MiB. |
| Lien public | Chat : "file":{"file_url":"https://…"} ; Responses : {"type":"input_file","file_url":"https://…"} ; Messages : "source":{"type":"url","url":"https://…"} | Le fichier est déjà en ligne. Nous le téléchargeons nous-mêmes : HTTPS uniquement, sans identifiant ni mot de passe, le serveur doit répondre avec application/pdf, avec une taille maximale de 20 MiB, dans un délai de 10 secondes et avec au maximum 3 redirections. |
file_id après le téléversement | Téléversez avec POST /v1/files et purpose=user_data, puis : Chat "file":{"file_id":"file-pv-…"}, Responses {"type":"input_file","file_id":"file-pv-…"}, Messages "source":{"type":"file","file_id":"file-pv-…"} | Un document utilisé dans plusieurs requêtes : inutile de renvoyer des mégaoctets à chaque fois, et un préfixe de requête identique est mis en cache. Le fichier est conservé pendant 7 jours et n’est visible que dans votre compte. |
Exemples prêts à l’emploi
La clé est lue depuis la variable d’environnement GETVIBE_API_KEY. Les exemples Python utilisent tels quels les SDK officiels openai et anthropic — seule l’adresse diffère.
/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"}Ce que voit le modèle : le texte ou le fichier lui-même
Par défaut, le texte extrait. Nous récupérons la couche de texte du PDF et la transmettons au modèle à la place du fichier. C’est gratuit et cela fonctionne avec tous les modèles, même ceux qui ne prennent pas en charge les PDF. Le modèle voit les mots et les nombres, y compris les tableaux (sans bordures, mais avec les bonnes valeurs). Ce qu’il ne voit pas : les images, les graphiques, les tampons, les signatures, les couleurs et la mise en page. Jusqu’à 60,000 caractères de texte par requête sont transmis (environ 28 pages denses) ; le reste est coupé et le modèle est averti que le document a été tronqué. L’en-tête de réponse x-pv-document-shim indique ce qui s’est passé : applied:text_extracted signifie que le modèle a reçu le texte, not-needed:lane_reads_pdf qu’il a reçu le fichier lui-même.
Le fichier lui-même. Pour que le modèle voie les pages entières, avec les images et la mise en page, ajoutez "plugins":[{"id":"documents","enabled":false}] au corps de la requête (l’en-tête indique alors not-needed:disabled_by_client). Faites-le uniquement avec les modèles marqués « yes » dans le tableau : les autres répondent 400 ou indiquent qu’ils ne voient aucun fichier, et les jetons d’entrée du fichier sont tout de même facturés.
# 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}]},
)| Modèle | Par défaut | Voit le fichier lui-même (extraction désactivée) |
|---|---|---|
gpt-6.1-sol | le fichier lui-même | oui — sur /chat/completions et /responses |
gpt-6-luna | text | oui — sur /chat/completions et /responses |
gpt-5.6-sol | text | non confirmé — conservez la valeur par défaut |
claude-sonnet-5.5, claude-opus-5.5 | text | non — le modèle ne peut pas voir le fichier ; nous en extrayons donc le texte même lorsque le plugin est désactivé (en-tête x-getvibe-warnings: plugin_overridden:documents) ; pour le fichier lui-même, utilisez gpt-6.1-sol |
claude-haiku-5.5 | text | non — le modèle ne voit pas le fichier |
gemini-4-argon, gemini-3.8-flash | text | non — le modèle ne voit pas le fichier, ou 400 |
qwen3.8-flash | text | oui — sur /chat/completions ; 400 sur /responses |
deepseek-v4.1-flash, glm-5.3, kimi-k3 | text | non — 400 |
Méthode de test : il a été demandé au modèle de trouver un mot à la page 1, un nombre dans une cellule du tableau et de décrire une image (formes, couleurs et nombre représenté sous forme d’image). « Text » signifie qu’il a correctement indiqué le mot et le nombre et précisé qu’il ne pouvait pas voir l’image. « Yes » signifie qu’il a également correctement décrit l’image. Envoyez des PDF aux modèles GPT, Gemini et Qwen via /v1/chat/completions ou /v1/responses : sur /v1/messages, ils ne voient pas le fichier lui-même.
not-needed:no_text_layer_unmeasured_lane). Le résultat dépend alors du modèle : gpt-6.1-sol et qwen3.8-flash lisent notre scan, tandis que les modèles DeepSeek répondent 400. Si votre modèle ne peut pas lire un scan, effectuez une OCR de votre côté et envoyez le texte, ou envoyez les pages sous forme d’images PNG/JPEG via image_url à un modèle qui accepte les images.Limites, jetons et durée
| Quoi | Limite |
|---|---|
| Un PDF dans une requête de modèle (base64, lien ou file_id) | jusqu’à 20 MiB par fichier ; le fichier doit commencer par %PDF- |
Téléverser vers POST /v1/files | jusqu’à 50 MiB (52,428,800 bytes), mais seul un PDF de 20 MiB maximum peut être inclus dans une requête au modèle |
file_id lifetime | 7 jours (le champ expires_at), puis le fichier est supprimé |
| Pages | pas de limite distincte ; avec l’extraction de texte, jusqu’à 60,000 caractères par requête ; avec le fichier lui-même, jusqu’à la fenêtre de contexte du modèle |
| Télécharger via un lien | jusqu’à 10 secondes et jusqu’à 3 redirections |
Comment les jetons sont comptabilisés. Un PDF est facturé comme des jetons d’entrée ordinaires du modèle choisi, au tarif de celui-ci ; il n’y a pas de frais distincts pour le fichier ou l’extraction de texte. Voici le résultat (mesuré avec une courte question incluse) :
- Texte extrait : environ 700 jetons par page dense de texte (10 pages — 7,300 jetons ; 40 pages tronquées à 60,000 caractères — 20,300 jetons). Une page avec un petit tableau — 100–200 jetons.
- Le fichier lui-même sur les modèles GPT : environ 600–700 tokens par page (10 pages — 5,900 ; 40 — 23,300) ; sur
gemini-4-argon, environ 1,200 par page ; sur Claude, environ 1,600 par page. Une page numérisée surgpt-6.1-sol— environ 5,800 tokens. - La répétition du même document utilise le cache lorsque le début de la requête ne change pas : lors d’une deuxième requête avec le même
file_id, 7,168 jetons sur 7,309 ont été lus depuis le cache.
Durée. L’extraction de texte prend une fraction de seconde ; une réponse sur un document de 40 pages est arrivée en 4–12 secondes. Pour les documents volumineux et les réponses longues, utilisez stream: true et définissez le délai d’expiration du client à au moins 300 secondes.
Erreurs et solutions
| Réponse | Cause | Que faire |
|---|---|---|
400 invalid_pdf | The PDF must start with the %PDF- signature. | Il ne s’agit pas d’un PDF ou le base64 est incorrect. Vérifiez que vous encodez le fichier lui-même, et non son chemin, et que le type est application/pdf. |
400 invalid_pdf | The PDF size must not exceed 20 MiB. | Divisez le document ou compressez les images qu’il contient. |
413 invalid_request_error | Sur POST /v1/files : le fichier dépasse 52,428,800 bytes | Le fichier dépasse 50 MiB : découpez-le. |
400 invalid_request_error | Le file_id est indisponible | Le fichier a été supprimé, a expiré (7 days), a été téléversé depuis un autre compte ou l’identifiant provient d’un autre service. Téléversez à nouveau le fichier avec la même clé. |
400 invalid_pdf | The PDF URL must be a public HTTPS URL without credentials. | Le lien commence par http://, contient un identifiant et un mot de passe, utilise un port non standard ou mène à un domaine inexistant. Fournissez un lien HTTPS public ou envoyez le fichier en base64. |
400 invalid_pdf | Could not safely fetch the PDF from the URL. | Le lien renvoie une erreur 404, une page de connexion, du HTML au lieu d’un PDF, ou le serveur n’a pas répondu en moins de 10 secondes. Ouvrez le lien dans une fenêtre de navigation privée ; si le fichier ne se télécharge pas immédiatement, envoyez-le en base64. |
400 unsupported_input | Le modèle ne peut pas lire les PDF et le fichier ne contient pas de texte (c’est une image numérisée). | Utilisez un modèle capable de lire les documents numérisés (voir ci-dessus) ou effectuez l’OCR de votre côté. |
400 invalid_request_error | Invalid request… avec l’extraction de texte désactivée, ou avec un scan. | Le modèle n’accepte pas les fichiers PDF. Supprimez plugins documents enabled:false afin que le modèle reçoive le texte, ou choisissez un modèle indiqué par « yes » dans le tableau. |
| 200, mais « Je ne vois aucun fichier » | L’extraction est désactivée et le modèle ou le canal ne lit pas le fichier. | Rétablissez l’extraction de texte par défaut ou choisissez un modèle marqué « yes » dans le tableau. |
Bonnes pratiques
- Vous devez utiliser le document dans plusieurs requêtes ? Téléversez-le une fois et transmettez le
file_id: la requête est plus petite et le préfixe répété est mis en cache, ce qui réduit le coût. - Placez le PDF et les instructions permanentes au début du message, et la question qui change à la fin : le cache sera ainsi utilisé plus souvent.
- Divisez les documents de plus d’environ 28 pages denses par chapitre : avec l’extraction de texte, tout ce qui dépasse 60,000 caractères ne parvient jamais au modèle.
- Pour les contrats, les rapports et les exports comportant une couche de texte, l’extraction de texte suffit : c’est l’option la moins coûteuse avec n’importe quel modèle, y compris
deepseek-v4.1-flash. - Vous avez besoin de graphiques, de tampons ou de scans ? Désactivez l’extraction et utilisez un modèle marqué « yes » dans le tableau, par exemple
gpt-6.1-sol. - Les textes non latins (russe, chinois et autres) contenus dans un PDF sont lus sans aucun réglage. Supprimez le mot de passe du PDF avant de l’envoyer.
- Supprimez les fichiers téléversés avec
DELETE /v1/files/{file_id}dès que vous n’en avez plus besoin.
file_id renvoyé par un identifiant tiers.