Multimodal
PDFs and files
Attach PDF documents to chat requests with the file content part. PDFs go only to endpoints that read files natively.
Add a file content part to a user message, with the PDF as an HTTPS URL or a base64 data: URL. Requests with a PDF go only to endpoints that read files natively; PDFs aren't converted to text or images for other models. The examples use openai/gpt-6-luna; replace it with a model that has an endpoint whose input_modalities include file.
Send a PDF by URL
curl -X POST "https://api.numes.ai/api/v1/chat/completions" \ -H "Authorization: Bearer $NUMES_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-6-luna", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Summarize the key findings of this report in five bullet points." }, { "type": "file", "file": { "filename": "annual-report.pdf", "file_data": "https://example.com/documents/annual-report.pdf" } } ] } ] }'The URL must be publicly reachable over HTTPS and return a PDF, served as application/pdf, application/octet-stream or without a Content-Type.
Send a local PDF
Encode the file as a data:application/pdf;base64, URL:
import base64import osfrom pathlib import Pathfrom openai import OpenAIdef pdf_data_url(path: str) -> str: return "data:application/pdf;base64," + base64.b64encode(Path(path).read_bytes()).decode("ascii")client = OpenAI(base_url="https://api.numes.ai/api/v1", api_key=os.environ["NUMES_API_KEY"])completion = client.chat.completions.create( model="openai/gpt-6-luna", messages=[ { "role": "user", "content": [ {"type": "text", "text": "Which payment terms does this contract set?"}, {"type": "file", "file": {"filename": "contract.pdf", "file_data": pdf_data_url("contract.pdf")}}, ], } ],)print(completion.choices[0].message.content)Inline PDFs count toward the 10 MiB chat body limit, and base64 adds about a third to their size. Send PDFs larger than about 7.5 MiB as HTTPS URLs.
The file part
Content part
type"file"RequiredIdentifies a file part.
fileobjectRequiredThe document to attach.
Show child attributesHide child attributes
file_datastringRequiredAn
https://URL that serves a PDF, or adata:application/pdf;base64,URL.filenamestringOptional name, at most 255 bytes, without control characters. It isn't forwarded to the provider; put instructions in a text part.
file_idstringNot supported; there's no file storage. Any
file_idis rejected with 400.
You can attach several PDFs to one message; they reach the model in the order you list them. Only PDFs are accepted. For Word documents, spreadsheets or plain text, extract the text yourself and send it in a text part.
Which endpoints accept PDFs
Routing considers only endpoints whose input_modalities include file, and never drops the PDF to answer from the text alone. Check a model's endpoints first:
curl "https://api.numes.ai/api/v1/models/author/document-model/endpoints" \ -H "Authorization: Bearer $NUMES_API_KEY"Limits
| Limit | Value |
|---|---|
| Format | PDF only |
| One PDF | 8 MiB decoded |
| All media in one request | 24 MiB decoded, shared with images and audio |
| Chat request body | 10 MiB, including inline data: URLs |
How many pages the model can use depends on the model and its context length. See Sending media for the rules every media URL follows.
Billing
A request with a PDF is charged like any other chat completion. usage.cost is the exact charge; see Usage accounting.
Troubleshooting
File problems return 400 invalid_request unless the table says otherwise. The message names the failing part, such as messages[0].content[1].file.file_data.
| Symptom | Cause and fix |
|---|---|
400 with file_id | Send file_data instead. |
400 with plugins | Remove plugins and use a model with file input. |
400 with a data: URL | The media type isn't application/pdf, the bytes aren't a PDF, or the data isn't standard base64. |
| 400 with an HTTPS URL | The server returned an error status, an HTML page, a compressed response or a mismatched Content-Type, or the URL isn't public HTTPS. |
| 400 for a large file | The PDF exceeds 8 MiB, or all media together exceed 24 MiB. Split or compress it. |
413 payload_too_large | An inline PDF pushed the body over 10 MiB. Send an HTTPS URL. |
503 provider_unavailable | No endpoint for the model accepts file input under your routing preferences. |