获取任务状态
curl --request GET \
--url https://api.poyo.ai/api/generate/status/{task_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.poyo.ai/api/generate/status/{task_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.poyo.ai/api/generate/status/{task_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{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "finished",
"credits_amount": 2,
"files": [
{
"file_url": "https://storage.poyo.ai/generated/image-abc123.jpg",
"file_type": "image"
}
],
"created_time": "2025-11-12T10:30:00",
"progress": 100,
"error_message": null
}
}{
"code": 200,
"error": {
"message": "<string>",
"type": "<string>"
}
}全部任务
获取任务状态
查询任务执行状态并获取生成结果
GET
/
api
/
generate
/
status
/
{task_id}
获取任务状态
curl --request GET \
--url https://api.poyo.ai/api/generate/status/{task_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.poyo.ai/api/generate/status/{task_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_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://api.poyo.ai/api/generate/status/{task_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.poyo.ai/api/generate/status/{task_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{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "finished",
"credits_amount": 2,
"files": [
{
"file_url": "https://storage.poyo.ai/generated/image-abc123.jpg",
"file_type": "image"
}
],
"created_time": "2025-11-12T10:30:00",
"progress": 100,
"error_message": null
}
}{
"code": 200,
"error": {
"message": "<string>",
"type": "<string>"
}
}获取任务状态
查询图像、视频、音频、3D 和内容审核任务的执行状态,并在完成后获取结果。接口
GET https://api.poyo.ai/api/generate/status/{task_id}
认证
所有请求都需要 Bearer token 认证:Authorization: Bearer YOUR_API_KEY
获取 API Key
在控制台生成你的 API Key
参数
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 提交接口返回的唯一任务标识 |
响应
成功响应(200)
{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "finished",
"credits_amount": 2,
"files": [
{
"file_url": "https://storage.poyo.ai/generated/image-abc123.jpg",
"file_type": "image"
}
],
"created_time": "2025-11-12T10:30:00",
"progress": 100,
"error_message": null
}
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | HTTP 状态码(成功为 200) |
data.task_id | string | 唯一任务标识 |
data.status | string | 任务状态:not_started、running、finished、failed |
data.credits_amount | number | 该任务扣除的积分 |
data.output | object | 可选的结构化模型输出。Omni Moderation 在这里返回完整的 OpenAI moderation 响应,同时 files: []、credits_amount: 0 |
data.files | array | 生成的媒体文件(状态为 finished 时) |
data.files[].file_url | string | 生成文件的直接 URL |
data.files[].file_type | string | 生成文件的类型:image、video、audio、3d 或 other |
data.files[].label | string | 可选的文件标签。常见于 3D 输出,例如 model_glb 或 thumbnail |
data.files[].format | string | 可选的文件格式,例如 glb、fbx、obj、png 或 mp4 |
data.files[].content_type | string | 可选的生成文件 MIME 类型 |
data.files[].file_name | string | 可选的文件名 |
data.files[].file_size | integer | 可选的文件大小(字节) |
data.files[] 结构化字段 | object | 部分音频工作流返回 voice_id、voice_status、is_available 或 origin_data 等字段,而不是单个媒体 URL |
data.created_time | string | 任务创建时间,ISO 8601 时间戳 |
data.progress | integer | 完成百分比(0-100) |
data.error_message | string | 错误描述(状态为 failed 时) |
finished 后检查 data.output.results[].flagged。flagged: true 表示审核已完成并检测到相关内容,不会使任务变为 failed。Omni Moderation 异步运行,支持通过 callback_url 回调,不支持流式输出。其回调体与这里返回的任务数据对象相同,有 output 时会包含 output,并且 credits_amount: 0。
状态值
| 状态 | 说明 |
|---|---|
not_started | 任务已排队,等待处理 |
running | 任务正在生成 |
finished | 任务成功完成,结果在 files 或 output 中 |
failed | 任务失败,错误详情在 error_message 中 |
各状态响应示例
未开始
{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "not_started",
"credits_amount": 2,
"files": [],
"created_time": "2025-11-12T10:30:00",
"progress": 0,
"error_message": null
}
}
运行中
{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "running",
"credits_amount": 2,
"files": [],
"created_time": "2025-11-12T10:30:00",
"progress": 45,
"error_message": null
}
}
已完成(图像)
{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "finished",
"credits_amount": 2,
"files": [
{
"file_url": "https://storage.poyo.ai/generated/image-abc123.jpg",
"file_type": "image"
}
],
"created_time": "2025-11-12T10:30:00",
"progress": 100,
"error_message": null
}
}
已完成(视频)
{
"code": 200,
"data": {
"task_id": "task-unified-1757165211-xyz789",
"status": "finished",
"credits_amount": 20,
"files": [
{
"file_url": "https://storage.poyo.ai/generated/video-xyz789.mp4",
"file_type": "video"
}
],
"created_time": "2025-11-12T10:30:00",
"progress": 100,
"error_message": null
}
}
已完成(TTS)
{
"code": 200,
"data": {
"task_id": "KAI9LGP3UIXLG51W",
"status": "finished",
"credits_amount": 1,
"files": [
{
"file_url": "https://cdn.doculator.org/audios/KAI9LGP3UIXLG51W/KAI9LGP3UIXLG51W.mp3",
"file_type": "audio"
},
{
"file_url": "https://cdn.doculator.org/audios/KAI9LGP3UIXLG51W/timestamps.json",
"file_type": "other"
}
],
"created_time": "2026-05-13T10:39:39",
"progress": 100,
"error_message": null
}
}
已完成(3D)
{
"code": 200,
"data": {
"task_id": "9OTM0HH9LBS63LF0",
"status": "finished",
"credits_amount": 30,
"files": [
{
"file_url": "https://cdn.doculator.org/3d/9OTM0HH9LBS63LF0/9OTM0HH9LBS63LF0_1.glb",
"file_type": "3d"
},
{
"file_url": "https://cdn.doculator.org/3d/9OTM0HH9LBS63LF0/9OTM0HH9LBS63LF0_2.png",
"file_type": "image"
},
{
"file_url": "https://cdn.doculator.org/3d/9OTM0HH9LBS63LF0/9OTM0HH9LBS63LF0_3.glb",
"file_type": "3d"
}
],
"created_time": "2026-05-12T02:36:12",
"progress": 100
}
}
失败
{
"code": 200,
"data": {
"task_id": "task-unified-1757165031-uyujaw3d",
"status": "failed",
"credits_amount": 0,
"files": [],
"created_time": "2025-11-12T10:30:00",
"progress": 0,
"error_message": "The prompt violates our content policy"
}
}
代码示例
cURL
curl -X GET https://api.poyo.ai/api/generate/status/task-unified-1757165031-uyujaw3d \
-H "Authorization: Bearer YOUR_API_KEY"
Python
import requests
import json
API_KEY = "your-api-key-here"
task_id = "task-unified-1757165031-uyujaw3d"
response = requests.get(
f"https://api.poyo.ai/api/generate/status/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
result = response.json()
data = result["data"]
print(f"Status: {data['status']}")
print(f"Progress: {data['progress']}%")
print(f"Credits: {data['credits_amount']}")
if data["status"] == "finished":
for item in data["files"]:
if "file_url" in item:
print(f"Generated file: {item['file_url']}")
else:
print(f"Structured result: {json.dumps(item)}")
elif data["status"] == "failed":
print(f"Error: {data['error_message']}")
JavaScript / Node.js
const API_KEY = 'your-api-key-here';
const taskId = 'task-unified-1757165031-uyujaw3d';
const response = await fetch(
`https://api.poyo.ai/api/generate/status/${taskId}`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`
}
}
);
const result = await response.json();
const data = result.data;
console.log(`Status: ${data.status}`);
console.log(`Progress: ${data.progress}%`);
console.log(`Credits: ${data.credits_amount}`);
if (data.status === 'finished') {
data.files.forEach(item => {
if (item.file_url) {
console.log(`Generated file: ${item.file_url}`);
} else {
console.log(`Structured result: ${JSON.stringify(item)}`);
}
});
} else if (data.status === 'failed') {
console.log(`Error: ${data.error_message}`);
}
Go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
APIKey = "your-api-key-here"
BaseURL = "https://api.poyo.ai"
)
type APIResponse struct {
Code int `json:"code"`
Data TaskData `json:"data"`
}
type TaskData struct {
TaskID string `json:"task_id"`
Status string `json:"status"`
Files []map[string]any `json:"files"`
CreatedTime string `json:"created_time"`
Progress int `json:"progress"`
CreditsAmount float64 `json:"credits_amount"`
ErrorMessage *string `json:"error_message"`
}
func main() {
taskID := "task-unified-1757165031-uyujaw3d"
req, _ := http.NewRequest(
"GET",
fmt.Sprintf("%s/api/generate/status/%s", BaseURL, taskID),
nil,
)
req.Header.Set("Authorization", "Bearer "+APIKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var apiResp APIResponse
json.Unmarshal(body, &apiResp)
data := apiResp.Data
fmt.Printf("Status: %s\n", data.Status)
fmt.Printf("Progress: %d%%\n", data.Progress)
fmt.Printf("Credits: %.2f\n", data.CreditsAmount)
if data.Status == "finished" {
for _, item := range data.Files {
if fileURL, ok := item["file_url"].(string); ok {
fmt.Printf("Generated file: %s\n", fileURL)
} else {
encoded, _ := json.Marshal(item)
fmt.Printf("Structured result: %s\n", encoded)
}
}
} else if data.Status == "failed" {
fmt.Printf("Error: %s\n", *data.ErrorMessage)
}
}
Java
import java.net.http.*;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
public class PoYoAPI {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.poyo.ai";
public static void main(String[] args) throws Exception {
String taskId = "task-unified-1757165031-uyujaw3d";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/api/generate/status/" + taskId))
.header("Authorization", "Bearer " + API_KEY)
.GET()
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.body());
JsonNode data = root.get("data");
String status = data.get("status").asText();
int progress = data.get("progress").asInt();
double creditsAmount = data.get("credits_amount").asDouble();
System.out.println("Status: " + status);
System.out.println("Progress: " + progress + "%");
System.out.println("Credits: " + creditsAmount);
if ("finished".equals(status)) {
JsonNode files = data.get("files");
files.forEach(item -> {
if (item.hasNonNull("file_url")) {
System.out.println("Generated file: " + item.get("file_url").asText());
} else {
System.out.println("Structured result: " + item.toString());
}
});
} else if ("failed".equals(status)) {
System.out.println("Error: " + data.get("error_message").asText());
}
}
}
PHP
<?php
$apiKey = 'your-api-key-here';
$taskId = 'task-unified-1757165031-uyujaw3d';
$baseUrl = 'https://api.poyo.ai';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$baseUrl/api/generate/status/$taskId");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey"
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
$data = $result['data'];
echo "Status: {$data['status']}\n";
echo "Progress: {$data['progress']}%\n";
echo "Credits: {$data['credits_amount']}\n";
if ($data['status'] === 'finished') {
foreach ($data['files'] as $item) {
if (isset($item['file_url'])) {
echo "Generated file: {$item['file_url']}\n";
} else {
echo "Structured result: " . json_encode($item) . "\n";
}
}
} elseif ($data['status'] === 'failed') {
echo "Error: {$data['error_message']}\n";
}
Ruby
require 'net/http'
require 'json'
require 'uri'
api_key = 'your-api-key-here'
task_id = 'task-unified-1757165031-uyujaw3d'
base_url = 'https://api.poyo.ai'
uri = URI("#{base_url}/api/generate/status/#{task_id}")
request = Net::HTTP::Get.new(uri)
request['Authorization'] = "Bearer #{api_key}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
result = JSON.parse(response.body)
data = result['data']
puts "Status: #{data['status']}"
puts "Progress: #{data['progress']}%"
puts "Credits: #{data['credits_amount']}"
if data['status'] == 'finished'
data['files'].each do |item|
if item['file_url']
puts "Generated file: #{item['file_url']}"
else
puts "Structured result: #{JSON.generate(item)}"
end
end
elsif data['status'] == 'failed'
puts "Error: #{data['error_message']}"
end
轮询最佳实践
轮询任务完成状态时,请遵循以下建议:轮询间隔:每 2-5 秒查询一次状态。避免更频繁地轮询,以免触发速率限制。
超时:设置超时以避免无限循环。典型生成耗时:
- 图像:15-60 秒
- 视频:90-300 秒
指数退避:遇到速率限制(429)或服务器错误(5xx)时,使用指数退避(等待 1 秒、2 秒、4 秒、8 秒……)。
完整轮询示例
import requests
import time
import json
API_KEY = "your-api-key-here"
BASE_URL = "https://api.poyo.ai"
def wait_for_completion(task_id, timeout=600, poll_interval=2):
"""
Wait for task completion with timeout
Args:
task_id: Task identifier
timeout: Maximum wait time in seconds
poll_interval: Seconds between checks
Returns:
Task data when complete
Raises:
TimeoutError: If timeout exceeded
RuntimeError: If task failed
"""
start_time = time.time()
headers = {"Authorization": f"Bearer {API_KEY}"}
while True:
# Check timeout
if time.time() - start_time > timeout:
raise TimeoutError(f"Task did not complete within {timeout}s")
# Get status
response = requests.get(
f"{BASE_URL}/api/generate/status/{task_id}",
headers=headers
)
if response.status_code == 429:
# Rate limited - wait longer
time.sleep(poll_interval * 2)
continue
response.raise_for_status()
result = response.json()
data = result["data"]
# Log progress
elapsed = int(time.time() - start_time)
print(f"[{elapsed}s] Status: {data['status']}, Progress: {data['progress']}%")
# Check completion
if data["status"] == "finished":
print(f"✓ Task completed successfully")
return data
elif data["status"] == "failed":
raise RuntimeError(f"Task failed: {data['error_message']}")
time.sleep(poll_interval)
# Usage
try:
task_id = "task-unified-1757165031-uyujaw3d"
result = wait_for_completion(task_id)
for item in result["files"]:
if "file_url" in item:
print(f"Download: {item['file_url']}")
else:
print(f"Structured result: {json.dumps(item)}")
except TimeoutError as e:
print(f"Timeout: {e}")
except RuntimeError as e:
print(f"Error: {e}")
错误响应
HTTP 错误码
| 状态码 | 说明 | 处理方式 |
|---|---|---|
| 401 | Unauthorized | 检查你的 API Key |
| 403 | Forbidden | 任务属于其他用户 |
| 404 | Not Found | 任务 ID 不存在 |
| 429 | Too Many Requests | 降低轮询频率,实现退避 |
| 500 | Server Error | 使用指数退避重试 |
| 502 | Bad Gateway | 服务暂时不可用,请重试 |
错误响应格式
{
"detail": "Task not found"
}
重要说明
内容有效期:生成的图像和视频在创建后 3 天内可访问。请及时下载并保存。
Webhook:对于支持回调的模型,提交任务时可以提供
callback_url 以自动接收通知。Omni Moderation 的回调包含与状态查询相同的 output 对象。参见 Webhook 回调。后续步骤
提交任务
了解如何提交生成任务
图像模型
浏览全部图像模型
视频模型
浏览全部视频模型
快速开始
完整集成指南
授权
所有 API 接口都需要 Bearer Token 认证。
创建 API Key:登录 PoYo,进入 仪表盘 → API 密钥(poyo.ai/zh/dashboard/api-key),点击创建 Key。
在请求头中添加:
Authorization: Bearer YOUR_API_KEY
路径参数
任务唯一标识
响应
成功获取任务状态
Show child attributes
Show child attributes