
List Files API uploads that have a public URL
Filter your Files API inventory to rows that currently expose an unauthenticated CDN link so you can audit shareable assets, revoke stale ones, or stay under the team cap of 1,000 active public URLs. Official Public URLs documents the filter parameter on list_files (public_url != null or public_url = null) and notes that get_file / list rows populate public_url and public_url_expires_at when a link is active. Create a key at console.x.ai.
What you need
An XAI_API_KEY, at least one file already uploaded (optionally with a public URL from Create a public URL for a Files API file), and a reason to inventory links rather than open the Console Files page by hand. Neighboring jobs include List, download, and delete Files API uploads for unfiltered pagination, and Set a TTL on Files API uploads when the underlying file should expire with the link. More API jobs live on the API hub.
Filter for active public URLs
- Export the key, then call list with a URL-encoded filter for files that have a public URL:
export XAI_API_KEY="your_api_key"
curl -s "https://api.x.ai/v1/files?filter=public_url%20!%3D%20null" \
-H "Authorization: Bearer $XAI_API_KEY"
- Or invert the filter to find private-only files (
public_url = null):
curl -s "https://api.x.ai/v1/files?filter=public_url%20%3D%20null" \
-H "Authorization: Bearer $XAI_API_KEY"
- With the xAI Python SDK, pass the same expression to
client.files.listand print id, filename, and the CDN URL:
import os
from xai_sdk import Client
client = Client(api_key=os.getenv("XAI_API_KEY"))
with_url = client.files.list(filter="public_url != null")
for f in with_url.data:
print(f.id, f.filename, getattr(f, "public_url", None))
without_url = client.files.list(filter="public_url = null")
print(f"Private-only count this page: {len(without_url.data)}")
- Combine with normal list options (
limit,order,sort_by,pagination_token) when the team has more than one page. Revoke a leaked link withPOST /v1/files/{id}/public-url/revokefrom the create-public-URL sibling — revoking clears the CDN token but leaves the private file in place.
What the metadata shows
Active rows carry public_url (for example https://files-cdn.x.ai/<token>/file_….png) and optionally public_url_expires_at when you set expires_after at create time. Deleting the file revokes the public URL automatically. A file can have only one active public URL; re-creating after revoke issues a new token and permanently kills the old link.
Pitfalls
Listing without the filter and scanning locally works until you hit pagination caps — use the server-side filter when you only care about shareable rows. Expecting a public URL on every upload is wrong; files stay private until you mint a link. Assuming revoke deletes the file will surprise you on the next authenticated GET /v1/files/{id}/content. Forgetting the team 1,000-active-URL limit leads to create failures until you revoke unused links.