Chat

Images, PDF, audio et vidéo en entrée

Ajoutez des images, des PDF, de l’audio et de la vidéo à un message pour les modèles qui les prennent en charge. Envoyez le fichier lui-même (en base64) ou un lien : nous récupérons nous-mêmes les fichiers liés, donc tout lien https public vers un fichier de 20 MB maximum convient.

En bref

À envoyer/v1/chat/completions (every model)/v1/messages (Claude)Formats
Une imageÉlément image_urlBloc imagePNG, JPEG, WebP, GIF
Un PDFÉlément fileBloc documentPDF
Un enregistrementÉlément input_audioClaude ne traite pas l’audioWAV, MP3
Une vidéoÉlément video_urlClaude ne traite pas la vidéoMP4, MOV, WebM
Texte, code, CSV, Word, ExcelLe texte lui-même, dans le messageUn bloc text, ou un document en texte brutTexte

Chaque élément accepte un lien https public ou le fichier lui-même sous forme d’URL de données en base64, par exemple data:application/pdf;base64,JVBERi0.... Un même message peut contenir plusieurs fichiers, dans toute combinaison prise en charge par le modèle.

Ce que chaque modèle peut lire

Tous les modèles de chat lisent le texte. Ce tableau est à jour : il indique ce que chaque modèle peut lire aujourd’hui. Si vous fournissez à un modèle un contenu qu’il ne peut pas lire, il le refuse immédiatement avec unsupported_content : il ne répond donc jamais à propos d’un fichier qu’il n’a pas vu.

Images

Ajoutez un élément image_url avec un lien ou une URL de données. PNG, JPEG, WebP et GIF. Tous les modèles qui lisent les images acceptent plusieurs images dans un même message.

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)

Pour envoyer un fichier depuis le disque, encodez-le en base64 dans une URL de données :

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) est transmis tel quel aux modèles qui l’utilisent.

PDF

Ajoutez un élément file avec le PDF sous forme d’URL de données dans file_data, ainsi que son nom de fichier. Les modèles lisent le texte et, lorsqu’ils le peuvent, les pages sous forme d’images (graphiques, scans, tableaux). Un lien public fonctionne aussi dans 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)

Les PDF longs consomment des tokens d’entrée par page (voir la facturation ci-dessous) : envoyez donc uniquement les pages utiles. Pour poser des questions sur plusieurs documents à la fois, ajoutez un élément file pour chacun, avec des noms qui permettent de les distinguer.

Word, Excel, texte et code

Les modèles lisent les PDF, pas les fichiers Word, Excel ou PowerPoint. Collez le texte, le CSV, le JSON, le Markdown ou le code directement dans le message sous forme de texte : il est facturé comme des tokens d’entrée ordinaires, et c’est ce que le modèle lit le mieux. Si la mise en page compte (tableaux, graphiques, scans), exportez le fichier en PDF et envoyez-le. Une URL de données de tout autre type, comme text/plain, est refusée avec une erreur explicite.

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)

Audio

Pour les modèles qui traitent l’audio (voir le tableau) : un élément input_audio avec l’audio en base64 et son format, wav ou mp3. input_audio accepte l’audio lui-même ; pour un lien, utilisez un élément file avec le lien dans file_data. Les enregistrements réalisés dans un navigateur sont généralement au format WebM, qui est lu comme une vidéo : convertissez-les en MP3 ou WAV pour les modèles qui ne traitent que l’audio.

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)

Vidéo

Pour les modèles qui traitent la vidéo : un élément video_url avec un lien ou une URL de données (un élément file fonctionne aussi). MP4, MOV et WebM. Les modèles qui traitent aussi l’audio lisent également la bande-son : vous pouvez donc leur demander ce qui est dit.

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)

Une vidéo stockée sur disque s’envoie de la même façon, sous forme d’URL de données :

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}},
]

Un seul format en entrée, le bon format en sortie

Les labos acceptent les médias sous différentes formes (une vidéo peut être une partie video_url, image_url ou file, selon la documentation consultée). Envoyez-les sous n’importe laquelle de ces formes : nous transmettons à chaque modèle ses médias au format qu’il accepte.

Plusieurs fichiers dans un même message

Ajoutez une partie par fichier, dans l’ordre de lecture souhaité, et désignez les fichiers dans votre texte par leur position ou leur nom (“la deuxième image”, “contract.pdf”). Vous pouvez mélanger images, PDF, audio et vidéo, à condition que le modèle accepte chaque type de fichier. Vous pouvez intercaler des parties de texte entre les fichiers pour les identifier.

  • Les liens doivent être des URL https publiques. Nous suivons jusqu’à trois redirections et attendons jusqu’à 20 secondes.
  • Si le téléchargement via un lien échoue, la requête est immédiatement refusée avec invalid_url et le statut renvoyé par le lien, avant tout appel à un modèle.
  • Les liens signés (S3, Cloud Storage, nos propres liens d’images) fonctionnent tant qu’ils sont valides.

Format Anthropic

Sur /v1/messages, les modèles Claude acceptent les blocs d’Anthropic : image et document, avec une source base64 ou url. Certains modèles Claude ne lisent les PDF que via /v1/chat/completions ; si vous en envoyez un à /v1/messages, l’erreur vous indique où l’envoyer à la place.

Blocs de contenu
[
{ "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

LimiteValeur
Un fichier20 MB
Tous les médias d’une requête30 MB
Corps de la requête (le base64 ajoute environ un tiers)25 MB
Parties multimédias par requête100
Liens par requête20

Pour les fichiers plus volumineux, envoyez un lien : il ne compte pas dans la taille du corps de la requête. Les fichiers importés via l’API Files d’un labo (file_id) ne sont pas utilisables ; envoyez plutôt le fichier ou un lien.

Erreurs

StatutErreurQuand
400unsupported_contentLe modèle ne lit pas ce type de fichier. Choisissez-en un qui le prend en charge dans le tableau ci-dessus.
400invalid_urlLe téléchargement via un lien a échoué. Le message précise pourquoi (statut renvoyé, délai dépassé, fichier non multimédia).
400invalid_request_errorUne partie n’est ni une URL de données ni un lien https, est vide ou correspond à un type de fichier que les modèles ne lisent pas (Word, texte brut).
413invalid_request_errorUn fichier de plus de 20 MB, plus de 30 MB de médias ou un corps de requête de plus de 25 MB.

Les deux premières correspondent au code de l’erreur ; les autres à son type, avec un message indiquant quoi modifier. Toutes sont renvoyées avant tout appel à un modèle et ne coûtent donc rien. Consultez Erreurs pour les autres cas.

Facturation des médias

Les modèles convertissent les médias en tokens d’entrée, facturés au tarif d’entrée du modèle. Chaque labo a sa propre méthode de calcul ; voici les valeurs typiques que nous avons mesurées :

ClaudeGPTGemini
Une image de 1024 × 1024environ 1,400 tokensenviron 1,250 à 1,650environ 1,100
Une grande photo (12 MP)jusqu’à environ 4,800varie selon le nombre de pixelsenviron 1,100 à 1,200
Une page de PDFenviron 1,600 à 2,500le texte de la pageenviron 560
Une seconde d’audionon pris en chargenon pris en chargeenviron 25
Une seconde de vidéonon pris en chargenon pris en chargeenviron 100 à 300

Votre journal des requêtes indique exactement ce que chaque requête a comptabilisé. Réduire les images à la taille dont vous avez besoin est le moyen le plus simple d’économiser : la plupart des modèles lisent aussi bien une image de 1024 px qu’une de 4000 px.

Vous envoyez la même image ou le même document dans plusieurs requêtes ? Placez-le au début de la conversation et gardez ce préfixe identique : les modèles avec mise en cache des prompts facturent les entrées répétées au tarif du cache.

Une question ou un élément manquant ? Contactez notre équipe d’assistance et nous vous répondrons par e-mail, généralement en moins d’une minute.