curl --request GET \
--url 'https://toapis.com/v1/images/generations/task_01KA040M0HP1GJWBJYZMKX1XS1' \
--header 'Authorization: Bearer <token>'
import requests
import time
API_BASE = 'https://toapis.com'
API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx'
headers = {
'Authorization': f'Bearer {API_KEY}'
}
def get_image_status(task_id):
response = requests.get(f'{API_BASE}/v1/images/generations/{task_id}', headers=headers)
return response.json()
def wait_for_image(task_id, max_attempts=60, interval=3):
for _ in range(max_attempts):
result = get_image_status(task_id)
status = result.get('status')
print(f"Status: {status}")
if status == 'completed':
return result
elif status == 'failed':
raise Exception(f"Task failed: {result}")
time.sleep(interval)
raise Exception("Task timeout")
# Usage example
task_id = "task_01KA040M0HP1GJWBJYZMKX1XS1"
result = wait_for_image(task_id)
print(f"Image URL: {result['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getImageStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/images/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForImage(taskId, maxAttempts = 60, interval = 3000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getImageStatus(taskId);
const status = result.status;
console.log(`Status: ${status}`);
if (status === 'completed') {
return result;
} else if (status === 'failed') {
throw new Error(`Task failed: ${JSON.stringify(result)}`);
}
await new Promise(r => setTimeout(r, interval));
}
throw new Error('Task timeout');
}
// Usage example
const taskId = 'task_01KA040M0HP1GJWBJYZMKX1XS1';
waitForImage(taskId).then(result => {
console.log('Image URL:', result.url);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getImageStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/images/generations/%s", taskId)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer <token>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
func main() {
taskId := "task_01KA040M0HP1GJWBJYZMKX1XS1"
for i := 0; i < 60; i++ {
result, _ := getImageStatus(taskId)
status := result["status"].(string)
fmt.Printf("Status: %s\n", status)
if status == "completed" {
fmt.Println("Image generation completed!")
fmt.Println("Image URL:", result["url"])
break
}
time.Sleep(3 * time.Second)
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "in_progress",
"progress": 50,
"created_at": 1768381010,
"billing": {
"status": "pending"
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "completed",
"progress": 100,
"created_at": 1768381010,
"completed_at": 1768381063,
"expires_at": 1768467463,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/1768381061_c55c1bbb.jpg"
}
]
}
}
{
"id": "img_73c450923a9a43e4aabf426e1c681d64",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "failed",
"progress": 0,
"created_at": 1768215312,
"billing": {
"status": "refunded",
"credits": "0",
"cost_usd": "0"
},
"error": {
"code": "generation_failed",
"message": "call upstream API failed: upstream returned status 422"
}
}
{
"id": "tsk_img_example",
"object": "generation.task",
"model": "gpt-image-2.5-flare-official",
"status": "completed",
"progress": 100,
"created_at": 1789099098,
"completed_at": 1789099158,
"expires_at": 1789185558,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/example.png"
}
]
},
"usage": {
"input_tokens": 100,
"output_tokens": 900,
"total_tokens": 1000,
"input_tokens_details": {
"text_tokens": 20,
"image_tokens": 80,
"cached_tokens": 30,
"cached_tokens_details": {
"text_tokens": 10,
"image_tokens": 20
}
},
"output_tokens_details": {
"text_tokens": 0,
"image_tokens": 900
}
},
"billing": {
"status": "settled",
"credits": "0",
"cost_usd": "0"
}
}
{
"error": {
"code": 404,
"message": "Task not found",
"type": "not_found_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
Task Management
Get Image Task Status
Query image generation task status and results
GET
/
v1
/
images
/
generations
/
{task_id}
curl --request GET \
--url 'https://toapis.com/v1/images/generations/task_01KA040M0HP1GJWBJYZMKX1XS1' \
--header 'Authorization: Bearer <token>'
import requests
import time
API_BASE = 'https://toapis.com'
API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx'
headers = {
'Authorization': f'Bearer {API_KEY}'
}
def get_image_status(task_id):
response = requests.get(f'{API_BASE}/v1/images/generations/{task_id}', headers=headers)
return response.json()
def wait_for_image(task_id, max_attempts=60, interval=3):
for _ in range(max_attempts):
result = get_image_status(task_id)
status = result.get('status')
print(f"Status: {status}")
if status == 'completed':
return result
elif status == 'failed':
raise Exception(f"Task failed: {result}")
time.sleep(interval)
raise Exception("Task timeout")
# Usage example
task_id = "task_01KA040M0HP1GJWBJYZMKX1XS1"
result = wait_for_image(task_id)
print(f"Image URL: {result['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getImageStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/images/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForImage(taskId, maxAttempts = 60, interval = 3000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getImageStatus(taskId);
const status = result.status;
console.log(`Status: ${status}`);
if (status === 'completed') {
return result;
} else if (status === 'failed') {
throw new Error(`Task failed: ${JSON.stringify(result)}`);
}
await new Promise(r => setTimeout(r, interval));
}
throw new Error('Task timeout');
}
// Usage example
const taskId = 'task_01KA040M0HP1GJWBJYZMKX1XS1';
waitForImage(taskId).then(result => {
console.log('Image URL:', result.url);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getImageStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/images/generations/%s", taskId)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer <token>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
func main() {
taskId := "task_01KA040M0HP1GJWBJYZMKX1XS1"
for i := 0; i < 60; i++ {
result, _ := getImageStatus(taskId)
status := result["status"].(string)
fmt.Printf("Status: %s\n", status)
if status == "completed" {
fmt.Println("Image generation completed!")
fmt.Println("Image URL:", result["url"])
break
}
time.Sleep(3 * time.Second)
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "in_progress",
"progress": 50,
"created_at": 1768381010,
"billing": {
"status": "pending"
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "completed",
"progress": 100,
"created_at": 1768381010,
"completed_at": 1768381063,
"expires_at": 1768467463,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/1768381061_c55c1bbb.jpg"
}
]
}
}
{
"id": "img_73c450923a9a43e4aabf426e1c681d64",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "failed",
"progress": 0,
"created_at": 1768215312,
"billing": {
"status": "refunded",
"credits": "0",
"cost_usd": "0"
},
"error": {
"code": "generation_failed",
"message": "call upstream API failed: upstream returned status 422"
}
}
{
"id": "tsk_img_example",
"object": "generation.task",
"model": "gpt-image-2.5-flare-official",
"status": "completed",
"progress": 100,
"created_at": 1789099098,
"completed_at": 1789099158,
"expires_at": 1789185558,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/example.png"
}
]
},
"usage": {
"input_tokens": 100,
"output_tokens": 900,
"total_tokens": 1000,
"input_tokens_details": {
"text_tokens": 20,
"image_tokens": 80,
"cached_tokens": 30,
"cached_tokens_details": {
"text_tokens": 10,
"image_tokens": 20
}
},
"output_tokens_details": {
"text_tokens": 0,
"image_tokens": 900
}
},
"billing": {
"status": "settled",
"credits": "0",
"cost_usd": "0"
}
}
{
"error": {
"code": 404,
"message": "Task not found",
"type": "not_found_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
Note for users in mainland China: Please use
https://toapis.cn as the API endpoint (Base URL). Replace https://toapis.com with https://toapis.cn in the examples in this document.- Query async image generation task execution status and results
- Real-time status updates and progress tracking
- Get generated images when task completes
- Multi-language support (zh/en/ko/ja)
Authorizations
string
required
All endpoints require Bearer Token authenticationGet your API Key:Visit the API Key Management Page to get your API KeyAdd it to the request header:
Authorization: Bearer YOUR_API_KEY
Path Parameters
string
required
Task ID returned by the image generation API
curl --request GET \
--url 'https://toapis.com/v1/images/generations/task_01KA040M0HP1GJWBJYZMKX1XS1' \
--header 'Authorization: Bearer <token>'
import requests
import time
API_BASE = 'https://toapis.com'
API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx'
headers = {
'Authorization': f'Bearer {API_KEY}'
}
def get_image_status(task_id):
response = requests.get(f'{API_BASE}/v1/images/generations/{task_id}', headers=headers)
return response.json()
def wait_for_image(task_id, max_attempts=60, interval=3):
for _ in range(max_attempts):
result = get_image_status(task_id)
status = result.get('status')
print(f"Status: {status}")
if status == 'completed':
return result
elif status == 'failed':
raise Exception(f"Task failed: {result}")
time.sleep(interval)
raise Exception("Task timeout")
# Usage example
task_id = "task_01KA040M0HP1GJWBJYZMKX1XS1"
result = wait_for_image(task_id)
print(f"Image URL: {result['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getImageStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/images/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForImage(taskId, maxAttempts = 60, interval = 3000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getImageStatus(taskId);
const status = result.status;
console.log(`Status: ${status}`);
if (status === 'completed') {
return result;
} else if (status === 'failed') {
throw new Error(`Task failed: ${JSON.stringify(result)}`);
}
await new Promise(r => setTimeout(r, interval));
}
throw new Error('Task timeout');
}
// Usage example
const taskId = 'task_01KA040M0HP1GJWBJYZMKX1XS1';
waitForImage(taskId).then(result => {
console.log('Image URL:', result.url);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getImageStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/images/generations/%s", taskId)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer <token>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
func main() {
taskId := "task_01KA040M0HP1GJWBJYZMKX1XS1"
for i := 0; i < 60; i++ {
result, _ := getImageStatus(taskId)
status := result["status"].(string)
fmt.Printf("Status: %s\n", status)
if status == "completed" {
fmt.Println("Image generation completed!")
fmt.Println("Image URL:", result["url"])
break
}
time.Sleep(3 * time.Second)
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "in_progress",
"progress": 50,
"created_at": 1768381010,
"billing": {
"status": "pending"
}
}
{
"id": "img_5b8b19afe5c24ab3a92df996f1a33931",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "completed",
"progress": 100,
"created_at": 1768381010,
"completed_at": 1768381063,
"expires_at": 1768467463,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/1768381061_c55c1bbb.jpg"
}
]
}
}
{
"id": "img_73c450923a9a43e4aabf426e1c681d64",
"object": "generation.task",
"model": "gemini-3-pro-image-preview",
"status": "failed",
"progress": 0,
"created_at": 1768215312,
"billing": {
"status": "refunded",
"credits": "0",
"cost_usd": "0"
},
"error": {
"code": "generation_failed",
"message": "call upstream API failed: upstream returned status 422"
}
}
{
"id": "tsk_img_example",
"object": "generation.task",
"model": "gpt-image-2.5-flare-official",
"status": "completed",
"progress": 100,
"created_at": 1789099098,
"completed_at": 1789099158,
"expires_at": 1789185558,
"result": {
"type": "image",
"data": [
{
"url": "https://files.toapis.com/generated/example.png"
}
]
},
"usage": {
"input_tokens": 100,
"output_tokens": 900,
"total_tokens": 1000,
"input_tokens_details": {
"text_tokens": 20,
"image_tokens": 80,
"cached_tokens": 30,
"cached_tokens_details": {
"text_tokens": 10,
"image_tokens": 20
}
},
"output_tokens_details": {
"text_tokens": 0,
"image_tokens": 900
}
},
"billing": {
"status": "settled",
"credits": "0",
"cost_usd": "0"
}
}
{
"error": {
"code": 404,
"message": "Task not found",
"type": "not_found_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
Response
string
Unique task identifier
string
Object type, always
generation.taskstring
Task status
queued- Queued for processingin_progress- Processingcompleted- Successfully completedfailed- Failed
string
Image generation model used
integer
Task creation time (Unix timestamp)
integer
Task completion time (Unix timestamp, only returned when completed)
string
Generated image URL (only returned on success)
integer
Image URL expiration time (Unix timestamp, only returned on completion)
object
object
Optional image-task billing information. Billing status is independent of generation status:
completed does not guarantee settlement. If billing data cannot be confirmed, the entire billing field is omitted, not returned as null. Omission does not mean the task was free.Show Properties
Show Properties
string
pending means settlement or a refund is not yet confirmed; amounts are omitted. settled means the final charge is confirmed. refunded means a refund or no net charge after failure is confirmed, including failure before any charge.string
Platform credits actually charged to the customer, as a decimal string. Returned only for
settled or refunded.string
USD actually charged to the customer, as a decimal string. Includes the discounts and multipliers applied when the task was billed; it is not the provider’s cost.
object
Optional settled image-token usage. Image-token fields are returned only when
All token counts are non-negative JSON integers. Cached tokens are a subset of input tokens and must not be added again.
billing.status is settled and the saved usage is valid and matches the final charge. Missing or invalid usage is omitted, not estimated or replaced with zeros. Confirmed amounts and image results can still be returned.| Field | Type | Description |
|---|---|---|
input_tokens | integer | Total input tokens, including text and images |
output_tokens | integer | Total output tokens |
total_tokens | integer | input_tokens + output_tokens |
input_tokens_details.text_tokens | integer | Text input tokens |
input_tokens_details.image_tokens | integer | Image input tokens |
input_tokens_details.cached_tokens | integer | Cached input tokens, already included in the input total |
input_tokens_details.cached_tokens_details.text_tokens | integer | Cached text input tokens |
input_tokens_details.cached_tokens_details.image_tokens | integer | Cached image input tokens |
output_tokens_details.text_tokens | integer | Text output tokens; returned only when output details are available |
output_tokens_details.image_tokens | integer | Image output tokens; returned only when output details are available |
output_tokens_details is omitted entirely when the breakdown is unavailable. usage.tool_usage.web_search may be returned independently or alongside image tokens.object
Billing Status and Spend Tracking
These billing rules apply to image-task queries across models and channels. GPT-Image-2.5 Sunburst and Flare VIP / Official variants provide token usage when settlement data is available; other models depend on their recorded settlement data. Example amounts illustrate the response format, not a fixed price.| billing.status | Meaning | Amounts and image tokens |
|---|---|---|
pending | Generation, settlement, or refund confirmation is pending | Amounts and image tokens omitted; a preauthorization is not final spend |
settled | Final charge confirmed | Amounts returned; image tokens returned when valid usage is available. Free tasks may also return "0" |
refunded | Refund or no net charge after failure confirmed | Both credits and cost_usd are "0"; image tokens omitted |
- Amounts reflect the task’s confirmed final charge. Querying does not charge, add charges, refund, or recalculate using current model prices. Use the returned amounts for accounting instead of multiplying tokens by current prices.
- Deduplicate by task
idand update its amount; do not sum the same charge on every poll. Use decimal arithmetic. Treatpendingor missing fields as unknown spend, not zero. - Amounts use decimal strings with no fixed number of decimal places.
- Missing or inconsistent billing records can cause
billingto be omitted. When an image is not yet deliverable and the task is temporarily shown asin_progress, bothbillingandusagemay be omitted. - A successful Webhook may include the same image-token fields in
data.usageand may include confirmed charges indata.billing. If either field is absent, query this endpoint as a fallback. See Pricing and Actual Charges.
Task Status Reference
| Status | Description | Is Final | Recommended Action |
|---|---|---|---|
submitted | Task submitted, waiting for processing | ❌ | Wait at least 5–10 seconds with jitter |
in_progress | Task is processing | ❌ | Wait at least 5–10 seconds with jitter |
completed | Task completed successfully | ✅ | Get image from url field |
failed | Task processing failed | ✅ | Check error info |
Polling Strategy
Initial wait: 5 seconds
Polling interval: at least 5–10 seconds with random jitter
Max wait: 120 seconds
Typical time: 5-30 seconds
Python Polling Example
import time
import random
import requests
def poll_image_task(task_id, api_key, max_wait=120):
"""Poll image generation task until completion or timeout"""
start_time = time.time()
interval = 5
while time.time() - start_time < max_wait:
response = requests.get(
f'https://toapis.com/v1/images/generations/{task_id}',
headers={'Authorization': f'Bearer {api_key}'}
)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', interval))
time.sleep(retry_after + random.uniform(0, 1))
interval = min(interval * 2, 60)
continue
response.raise_for_status()
data = response.json()
if data['status'] == 'completed':
return data['url']
elif data['status'] == 'failed':
raise Exception(f"Generation failed: {data['error']['message']}")
time.sleep(interval + random.uniform(0, 1))
raise TimeoutError("Task timeout")
Resource Expiration
Generated image URLs are valid for 24 hours
- Please download and save images within the validity period
expires_atfield indicates image expiration time (Unix timestamp)- Expired images cannot be accessed; to regenerate, submit a new task
Error Codes
| HTTP Code | Error Type | Description |
|---|---|---|
| 400 | invalid_request | Invalid request parameters |
| 401 | unauthorized | Authentication failed, check API Key |
| 402 | insufficient_quota | Insufficient balance |
| 404 | task_not_found | Task not found |
| 422 | content_policy_violation | Content policy violation |
| 429 | rate_limit_exceeded | Rate limit exceeded |
| 500 | internal_error | Internal server error |
ToAPIs provides a unified Task Webhook. Prefer callbacks and use polling as fallback. Poll every 5–10 seconds or slower with jitter and honor
Retry-After on 429. Batch queries accept at most 100 task IDs; see rate limits.