Upload Files with the Files API
On this page
From copy-paste to native documents
You’ve probably pasted fifteen pages of a report into a prompt hoping the layout survives. It never does: table columns get mixed up and the model ends up reasoning over text mush. xAI’s Files API solves this exact problem. You send the original document, xAI analyzes it server-side, and Grok works on content where the structure, tables, and section breaks are preserved.
The mechanism fits into a single endpoint, POST /v1/files. You send your file as multipart/form-data with a purpose parameter set to "assistants", and the API returns a unique identifier called a file_id. This identifier becomes the key for everything you do next: querying the document, checking its metadata, deleting it, or adding it to a collection.
Your first upload
Take an annual report in PDF format sitting on your drive. The upload request isn’t JSON but multipart/form-data, which explains the -F syntax instead of -d:
curl -X POST https://api.x.ai/v1/files \
-H "Authorization: Bearer $XAI_API_KEY" \
-F "[email protected]" \
-F "purpose=assistants"
The response arrives in a few seconds and contains the file identifier along with its characteristics:
{
"id": "file_abc123xyz",
"object": "file",
"bytes": 2458901,
"created_at": 1710000000,
"filename": "annual-report.pdf",
"purpose": "assistants"
}
This file_id—here file_abc123xyz—is your permanent reference to the document. Note it as soon as you receive the response: a lost identifier means an orphaned file that consumes quota without being usable.
Parameters and authentication
Only two parameters, both required:
- file: The binary content of the file, sent as multipart. Max size is 48 MB
- purpose: Always
"assistants", the only accepted value to date. It indicates the file will be used for model interactions
You’ll hit the 48 MB limit faster than you might expect: a one-day log export or complete product documentation regularly exceeds it. In this case, split your source into several coherent files rather than truncating arbitrarily—you’ll find them all in the same collection later.
On the authentication side, every request to the Files API carries your standard API key in the Authorization: Bearer header. Keep in mind right now that this key is not the Management API Key: that one, reserved for collections, comes later in the course and is frequently confused with the first one during early attempts.
Using the file
The uploaded file is useless unless you reference it in a request. This is the role of the input_file block in the Responses API, which you accompany with a free-text instruction:
{
"model": "grok-4.5",
"input": [
{
"type": "input_file",
"file_id": "file_abc123xyz"
},
{
"type": "input_text",
"text": "Summarize the key points of this document."
}
]
}
Grok receives the file, automatically activates the attachment_search tool server-side, extracts relevant passages, and writes its response based on them. No manual activation is necessary, and no additional parameters need to be added: the presence of an input_file is enough to trigger the whole chain. Each attachment call is billed at $10 per 1,000, making a single upload queried ten times more cost-effective than ten uploads of the same document.
Pricing as of August 5, 2026 — prices change regularly: before any budget calculation, check the current grid on the official xAI models and pricing page.
Key takeaways
- The
POST /v1/filesendpoint accepts files up to 48 MB inmultipart/form-data - The
purposeparameter must be"assistants" - The returned
file_idis your reference for all subsequent operations - The
attachment_searchtool activates automatically when a file is referenced in a request - The cost is $10 per 1,000 attachment calls