08API 基础
任务与状态
图片是异步生成的。请求被接收后,你会得到任务 id:可以用它查询状态,直到返回 completed 或 failed,也可以等待 Webhook。
查询状态
/creations/{id}代入生成请求响应中的 id。任务只对创建它的账号可见:他人的或未知的 id 会返回 404 ERR_NOT_FOUND。请自行保存 id。
CREATION_ID="5b0214ae-9e39-460a-820a-f6ae3e24400b" curl --fail-with-body --max-time 20 \ "https://api.rendergrid.io/ api/ public/ v1/ creations/ $CREATION_ID" \ -H "Authorization: Bearer $RENDERGRID_API_KEY"
import os import requests API = "https://api.rendergrid.io/ api/ public/ v1" creation_id = "5b0214ae-9e39-460a-820a-f6ae3e24400b" key = os.environ["RENDERGRID_API_KEY"] response = requests.get( f"{API}/creations/{creation_id}", headers={"Authorization": f"Bearer {key}"}, timeout=(5, 20), ) response.raise_for_status() print(response.json())
// Node.js 22+,文件扩展名为 .mjs const API = "https://api.rendergrid.io/ api/ public/ v1"; const id = "5b0214ae-9e39-460a-820a-f6ae3e24400b"; const key = process.env.RENDERGRID_API_KEY; const response = await fetch(`${API}/creations/${id}`, { headers: { Authorization: `Bearer ${key}` }, signal: AbortSignal.timeout(20_000), }); if (!response.ok) { const body = await response.text(); throw new Error(`HTTP ${response.status}: ${body}`); } console.log(await response.json());
状态
| 状态 | 含义 | 怎么办 |
|---|---|---|
queued | 请求已接收,正在排队等待 | 请等待,稍后再查询 |
processing | 正在生成图片 | 请等待,稍后再查询 |
completed | 已完成 | 通过 result_urls 中的链接下载文件 |
failed | 未能得到图片 | 阅读 failure,再决定是否调整请求 |
completed 和 failed 是最终状态:此时可以停止轮询。200 响应中可能带有 status: "failed":这是任务的结果,而不是状态查询请求本身的错误。
请求失败不收费:金额会立即退回余额。
响应的样子
结果出来之前,响应中只有 id 和 status。其余字段在最后才会出现。
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "queued"
}
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "processing"
}目前没有其他字段。请在 5 秒或更长时间后再查询一次。
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "completed",
"result_urls": ["https:// cdn.rendergrid.io/ images/ example/ result.jpg"]
}result_urls 是现成的文件链接。请原样使用:不要用 id 拼接,也不要依赖文件扩展名。
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "failed",
"error": "The image or prompt was rejected by the safety filter. Try a different image or rephrase the prompt.",
"failure": {
"type": "declined",
"code": "content_policy",
"retryable": false
}
}error 是用于展示的文本。业务逻辑请依据 failure.type 和 failure.code:它们的含义。
亲自试试
这是教学示意,不会向 API 发出请求。选择一种结果,然后点击按钮。
queued请求已接收。任务正在排队。
processing图片正在生成。
completed完成:响应中有 result_urls。
点击“发送请求”:我们会展示 GET /creations/ 在每一步返回什么。
查询的频率
同一个任务、同一个密钥,每 5 秒最多查询一次。更频繁的轮询会收到 429 ERR_RATE_LIMIT:等待时间既不要少于 details.min_interval_seconds,也不要少于 Retry-After。
HTTP/1.1 429 Too Many Requests
Retry-After: 2
{
"error": {
"code": "ERR_RATE_LIMIT",
"message": "polled too soon — retry after the minimum interval",
"details": { "min_interval_seconds": 5 }
}
}- 收到
completed或failed时停止轮询。 - 遇到连接中断、
429和5xx时,请间隔一段时间后重试,并遵循Retry-After。 - 限制总等待时间。如果超时,请保存
id并稍后继续:你的客户端超时并不会取消任务。 - 如果有多个进程在轮询,请让它们共用同一个间隔。
等待循环的示例。其中的等待时间是示例的设置,而不是模型的处理时长。
import os import time import requests BASE = "https://api.rendergrid.io/ api/ public/ v1" KEY = os.environ["RENDERGRID_API_KEY"] SESSION = requests.Session() SESSION.headers["Authorization"] = f"Bearer {KEY}" TIMEOUT = (5, 20) # 单位为秒:连接超时、读取超时 def wait_for(creation_id: str, wait_seconds: int = 180) -> dict: url = f"{BASE}/creations/{creation_id}" deadline = time.monotonic() + wait_seconds while time.monotonic() < deadline: delay = 5.0 try: resp = SESSION.get(url, timeout=TIMEOUT) except (requests.Timeout, requests.ConnectionError): resp = None if resp is not None: if resp.status_code == 429 or resp.status_code >= 500: wait = resp.headers.get("Retry-After", "5") if wait.isascii() and wait.isdigit(): delay = max(5.0, int(wait)) else: resp.raise_for_status() creation = resp.json() if creation["status"] in ("completed", "failed"): return creation if delay >= deadline - time.monotonic(): break time.sleep(delay) # 超时:id 已保存,之后可以继续轮询 raise TimeoutError(f"Still unresolved: {creation_id}")
const BASE = "https://api.rendergrid.io/ api/ public/ v1"; const KEY = process.env.RENDERGRID_API_KEY; const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function waitFor(creationId, waitMs = 180_000) { const url = `${BASE}/creations/${creationId}`; const deadline = Date.now() + waitMs; while (Date.now() < deadline) { let delay = 5_000; let resp; try { const left = Math.min(20_000, deadline - Date.now()); resp = await fetch(url, { headers: { Authorization: `Bearer ${KEY}` }, signal: AbortSignal.timeout(Math.max(1, left)), }); } catch (error) { const network = error instanceof TypeError; if (!network && error.name !== "TimeoutError") throw error; } if (resp) { if (resp.status === 429 || resp.status >= 500) { const wait = resp.headers.get("Retry-After"); if (wait && /^[0-9]+$/.test(wait)) { delay = Math.max(delay, Number(wait) * 1_000); } } else { if (!resp.ok) { const text = await resp.text(); throw new Error(`HTTP ${resp.status}: ${text}`); } const creation = await resp.json(); if (["completed", "failed"].includes(creation.status)) { return creation; } } } if (delay >= deadline - Date.now()) break; await sleep(delay); } // 超时:id 已保存,之后可以继续轮询 throw new Error(`Still unresolved: ${creationId}`); }
结果文件
文件保存一天。拿到链接后请立即把图片下载到你自己的存储中;如果下载时出现临时错误,请重试。轮询不会延长保存期限。
任务记录和响应中的链接并不保证文件仍然可用。永久存储在你这一侧。
用 Webhook 代替轮询
在生成请求中传入 webhook_url,任务变为 completed 或 failed 时我们会主动通知你。请把轮询留作备用方案:通知可能延迟,也可能没有送达。
常见问题
要等多久才能拿到结果?
id 并稍后继续。任务变为 failed 后怎么办?
failure.type 和 failure.code。这类任务的金额已自动退回余额。如需再试一次,请使用新的幂等键发送新的请求。为什么用我的 id 查询会返回 404?
id,并确认密钥属于同一个账号。