API / set-files-api-ttl

API

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_after after file returns 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.