Skip to content
Numes

Multimodal

PDFs and files

Attach PDF documents to chat requests with the file content part. PDFs go only to endpoints that read files natively.

On this page

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 Path​from openai import OpenAI​def 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"Required

Identifies a file part.

fileobjectRequired

The document to attach.

Show child attributes
file_datastringRequired

An https:// URL that serves a PDF, or a data:application/pdf;base64, URL.

filenamestring

Optional name, at most 255 bytes, without control characters. It isn't forwarded to the provider; put instructions in a text part.

file_idstring

Not supported; there's no file storage. Any file_id is 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

LimitValue
FormatPDF only
One PDF8 MiB decoded
All media in one request24 MiB decoded, shared with images and audio
Chat request body10 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.

SymptomCause and fix
400 with file_idSend file_data instead.
400 with pluginsRemove plugins and use a model with file input.
400 with a data: URLThe media type isn't application/pdf, the bytes aren't a PDF, or the data isn't standard base64.
400 with an HTTPS URLThe 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 fileThe PDF exceeds 8 MiB, or all media together exceed 24 MiB. Split or compress it.
413 payload_too_largeAn inline PDF pushed the body over 10 MiB. Send an HTTPS URL.
503 provider_unavailableNo endpoint for the model accepts file input under your routing preferences.

Next steps