
Upload Files API content from bytes or a file handle
Upload Files API content from bytes or a file handle
client.files.upload accepts a path string, raw bytes, a BytesIO, or an open file handle. Use bytes or a handle when the payload already lives in memory or came from another stream and you do not want a temp file on disk. Max size is 512 MB. Get a key at console.x.ai.
From bytes
Pass the bytes and a filename so the Files object has a usable name downstream.
import os
from xai_sdk import Client
client = Client(api_key=os.getenv("XAI_API_KEY"))
content = b"This is my document content.\nIt can span multiple lines."
file = client.files.upload(content, filename="document.txt")
print(f"File ID: {file.id}")
print(f"Filename: {file.filename}")
print(f"Size: {file.size} bytes")
From an open file handle
import os
from xai_sdk import Client
client = Client(api_key=os.getenv("XAI_API_KEY"))
with open("document.pdf", "rb") as f:
file = client.files.upload(f, filename="document.pdf")
print(f"File ID: {file.id}")
Path uploads still work: client.files.upload("/path/to/document.pdf"). Attach the returned id in chat with Attach files to a Grok chat request, or feed Imagine with Use Files API as Imagine inputs.
REST / OpenAI SDK
Multipart POST https://api.x.ai/v1/files with purpose=assistants (stored for compatibility; xAI does not enforce it) and file=@.... OpenAI SDK: client.files.create(file=..., purpose="assistants") against base_url="https://api.x.ai/v1".
Pitfalls
- Omitting
filenameon bytes uploads leaves a vague name in list/get responses. - Putting
expires_afterafterfilein multipart returns 400; TTL fields must come first. - Collections uploads cap at 100 MB per file; the standalone Files API allows 512 MB.