curl --request GET \
--url https://apis.viggle.ai/v1/images/{image_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/images/{image_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://apis.viggle.ai/v1/images/{image_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://apis.viggle.ai/v1/images/{image_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://apis.viggle.ai/v1/images/{image_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://apis.viggle.ai/v1/images/{image_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/images/{image_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "queued",
"model": "<string>",
"progress": 50,
"images": [
{
"url": "<string>",
"width": 2,
"height": 2,
"seed": 1
}
],
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}查询图片
获取图片生成任务的当前状态,就绪后获取 PNG 下载链接。
curl --request GET \
--url https://apis.viggle.ai/v1/images/{image_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/images/{image_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://apis.viggle.ai/v1/images/{image_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://apis.viggle.ai/v1/images/{image_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://apis.viggle.ai/v1/images/{image_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://apis.viggle.ai/v1/images/{image_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/images/{image_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "queued",
"model": "<string>",
"progress": 50,
"images": [
{
"url": "<string>",
"width": 2,
"height": 2,
"seed": 1
}
],
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}GET /v1/images/{image_id} 返回生成图片所创建任务的当前状态,结构与创建接口返回的 Image 对象相同。每 2–3 秒轮询一次,直到 status 为 ready 或 failed,然后从 images[].url 下载 PNG。
只能查询自己 API 密钥创建的任务。ID 不存在或属于其他密钥时返回 404 NOT_FOUND,两种情况刻意不做区分。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
image_id | string | 是 | 生成图片返回的完整任务 ID,以 img_ 开头。 |
响应参数
返回200 OK 和 Image 对象。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 任务 ID,以 img_ 开头。 |
status | string | queued、processing、ready 或 failed,见状态与错误码。 |
model | string | 使用的模型,目前为 qwen。 |
progress | integer 或 null | 已完成张数占比:queued 为 0,processing 为 0–99,ready 为 100,failed 为 null。 |
images | array | ready 前始终为空;ready 后按请求顺序列出全部 n 张。 |
images[].url | string 或 null | PNG 的签名下载链接,1 小时内有效,过期后再查询一次即可拿到新链接。文件在保留期结束被清理后为 null。 |
images[].width / images[].height | integer | 实际尺寸(像素),见输出尺寸。 |
images[].seed | integer | 这张图实际使用的 seed。 |
created_at | string 或 null | 创建时间,RFC 3339。 |
completed_at | string 或 null | 结束时间,ready 或 failed 时有值。 |
error | object 或 null | 失败原因,只在 failed 时有值。 |
就绪示例
签名参数已省略:{
"id": "img_b16a190d-2d44-41a0-8056-ef68183c3b9e",
"status": "ready",
"model": "qwen",
"progress": 100,
"images": [
{"url": "https://storage.googleapis.com/viggle/image-generation/b16a190d-2d44-41a0-8056-ef68183c3b9e/0.png?X-Goog-Signature=...", "width": 1376, "height": 768, "seed": 0},
{"url": "https://storage.googleapis.com/viggle/image-generation/b16a190d-2d44-41a0-8056-ef68183c3b9e/1.png?X-Goog-Signature=...", "width": 1376, "height": 768, "seed": 1}
],
"created_at": "2026-10-12T08:20:00Z",
"completed_at": "2026-10-12T08:20:22Z",
"error": null
}
失败示例
{
"id": "img_b16a190d-2d44-41a0-8056-ef68183c3b9e",
"status": "failed",
"model": "qwen",
"progress": null,
"images": [],
"created_at": "2026-10-12T08:20:00Z",
"completed_at": "2026-10-12T08:35:00Z",
"error": {
"code": "SERVICE_BUSY",
"message": "The image service is busy; try again later.",
"retryable": true,
"request_id": null,
"details": {},
"remediation": { "action": "retry", "retry_after_ms": null }
}
}
状态与错误码
任务只会向前走:queued → processing → ready 或 failed,不会出现 cancelled。一个任务要么 n 张全部生成,要么整体失败,不会只返回部分图片。
status | 含义 |
|---|---|
queued | 已接受,在等 GPU;高峰时会在这个状态停留一段时间。 |
processing | 正在逐张生成,progress 随每张完成而增加。 |
ready | 全部完成,images 已填充。 |
failed | 失败,原因见 error。 |
error.code 的取值:
code | retryable | 什么时候出现 | 建议 |
|---|---|---|---|
SERVICE_BUSY | true | 生成服务繁忙或暂时不可用,或任务 15 分钟内未完成。 | 稍后用同样的参数重新创建。 |
TASK_FAILED | true | 其他生成或上传失败。 | 重新创建;反复出现请带上任务 id 联系我们。 |
INVALID_REQUEST | false | 模型拒绝了这个请求,例如参考图无法使用。 | 调整参数或参考图后再试。 |
| HTTP | code | 含义 |
|---|---|---|
401 | UNAUTHENTICATED | 缺少或无效的 API 密钥。 |
404 | NOT_FOUND | 任务不存在,或不属于当前密钥。 |
429 | RATE_LIMITED | 请求过多,稍后重试。 |
500 | INTERNAL_ERROR | 服务端内部错误,可重试。 |
503 | SERVICE_BUSY | 服务暂时不可用,可重试。 |
error 使用同样的结构,外面包一层 {"error": {...}},详见错误与恢复。
耗时
2026-10-12 生产实测:1K 两张约 17–22 秒,2K 带参考图一张约 37 秒。图片逐张生成,张数越多越久;高峰时会先在 queued 排队。一个任务 15 分钟内没完成会以 SERVICE_BUSY 失败。
数据保留
- 生成的图片在任务结束 24 小时后删除,请在此之前下载。之后本接口仍然可以查到任务,状态仍为
ready,但每个images[].url为null。 - 上传的或从
reference_image_url拉取的参考图在 24 小时内删除。 - 客户数据不会用于训练模型。
示例
curl https://apis.viggle.ai/v1/images/img_b16a190d-2d44-41a0-8056-ef68183c3b9e \
-H "Authorization: Bearer $VIGGLE_API_KEY"
import os, requests
response = requests.get(
"https://apis.viggle.ai/v1/images/img_b16a190d-2d44-41a0-8056-ef68183c3b9e",
headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"},
)
response.raise_for_status()
image = response.json()
const response = await fetch("https://apis.viggle.ai/v1/images/img_b16a190d-2d44-41a0-8056-ef68183c3b9e", {
headers: { Authorization: `Bearer ${process.env.VIGGLE_API_KEY}` },
});
const image = await response.json();
req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/images/img_b16a190d-2d44-41a0-8056-ef68183c3b9e", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
const image = await viggle.images.get("img_b16a190d-2d44-41a0-8056-ef68183c3b9e");
console.log(image.status, image.images.map((generated) => generated.url));
快速入门:Viggle Image
授权
服务端 SDK 使用项目 API 密钥,Remote MCP 使用 OAuth 访问令牌。不要在浏览器代码中暴露项目密钥。
请求头
可选的调用者自定义关联 ID,最长 128 字符。服务会在响应头返回实际使用的值,便于追踪和支持排查。
1 - 128可选来源标签,最长 128 字符,用于识别 SDK、集成、产品入口或内部工作流。
1 - 128路径参数
POST /v1/images 返回的图片任务公开 ID,以 img_ 开头,必须由当前 API 密钥创建。
1响应
请求成功。
图片生成任务(img_ 前缀),创建接口与查询接口返回同一结构。状态只会向前推进:queued → processing → ready 或 failed,不会出现 cancelled。ready 前 images 始终为空,ready 后按请求顺序列出全部 n 张。一个任务要么 n 张全部生成,要么整体失败,不会只返回部分图片。
图片任务公开 ID,以 img_ 开头。
1任务状态,ready 和 failed 为终态。
queued, processing, ready, failed 使用的模型,目前为 qwen。
已完成张数占比:queued 为 0,processing 为 0–99,ready 为 100,failed 为 null。
0 <= x <= 100ready 前为空;ready 后按请求顺序列出全部 n 张。
Show child attributes
Show child attributes
创建时间,RFC 3339。
结束时间,ready 或 failed 时有值,之前为 null。
失败原因,只在 status 为 failed 时有值。code 为 SERVICE_BUSY(可重试:生成服务繁忙或暂时不可用,或任务 15 分钟内未完成)、TASK_FAILED(可重试:其他生成或上传失败)或 INVALID_REQUEST(不可重试:模型拒绝了请求,例如参考图无法使用)。
Show child attributes
Show child attributes

