Documents and media
Send PDFs, Office files, images, audio and video in a conversation; what each becomes, and what it costs.
Documents
Any chat model can read a document: the API turns it into text before the model sees it, so the model needs no file support of its own. PDF, Word, Excel, PowerPoint, RTF, HTML, CSV, Markdown, JSON, XML and plain text are read.
| Route | Part | Holds |
|---|---|---|
/v1/chat/completions |
file |
A filename, and the file as file_data (a data URI, bare base64 or a URL) or file_id |
/v1/responses |
input_file |
A filename, and the file as file_data, file_url or file_id |
/v1/messages |
document |
A source: base64, a URL, text or a file_id |
# A document travels as a data URI; the API turns it into text the model reads
doc=$(printf '# Leave policy\n\nNew hires get 20 vacation days a year.\n' | base64 | tr -d '\n')
curl https://api.vultrinference.com/v1/chat/completions \
-H "Authorization: Bearer $VULTR_INFERENCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash-1017",
"messages": [{"role": "user", "content": [
{"type": "text", "text": "How many vacation days do new hires get?"},
{"type": "file", "file": {"filename": "policy.md", "file_data": "data:text/markdown;base64,'"$doc"'"}}
]}]
}'import base64
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.vultrinference.com/v1", api_key=os.environ["VULTR_INFERENCE_API_KEY"])
# A PDF, Word, Excel or PowerPoint file works the same way: read its bytes and name its type
policy = base64.b64encode(b"# Leave policy\n\nNew hires get 20 vacation days a year.\n").decode()
reply = client.chat.completions.create(
model="deepseek-v4.1-flash-1017",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "How many vacation days do new hires get?"},
{"type": "file", "file": {"filename": "policy.md", "file_data": f"data:text/markdown;base64,{policy}"}},
],
}],
)
print(reply.choices[0].message.content)The type comes from the data URI, then the filename's extension, then the file's first bytes. If none of them tells it, the answer is a 400 that asks you to name the file.
- The text counts toward the context window, and is billed as prompt tokens in every request that sends it.
- A file may be up to 100 MB, and a PDF up to 300 pages.
- A URL is downloaded by the API. It must be
httporhttpson a public address. Up to five redirects are followed, and each must lead to a public address too. - A long PDF takes about half a second a page to read. If your request gives up partway, the conversion still finishes, and the same document sent within the hour is not read again.
- When the converter is busy the answer is 503; retry after
Retry-After.
To use one document in many requests, upload it once to POST /v1/files and send its file_id: it is read once, up front. Chat over your files shows the whole round.
Images, audio and video
On /v1/chat/completions, a model that reads a kind of media gets it as it is. A model that does not gets a description of it, written by a model that does, so it can still answer about it.
| Media | Part | Formats | A model that reads it gets |
|---|---|---|---|
| Images | image_url |
PNG, JPEG, WebP or GIF | The picture as you sent it, which the model scales to its own limit |
| Audio | input_audio |
WAV or MP3 | The clip as you sent it |
| Video | video_url |
MP4 or WebM | The clip as you sent it, from which the model samples frames |
A model's catalog entry lists audio or video among its inputs when it hears or watches them itself. /v1/responses and /v1/messages give media to the model without descriptions, so use a model that reads it.
A media URL is downloaded by the API, not by the model, and the model is given that copy, unchanged. On every route the URL must be http or https on a public address, and so must every redirect from it, up to five; an image can be up to 20 MB, audio and video up to 50 MB. Any other URL is a 400. On /v1/responses, /v1/messages and /v1/chat/completions/RAG a base64 data URI is sent as it is.
The API reads the format from the file itself, not from its name or data URI, and any other format is a 400 that lists the ones above; on /v1/responses, /v1/messages and /v1/chat/completions/RAG it checks downloaded URLs only. A larger picture costs more prompt tokens, up to the model's own limit.
Errors
| Status | When |
|---|---|
| 400 | The file is unreadable, encrypted or empty, a PDF is over 300 pages, a URL could not be downloaded, or the type could not be told. The message says which. |
| 400 | A file_id that does not exist, is still processing, failed to convert, or has expired. |
| 400 | An image, audio clip or video in a format other than those above. |
| 503 | The converter is busy. Retry after Retry-After. |
Endpoints