> ## Documentation Index
> Fetch the complete documentation index at: https://docs.toapis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Image Task Status

> Query image generation task status and results

> [!NOTE]
>
> **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)

All image generation tasks are executed asynchronously. After submitting a task, you need to query the status and results via the query endpoint.

Ordinary image and video tasks can also be queried with `GET /v1/tasks/{task_id}`, using the same `usage` and `billing` definitions. This page describes responses from the generation-task query path shown above.

Examples illustrate the fields, not current model prices or a fixed billing mode. Use the fields and amounts returned for the actual task.

## Authorizations

**Authorization** `string` *required*

All endpoints require Bearer Token authentication

Get your API Key:

Visit the [API Key Management Page](https://toapis.com/console/token) to get your API Key

Add it to the request header:

```
Authorization: Bearer YOUR_API_KEY
```

## Path Parameters

**task\_id** `string` *required*

Task ID returned by the image generation API

```bash cURL theme={null}
curl --request GET \
  --url 'https://toapis.com/v1/images/generations/task_01KA040M0HP1GJWBJYZMKX1XS1' \
  --header 'Authorization: Bearer <token>'
```

```python Python theme={null}
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']}")
```

```javascript JavaScript theme={null}
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);
});
```

```go Go theme={null}
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)
    }
}
```

```json 200 - In Progress theme={null}
{
  "id": "img_5b8b19afe5c24ab3a92df996f1a33931",
  "object": "generation.task",
  "model": "gemini-3-pro-image-preview",
  "status": "in_progress",
  "progress": 50,
  "created_at": 1768381010,
  "billing": {
    "status": "pending"
  }
}
```

```json 200 - Completed theme={null}
{
  "id": "img_5b8b19afe5c24ab3a92df996f1a33931",
  "object": "generation.task",
  "model": "gemini-3-pro-image-preview",
  "status": "completed",
  "progress": 100,
  "created_at": 1768381010,
  "finished_at": 1768381063,
  "completed_at": 1768381063,
  "expires_at": 1768467463,
  "result": {
    "type": "image",
    "data": [
      {
        "url": "https://files.toapis.com/generated/1768381061_c55c1bbb.jpg"
      }
    ]
  },
  "usage": {
    "charge_type": "per_request",
    "requests": 1
  },
  "billing": {
    "status": "settled",
    "credits": "100",
    "cost_usd": "0.5"
  }
}
```

```json 200 - Failed theme={null}
{
  "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"
  }
}
```

```json 200 - Completed - Free Task with Usage theme={null}
{
  "id": "tsk_img_example",
  "object": "generation.task",
  "model": "gpt-image-2.5-flare-official",
  "status": "completed",
  "progress": 100,
  "created_at": 1789099098,
  "finished_at": 1789099158,
  "completed_at": 1789099158,
  "expires_at": 1789185558,
  "result": {
    "type": "image",
    "data": [
      {
        "url": "https://files.toapis.com/generated/example.png"
      }
    ]
  },
  "usage": {
    "charge_type": "per_token",
    "billed_tokens": 1000,
    "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": "10",
    "cost_usd": "0.05"
  }
}
```

```json 404 theme={null}
{
  "error": {
    "code": 404,
    "message": "Task not found",
    "type": "not_found_error"
  }
}
```

```json 401 theme={null}
{
  "error": {
    "code": 401,
    "message": "Authentication failed, please check your API key",
    "type": "authentication_error"
  }
}
```

## Response

**id** `string`

Unique task identifier

**client\_business\_id** `string`

Optional customer business ID, returned only when `client_business_id` was supplied at task creation.

**object** `string`

Object type, always `generation.task`

**status** `string`

Task status

* `queued` - Queued for processing
* `in_progress` - Processing
* `completed` - Successfully completed
* `failed` - Failed

**progress** `integer`

Integer progress percentage, from 0 to 100.

**model** `string`

Image generation model used

**created\_at** `integer`

Task creation time (Unix timestamp)

**finished\_at** `integer`

Task finish time as a Unix timestamp. This query path returns it for successful or failed tasks when a finish time has been saved.

**completed\_at** `integer`

Task completion time (Unix timestamp, only returned when completed)

**expires\_at** `integer`

Image URL expiration time (Unix timestamp, only returned on completion)

**result** `object`

Task result (only returned on success)

**Properties**

**type** `string`

Result type, always `image`

**data** `array`

Image data array

**Array Elements**

**url** `string`

Generated image URL

**billing** `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.

**Properties**

**status** `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.

**credits** `string`

Platform credits actually charged to the customer, as a decimal string. Returned only for `settled` or `refunded`.

**cost\_usd** `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.

**usage** `object`

Optional billing quantities, image-token details, and tool counts. See [Task usage fields](https://docs.toapis.com/docs/en/api-reference/account/pricing.md) for `charge_type`, `requests`, `billed_tokens`, and related fields. Image-token details are returned only when `billing.status` is `settled` and saved usage is valid and consistent with the final charge. Unconfirmed parts are omitted; confirmed amounts and image results remain available.

| 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.text_or_reasoning_tokens` | integer | Output tokens where text and reasoning share a price and are not split; not counted in `text_tokens`; returned only when present |
| `charge_type` | string | Billing mode: `per_request` or `per_token` |
| `requests` | integer | Billed request count, returned for `per_request`. The request `n` is not multiplied directly |
| `billed_tokens` | integer | Tokens used for pricing, returned for `per_token` |
| `input_images` | integer | Billed input images after the free allowance; omitted when zero |
| `tool_usage.web_search`, `tool_usage.image_search`, `tool_usage.grounding_queries` | integer | Web search, image search, and Grounding query counts, returned when used |

`charge_type`, `requests`, `billed_tokens`, and `input_images` are billing quantities and are returned only together with `billing.status=settled`. Per-request tasks charged once at submission also return `settled` with the actual amount. All token counts are non-negative JSON integers. Cached tokens are a subset of input tokens and must not be added again. `output_tokens_details` is omitted entirely when the breakdown is unavailable. `usage.tool_usage.web_search` may be returned independently or alongside image tokens.

**error** `object`

Error information (only returned on failure)

**Properties**

**code** `string`

Error code

**message** `string`

Error description

## 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 `id` and update its amount; do not sum the same charge on every poll. Use decimal arithmetic. Treat `pending` or 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 `billing` to be omitted. When an image is not yet deliverable and the task is temporarily shown as `in_progress`, both `billing` and `usage` may be omitted.
* A successful Webhook uses the same confirmation rules and field values for `data.usage` and `data.billing` as this endpoint. A Webhook is a snapshot taken when the event is created; if a field is absent, query this endpoint as a fallback. See [Pricing and Actual Charges](https://docs.toapis.com/docs/en/api-reference/account/pricing.md).

## Task Status Reference

| Status | Description | Is Final | Recommended Action |
| - | - | - | - |
| `queued` | 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

```python theme={null}
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

> [!WARNING]
>
> Generated image URLs are valid for **24 hours**
>
> * Please download and save images within the validity period
> * `expires_at` field indicates image expiration time (Unix timestamp)
> * Expired images cannot be accessed; to regenerate, submit a new task

## Errors and failure reasons

See the [error reference](https://docs.toapis.com/docs/en/api-reference/errors.md) for request errors, task failures, specific causes, and recovery guidance. A successful query still requires checking task status; HTTP status is not a business error code.

> [!NOTE]
>
> ToAPIs provides a unified [Task Webhook](https://docs.toapis.com/docs/en/api-reference/webhooks/task-webhooks.md). 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](https://docs.toapis.com/docs/en/api-reference/rate-limits/async-tasks.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.