Set a TTL on Files API uploads
Set a TTL on Files API uploads
Pass expires_after (seconds from upload) on POST https://api.x.ai/v1/files. Inclusive range: 3600–2592000 (1 hour–30 days). Omit it to keep the file permanently (expires_at is null). The response expires_at is the absolute UTC delete time. After expiry the file is gone from list, metadata and content return not found, and you cannot reference the id. Manual delete still works before the TTL. Max size is 48 MB. Attach the file later with Attach files to a Grok chat request.
purpose is stored for SDK compatibility. Conventional value is assistants. xAI does not enforce it.
curl
-F fields are sent in declaration order. expires_after must come before file or the request returns 400.
# -F fields are sent in declaration order.
# expires_after must come before file in the form body.
curl https://api.x.ai/v1/files \
-H "Authorization: Bearer $XAI_API_KEY" \
-F expires_after=86400 \
-F purpose=assistants \
-F file=@/path/to/document.pdf
xAI SDK
expires_after accepts an int (seconds) or a datetime.timedelta.
import os
from datetime import timedelta
from xai_sdk import Client
client = Client(api_key=os.getenv("XAI_API_KEY"))
# Upload a file that will be auto-deleted in 24 hours.
# expires_after accepts an int (seconds) or a datetime.timedelta.
file = client.files.upload(
"/path/to/document.pdf",
expires_after=timedelta(hours=24),
)
print(f"File ID: {file.id}")
print(f"Expires at: {file.expires_at.ToDatetime()}")
OpenAI SDK
with open("/path/to/document.pdf", "rb") as f:
file = client.files.create(
file=f,
purpose="assistants",
expires_after={"anchor": "created_at", "seconds": 86400}, # 24 hours
)
requests
Put TTL fields in data= before files=.
response = requests.post(
url,
headers=headers,
data=[
("expires_after", "86400"), # 24 hours in seconds
("purpose", "assistants"),
],
files={"file": f},
)
JavaScript FormData
Append expires_after before file.
const formData = new FormData();
// expires_after MUST be appended before the file field.
formData.append("expires_after", "86400"); # 24 hours in seconds
formData.append("purpose", "assistants");
formData.append(
"file",
new Blob([fs.readFileSync("/path/to/document.pdf")]),
"document.pdf",
);
Pitfalls
- Multipart:
expires_afterafterfilereturns 400. - Raw multipart uses a plain integer. Do not send the OpenAI
{"anchor":"created_at","seconds":…}shape on a bare form upload. - After TTL, retrieve is not found.
- Console API credits are separate from SuperGrok's weekly pool on grok.com.