Create a public URL for a Files API file
Create a public URL for a Files API file
After a file is uploaded, call POST /v1/files/{id}/public-url to mint an unauthenticated CDN link on https://files-cdn.x.ai/<token>/file_….png. Upload first (Set a TTL on Files API uploads); you cannot create a public URL during the upload request. For Imagine generation-time public URLs via storage_options.public_url, see Persist an Imagine output with a public URL.
Create
Body may be empty {} or set expires_after (seconds). Inclusive range: 3600–2592000 (1 hour–30 days). The public URL never outlives the file.
curl -X POST https://api.x.ai/v1/files/$FILE_ID/public-url \
-H "Authorization: Bearer $XAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expires_after": 86400}'
curl -X POST https://api.x.ai/v1/files/$FILE_ID/public-url \
-H "Authorization: Bearer $XAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Revoke
curl -X POST https://api.x.ai/v1/files/$FILE_ID/public-url/revoke \
-H "Authorization: Bearer $XAI_API_KEY"
xAI SDK
import os
from xai_sdk import Client
client = Client(api_key=os.getenv("XAI_API_KEY"))
# After upload: file.id is required
public = client.files.create_public_url(file.id, expires_after=86400)
print(public.public_url) # https://files-cdn.x.ai/<token>/file_….png
client.files.revoke_public_url(file.id)
# List files that currently have a public URL
for f in client.files.list(filter="public_url != null"):
print(f.id, f.public_url)
Idempotency and limits
One active public URL per file. Repeating create returns the same URL. Passing a different expires_after updates expiry in place.
| Limit | Value |
|---|---|
| Max size for public | 50 MiB |
| Allowed types | png, jpeg, mp4, pdf |
| Active public URLs per team | 1000 |
expires_after |
3600–2592000 seconds |
Pitfalls
- Upload the file first; public URL create during upload is unsupported.
- The CDN URL ends when the file expires or is deleted, even if
expires_afteris longer. - Types outside png/jpeg/mp4/pdf cannot get a public URL.
- Console API credits are separate from SuperGrok's weekly pool on grok.com.