模型能力

持久保存生成的输出

在任意 Imagine 请求中使用 storage_options,即可将生成的 asset 持久保存到你的 Files API 存储中,之后可通过经过身份验证的 Files API 获取。此外,设置 storage_options.public_url 还可以为该 asset 生成永久、可分享的 public URL;这是任何人都能打开的免身份验证链接,在你撤销之前会一直有效。

存储与 public URL 创建彼此独立:你可以只进行私有存储而不创建 public URL,也可以在存储时创建 public URL。无论哪种方式,response 仍会包含默认始终返回的临时 generation URL。

快速开始

生成图像、将其持久保存到 Files,并获得可分享的 public URL;所有操作都在一次调用中完成:

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

response = client.image.sample(
    prompt="A serene Japanese garden in winter",
    model="grok-imagine-image-quality",
    storage_options={"filename": "garden.jpg", "public_url": True},
)

# Ephemeral, short-lived URL.
print(f"Ephemeral:  {response.url}")

# Persistent file in your Files API storage.
print(f"File ID:    {response.file_output.file_id}")

# Permanent, shareable public URL.
print(f"Public URL: {response.public_url}")

Response body 如下:

JSON

{
  "data": [
    {
      "url": "https://imgen.x.ai/xai-imgen/xai-tmp-imgen-abc123.jpg",
      "file_output": {
        "file_id": "file_7de029f4-eb66-42ee-87f8-b2a9d9e7466a",
        "filename": "garden.jpg",
        "public_url": "https://files-cdn.x.ai/ZsqeMtdcSYWPPHTQdxXDKQ/file_7de029f4-eb66-42ee-87f8-b2a9d9e7466a.jpg"
      }
    }
  ]
}

需要注意的要点:

  • data[i].url临时 Imagine URL,生命周期较短,适合立即使用。无论是否指定 storage_options,它都会返回。

  • data[i].file_output.file_id 是生成 asset 的稳定 Files API 标识符。

  • data[i].file_output.public_url永久 public URL。可用于在应用中分享、嵌入和长期存储。

storage_options 参考

字段类型说明
filenamestring(必填存储文件的 filename。public URL 路径上的扩展名来自该 filename。
expires_afterinteger(可选)从当前时间到存储文件过期的秒数。必须介于 3600(1 小时)和 2592000(30 天)之间。省略该字段表示永久存储。
public_urlboolean 或 object(可选)设置为 true 可使用默认设置创建 public URL,也可以传入 object 进行配置。省略该字段(或设为 false)表示私有存储。
public_url.expires_afterinteger(可选)从当前时间到 public URL 过期的秒数。必须介于 3600(1 小时)和 2592000(30 天)之间。详见 过期行为

filename 为必填项。仅传入 storage_options={"filename": "..."} 而不设置其他字段,会将 asset 私有地持久保存:存储文件不会过期,也不会创建 public URL。如果之后改变主意,随时可以对已存储的 create_public_url 调用 file_id

response = client.image.sample(
    prompt="A red circle on a white background",
    model="grok-imagine-image-quality",
    storage_options={"filename": "circle.jpg"},  # store privately, no public URL
)

print(response.file_output.file_id)    # file_...
print(response.file_output.filename)   # circle.jpg
print(response.public_url)             # None — public URL was not requested

过期行为

storage_options 提供两个相互独立的过期控制项:storage_options.expires_after 控制存储文件何时自动删除,storage_options.public_url.expires_after 控制public URL 则控制何时自动撤销。省略 public_url.expires_after 时,URL 会继承文件的过期时间(如果文件没有过期时间,则 URL 永不过期)。

public URL 的生命周期永远不能超过其文件,并且两个值都必须介于1 小时和 30 天之间。完整规则请参阅 Public URLs → 过期行为;以下示例展示了这两个控制项如何在 Imagine 请求中组合使用。

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

# Permanent file, public URL expires in 24h.
response = client.image.sample(
    prompt="A futuristic city skyline at night",
    model="grok-imagine-image-quality",
    storage_options={"filename": "skyline.jpg", "public_url": {"expires_after": 86400}},  # 24h
)
print(response.file_output.file_id)                # file_...
print(response.public_url)                         # https://files-cdn.x.ai/<token>/file_....jpg
print(response.file_output.public_url_expires_at)  # protobuf Timestamp, ~24h from now

# File and public URL both expire in 2h (URL inherits the file's expiry).
response = client.image.sample(
    prompt="A futuristic city skyline at night",
    model="grok-imagine-image-quality",
    storage_options={"filename": "skyline.jpg", "expires_after": 7200, "public_url": True},
)
print(response.file_output.file_id)                # file_...
print(response.public_url)
print(response.file_output.expires_at)             # ~2h from now
print(response.file_output.public_url_expires_at)  # matches file's expires_at

# File expires in 24h, public URL expires in 1h (independent, shorter).
response = client.image.sample(
    prompt="A futuristic city skyline at night",
    model="grok-imagine-image-quality",
    storage_options={
        "filename": "skyline.jpg",
        "expires_after": 86400,
        "public_url": {"expires_after": 3600},
    },
)
print(response.file_output.file_id)                # file_...
print(response.public_url)
print(response.file_output.expires_at)             # ~24h from now
print(response.file_output.public_url_expires_at)  # ~1h from now (URL dies before file)

file_output Response

每个设置了 storage_options 的 Imagine response 都会在每个生成的 asset 上包含一个 file_output block:

字段始终存在含义
file_id稳定的 Files API 标识符。将其用于 client.files.* 操作。
filename你在 storage_options
expires_at仅在文件设置了过期时间时文件过期时的 Unix timestamp。
public_url仅当设置了 storage_options.public_url 且创建成功时永久、可分享的 URL。
public_url_expires_at仅当 public URL 设置了过期时间时public URL 失效时的 Unix timestamp。永久 URL 不包含该字段。
public_url_error仅在部分失败时asset 已存储但 public URL 创建失败时返回的可读错误。详见 Public URL 错误

Python SDK 还会将 response.public_urlresponse.public_url_error 作为 ImageResponseVideoResponse

多个输出(n > 1

在一次调用中请求多张图像时,每张图像都会获得自己的 file_id 以及具有唯一 token 的 public_url。这些文件完全独立,撤销或删除其中一个不会影响其他文件。

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

responses = client.image.sample_batch(
    prompt="A cat wearing a hat, four different art styles",
    model="grok-imagine-image-quality",
    n=4,
    storage_options={"filename": "cat-styles.jpg", "public_url": True},
)

for r in responses:
    print(r.file_output.file_id, r.public_url)

存储图像编辑输出

storage_options/v1/images/edits 上的工作方式与 /v1/images/generations 相同。编辑结果会存储为新文件。

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

response = client.image.sample(
    prompt="Add a party hat to the dog",
    model="grok-imagine-image-quality",
    image_url="https://docs.x.ai/assets/api-examples/images/style-realistic.png",
    storage_options={"filename": "party-dog.png", "public_url": True},
)

print(response.file_output.file_id)  # new file, not the input
print(response.public_url)

存储视频输出

视频 endpoint(/v1/videos/generations/v1/videos/edits/v1/videos/extensions)使用相同的 storage_options 结构。由于视频生成是异步的,file_output.public_url 会填充在视频生成完成后的已完成 response 中。

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

# SDK handles polling automatically and returns the completed video.
response = client.video.generate(
    prompt="A ball bouncing slowly on a flat surface",
    model="grok-imagine-video-1.5",
    duration=5,
    storage_options={"filename": "bouncing-ball.mp4", "public_url": True},
)

print(response.url)                   # ephemeral vidgen URL
print(response.file_output.file_id)   # file_...
print(response.public_url)            # https://files-cdn.x.ai/<token>/file_....mp4

Image-to-video、视频编辑和视频扩展均以相同方式接受 storage_options

Public URL 错误

在极少数情况下,即使 asset 生成和存储成功,public URL 创建也可能失败,例如出现暂时性基础设施问题,或 team 达到 active URL quota。此时不会让整个请求失败,response 仍会包含有效的 file_output.file_id 和原始 asset URL,仅将 public_url 替换为 public_url_error

JSON

{
  "data": [
    {
      "url": "https://imgen.x.ai/.../xai-tmp-imgen-abc123.jpg",
      "file_output": {
        "file_id": "file_abc123",
        "filename": "poster.jpg",
        "public_url_error": "Public URL creation timed out. The file was stored successfully."
      }
    }
  ]
}

如果看到 public_url_error,文件仍在你的存储中;你可以直接通过 Files API 重试 public URL 创建,而无需重新生成 asset:

Python

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

response = client.image.sample(
    prompt="A vintage poster",
    model="grok-imagine-image-quality",
    storage_options={"filename": "poster.jpg", "public_url": True},
)

if response.public_url_error:
    # The image is stored — just retry the public URL on the file directly.
    resp = client.files.create_public_url(response.file_output.file_id)
    public_url = resp.public_url
else:
    public_url = response.public_url

print(public_url)

管理通过 Imagine 创建的文件

通过 storage_options 创建的文件都是完整的一等 Files API 文件。使用 Files API 列出、获取、更新和删除这些文件,并使用 public URL endpoint 撤销或重新创建 URL:

import os
import xai_sdk

client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))

response = client.image.sample(
    prompt="A futuristic city",
    model="grok-imagine-image-quality",
    storage_options={"filename": "city.jpg", "public_url": True},
)
file_id = response.file_output.file_id

# Inspect file metadata
file = client.files.get(file_id)

# Stop sharing publicly (keeps the file in your storage)
client.files.revoke_public_url(file_id)

# Generate a new public URL later with a different expiry
client.files.create_public_url(file_id, expires_after=604800)  # 7 days

# Delete the file entirely (also tears down any active public URL)
client.files.delete(file_id)

限制

  • 每个 team 最多可拥有 1,000 个活跃 public URL。 达到上限时,response 会设置 public_url_error;请撤销未使用的 URL 以释放名额。

  • 过期限制(参见 过期行为):

    • 两个 expires_after 值都必须介于 1 小时和 30 天

    • public_url.expires_after 必须小于或等于文件的 expires_after

  • 自定义 filename 会影响 public URL 路径。 传入 storage_options.filename = "my-cover.png" 会使 public URL 以 .png 结尾。存储的 content type 仍由生成的 asset 决定,而不是由 filename 决定。

  • response_format 不影响存储。 storage_options 无论请求 url 还是 b64_json

  • public URL 与临时 URL 相互独立。 二者在同一个 response 中返回,但具有独立生命周期。撤销 public URL 不会影响临时 URL。

  • 所有验证都是同步的。 无效的存储配置会在生成开始前被拒绝,因此不会将计算资源浪费在格式错误的请求上。