Skip to content
curl "https://api.wxiai.com/xai/v1/videos/$REQUEST_ID" \
  -H "Authorization: Bearer $WXIAI_API_KEY"
import time
import requests

BASE = "https://api.wxiai.com"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

def wait_video(request_id, interval=5, timeout=600):
    deadline = time.time() + timeout
    while time.time() < deadline:
        task = requests.get(
            f"{BASE}/xai/v1/videos/{request_id}", headers=HEADERS
        ).json()
        if task["status"] in ("done", "failed", "expired"):
            return task
        time.sleep(interval)
    raise TimeoutError("轮询超时")

task = wait_video("YOUR_REQUEST_ID")
if task["status"] == "done":
    print(task["video"]["url"])
else:
    print(task["status"], task.get("error"))
{
  "status": "pending",
  "progress": 42,
  "model": "grok-imagine-video-1.5"
}
{
  "status": "done",
  "progress": 100,
  "video": {
    "url": "https://vidgen.x.ai/.../video.mp4",
    "duration": 8,
    "respect_moderation": true
  },
  "model": "grok-imagine-video-1.5"
}
{
  "status": "failed",
  "error": {
    "code": "invalid_argument",
    "message": "Prompt cannot be empty. Please provide a prompt."
  }
}
原生透传层

查询视频任务

用提交时拿到的 request_id 查询任务进度,status 变成 done / failed / expired 就停止轮询。报错是 Grok 官方原文。

GET/xai/v1/videos/{request_id}

端点 ​

http
GET /xai/v1/videos/{request_id}           # 查询状态

同一能力在 OpenAI 兼容层的写法见 查询视频任务(OpenAI 兼容)。

这里的 ID 是 request_id,不是 task_id

原生透传层用 request_id,兼容层用 task_id,两者不通用。拿 task_id 来这里查会找不到任务。

请求 ​

bash
curl "https://api.wxiai.com/xai/v1/videos/$REQUEST_ID" \
  -H "Authorization: Bearer $WXIAI_API_KEY"

状态值 ​

status含义是不是终态常见 HTTP 状态
pending生成中否202
done完成是200
expired请求过期是200
failed生成失败是200

看到 done / failed / expired 就退出轮询。

判断依据是 status,不是 HTTP 200

生成中可能返回 HTTP 202;而失败时返回的仍是 HTTP 200,错误放在 status 和 error 里。

所以别写「HTTP 200 就当成功」——一定读 status。

返回 ​

生成中:

json
{
  "status": "pending",
  "progress": 42,
  "model": "grok-imagine-video-1.5"
}

完成:

json
{
  "status": "done",
  "progress": 100,
  "video": {
    "url": "https://vidgen.x.ai/.../video.mp4",
    "duration": 8,
    "respect_moderation": true
  },
  "model": "grok-imagine-video-1.5"
}
字段说明
statuspending / done / expired / failed
progress完成百分比 0–100。pending 时 0–99,done 时 100,failed 时不返回
video.url视频地址,完成后才有
video.duration实际时长(秒)
video.respect_moderation是否通过内容审核。为 false 时 video.url 是空的
model实际使用的模型。failed 时不返回
errorfailed 时的错误对象
usage用量与成本,含 cost_in_usd_ticks(1 美分 = 100,000,000 ticks)

失败(error 是对象):

json
{
  "status": "failed",
  "error": {
    "code": "invalid_argument",
    "message": "Prompt cannot be empty. Please provide a prompt."
  }
}

失败(error 是字符串,内容审核拦截等情况会这样返回):

json
{
  "status": "failed",
  "error": "imagine:content-moderated"
}

error 有两种形态,解析要兼容

轮询失败时 error 可能是对象({code, message}),也可能是字符串(如 "imagine:content-moderated")。

写解析代码时先判断类型:

python
err = task.get("error")
if isinstance(err, dict):
    code, message = err.get("code"), err.get("message")
elif isinstance(err, str):
    code, message = err, err
else:
    code = message = None

直接把 error 当对象取 .code,遇到字符串形态会崩。

error.code含义怎么办
invalid_argument参数不合法:时长超范围、图片/视频输入有问题、提示词过长、请求模式冲突、被内容审核拦下改参数或素材后重新提交
permission_deniedKey 或团队没有该操作的权限确认 Key 所属分组和模型权限
failed_precondition该模型/设置不支持这个操作(模型不支持编辑/扩展,或分辨率超了)换模型、模式或分辨率
service_unavailable上游暂时过载稍后重试
internal_error上游内部错误重试;持续出现就带上 request_id 找客服

上游同步拒绝时的形态(HTTP 4xx) ​

以下情况不走任务状态,而是直接返回 HTTP 错误,响应体是 xAI 原文(原生层的报错不套 OpenAI 信封):

json
{
  "code": "imagine:content-moderated",
  "error": "Generated image rejected by content moderation.",
  "usage": { "cost_in_usd_ticks": 220000000 }
}
字段说明
code机器可读的原因码,如 imagine:content-moderated
error字符串,人可读的原因
usage本次已产生的成本(被拦下也可能已经计费)

鉴权失败、模型不存在、限流这些错误是在创建任务之前返回的,不会出现在任务结果的 error.code 里。

这一层的注意点 ​

  • progress 在 failed 时不返回:别写 task["progress"] 这种硬取值。
  • 别把轮询写成死循环:服务端 600 秒后判定超时并退还本次额度;客户端也要有自己的超时上限。
  • video.url 是临时地址:done 后尽快下载。要长期保存就用提交时的 storage_options。
  • 审核不通过不是错误:respect_moderation: false 时 status 仍是 done,只是 video.url 为空——要单独判断。

相关页 ​

基于 Apache-2.0 许可发布