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

# Understanding Async Task Processing in GlobalAI OPC

> Video and image generation in GlobalAI OPC uses async task processing. Submit a task, receive an ID, then poll for results until completion.

Video and image generation are compute-intensive operations that can take anywhere from a few seconds to several minutes to complete. Rather than making you wait for a synchronous HTTP response that could time out, GlobalAI OPC uses an **asynchronous task model**: you submit a generation request, receive a task ID immediately, and then poll a separate endpoint to check progress until your result is ready.

## How Async Tasks Work

<Steps>
  <Step title="Create a task">
    Send a `POST` request to the appropriate generation endpoint (for example, `/v1/sora/videos` for Sora video generation). The API responds immediately with a task `id` and an initial status of `queued`. Keep this ID — you'll need it to retrieve your result.
  </Step>

  <Step title="Poll for status">
    Send a `GET` request to `/v1/result/{id}` using the task ID you received. Repeat this request on a regular interval (every 30–60 seconds for video, every 2–5 seconds for images) until the status changes from `queued` or `processing` to a terminal state.
  </Step>

  <Step title="Retrieve your result">
    When the status field returns `completed`, the response includes a result URL (for example, `video_url` or `image_url`) containing your generated media. Download or store this URL promptly — result URLs expire after 24 hours.
  </Step>
</Steps>

## Task Statuses

Every task returned by the API carries a `status` field. The following table describes each possible value:

| Status       | Description                                                               |
| ------------ | ------------------------------------------------------------------------- |
| `queued`     | The task is waiting in the queue and has not yet started processing.      |
| `processing` | The task is actively being generated. Continue polling.                   |
| `completed`  | Generation is complete. The result URL is available in the response.      |
| `failed`     | Generation failed. Inspect the `error` field in the response for details. |
| `cancelled`  | The task was cancelled before completion. Applies to Seedance 1.5 tasks.  |

## Polling Best Practices

* **Poll every 30–60 seconds for video generation** to avoid unnecessary API calls while respecting server load.
* **Poll every 2–5 seconds for image generation**, which typically completes much faster than video.
* **Stop polling immediately** when the status is `completed`, `failed`, or `cancelled` — further polling is wasteful and unnecessary.
* **Video URLs expire after 24 hours** — download your generated video to your own storage as soon as generation completes.
* **Image URLs also expire after 24 hours** — save generated images to your own storage rather than relying on the temporary URL long-term.
* **Do not retry on `failed` status** without reviewing the `error` field first; the same prompt or parameters may continue to fail.

## Code Example: Full Polling Loop

The example below creates a video generation task using the Sora model, then polls in a loop until the task completes or fails.

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  API_KEY = "your_api_key"
  BASE_URL = "https://zcbservice.aizfw.cn/kyyReactApiServer"
  HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

  # Create task
  response = requests.post(
      f"{BASE_URL}/v1/sora/videos",
      headers=HEADERS,
      json={
          "model": "openAiSora2Plus",
          "prompt": "A cat dancing in the rain, cinematic style",
          "aspect_ratio": "16:9",
          "seconds": 8
      }
  )
  task_id = response.json()["id"]
  print(f"Task created: {task_id}")

  # Poll for result
  while True:
      result = requests.get(f"{BASE_URL}/v1/result/{task_id}", headers=HEADERS).json()
      status = result["status"]
      print(f"Status: {status}")
      if status == "completed":
          print(f"Video URL: {result['video_url']}")
          break
      elif status == "failed":
          print(f"Failed: {result['error']}")
          break
      elif status == "cancelled":
          print("Task was cancelled.")
          break
      time.sleep(30)
  ```

  ```bash cURL theme={null}
  # Step 1: Create a video generation task
  curl -X POST https://zcbservice.aizfw.cn/kyyReactApiServer/v1/sora/videos \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openAiSora2Plus",
      "prompt": "A cat dancing in the rain, cinematic style",
      "aspect_ratio": "16:9",
      "seconds": 8
    }'

  # The response contains your task ID, e.g.:
  # { "id": "task_abc123", "status": "queued" }

  # Step 2: Poll for the result using the task ID
  # Replace TASK_ID with the id value from the response above
  curl -X GET https://zcbservice.aizfw.cn/kyyReactApiServer/v1/result/TASK_ID \
    -H "Authorization: Bearer YOUR_API_KEY"

  # Keep repeating the GET request every 30–60 seconds until
  # the status field returns "completed" or "failed".
  # On completion, the response will include a "video_url" field.
  ```
</CodeGroup>

<Warning>
  Result URLs (both video and image) expire **24 hours** after generation completes. Download and store your generated media in your own storage immediately after retrieval — you cannot regenerate an expired URL without re-running the full generation task.
</Warning>

<Note>
  Text chat APIs (OpenAI Chat, Claude Messages, and Gemini Native) are **synchronous** — they return the model's response directly in the HTTP response body and do not use the async task pattern described on this page.
</Note>
