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

# 비디오 상태 가져오기

> 비디오 생성 작업의 상태와 결과를 가져옵니다

## 경로 매개변수

<ParamField path="id" type="string" required>
  비디오 생성 요청에서 반환된 작업 ID입니다. `id`와 `task_id`는 동일한 비동기 식별자로 취급하세요.
</ParamField>

<Info>
  생성 응답이 `poll_url`을 반환하면 해당 URL을 정확히 호출하세요. 그것이 `/v1/tasks/{id}`를 가리킬 때, 이를 정식 고정 상태 엔드포인트로 간주하세요.

  작업이 더 이상 존재하지 않거나 공개 비동기 작업 계약을 통해 더 이상 확인할 수 없는 경우, TokenLab는 `async_task_not_found`를 반환하며 메시지는 `Task not found or no longer available.`입니다.
</Info>

## 응답

<ResponseField name="id" type="string">
  정식 비동기 작업 식별자.
</ResponseField>

<ResponseField name="task_id" type="string">
  비동기 작업 식별자 별칭.
</ResponseField>

<ResponseField name="poll_url" type="string">
  생성 응답에서 제공하는 경우 권장 폴링 URL입니다.
</ResponseField>

<ResponseField name="billing_transaction_id" type="string">
  정산이 이미 완료된 경우 반환되는 TokenLab 청구 거래 ID입니다. dashboard / 정산에 사용하는 거래 식별자이며 비동기 `id` / `task_id` 와는 별개입니다.
</ResponseField>

<ResponseField name="status" type="string">
  작업 상태: `pending`, `processing`, `completed`, `failed`.
</ResponseField>

<ResponseField name="progress" type="number">
  선택적 진행 값입니다. 실제 진행 값이 제공될 때만 반환됩니다. 완료 여부는 `status` 로 판단하세요.
</ResponseField>

<ResponseField name="video_url" type="string">
  생성된 비디오의 URL(완료 시).
</ResponseField>

<ResponseField name="video" type="object">
  사용 가능한 경우 `url`, `duration`, `width`, 및 `height`를 포함한 단일 비디오 페이로드.
</ResponseField>

<ResponseField name="videos" type="array">
  생성 작업이 여러 출력을 반환할 때의 다중 비디오 페이로드.
</ResponseField>

<ResponseField name="error" type="string">
  오류 메시지(실패한 경우).
</ResponseField>

<ResponseField name="created" type="integer">
  생성 타임스탬프.
</ResponseField>

<ResponseField name="updated" type="integer">
  최종 업데이트 타임스탬프.
</ResponseField>

<ResponseField name="model" type="string">
  작업에 사용된 모델.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.tokenlab.sh/v1/tasks/ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
    -H "Authorization: Bearer sk-your-api-key"
  ```

  ```python Python theme={null}
  import requests
  import time

  task_id = "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

  while True:
      response = requests.get(
          f"https://api.tokenlab.sh/v1/tasks/{task_id}",
          headers={"Authorization": "Bearer sk-your-api-key"}
      )

      data = response.json()
      print(f"Status: {data['status']}")

      if data["status"] == "completed":
          print(f"Video URL: {data['video_url']}")
          break
      elif data["status"] == "failed":
          print(f"Error: {data['error']}")
          break

      time.sleep(5)  # Poll every 5 seconds
  ```

  ```javascript JavaScript theme={null}
  const taskId = 'ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';

  async function pollForVideo() {
    while (true) {
      const response = await fetch(
        `https://api.tokenlab.sh/v1/tasks/${taskId}`,
        { headers: { 'Authorization': 'Bearer sk-your-api-key' } }
      );

      const data = await response.json();
      console.log(`Status: ${data.status}`);

      if (data.status === 'completed') {
        console.log(`Video URL: ${data.video_url}`);
        return data.video_url;
      } else if (data.status === 'failed') {
        throw new Error(data.error);
      }

      await new Promise(r => setTimeout(r, 5000));
    }
  }
  ```

  ```go Go theme={null}
  package main

  import (
      "encoding/json"
      "fmt"
      "net/http"
      "time"
  )

  func main() {
      taskID := "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

      for {
          req, _ := http.NewRequest("GET",
              fmt.Sprintf("https://api.tokenlab.sh/v1/tasks/%s", taskID), nil)
          req.Header.Set("Authorization", "Bearer sk-your-api-key")

          client := &http.Client{}
          resp, _ := client.Do(req)

          var result map[string]interface{}
          json.NewDecoder(resp.Body).Decode(&result)
          resp.Body.Close()

          fmt.Printf("Status: %s\n", result["status"])

          if result["status"] == "completed" {
              fmt.Printf("Video URL: %s\n", result["video_url"])
              break
          } else if result["status"] == "failed" {
              fmt.Printf("Error: %s\n", result["error"])
              break
          }

          time.Sleep(5 * time.Second)
      }
  }
  ```

  ```php PHP theme={null}
  <?php
  $taskId = 'ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';

  while (true) {
      $ch = curl_init("https://api.tokenlab.sh/v1/tasks/{$taskId}");

      curl_setopt_array($ch, [
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_HTTPHEADER => [
              'Authorization: Bearer sk-your-api-key'
          ]
      ]);

      $response = curl_exec($ch);
      curl_close($ch);

      $data = json_decode($response, true);
      echo "Status: {$data['status']}\n";

      if ($data['status'] === 'completed') {
          echo "Video URL: {$data['video_url']}\n";
          break;
      } elseif ($data['status'] === 'failed') {
          echo "Error: {$data['error']}\n";
          break;
      }

      sleep(5);
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Response (pending) theme={null}
  {
    "id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "task_id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "poll_url": "/v1/tasks/ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "status": "pending",
    "model": "veo3.1",
    "created": 1706000000,
    "updated": 1706000000
  }
  ```

  ```json Response (processing) theme={null}
  {
    "id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "task_id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "poll_url": "/v1/tasks/ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "status": "processing",
    "model": "veo3.1",
    "created": 1706000000,
    "updated": 1706000030
  }
  ```

  ```json Response (completed) theme={null}
  {
    "id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "task_id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "poll_url": "/v1/tasks/ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "billing_transaction_id": "cmo164zyc0s48jpgegi80vqv4",
    "status": "completed",
    "video_url": "https://assets.tokenlab.sh/videos/abc123.mp4",
    "model": "veo3.1",
    "created": 1706000000,
    "updated": 1706000060
  }
  ```

  ```json Response (failed) theme={null}
  {
    "id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "task_id": "ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "poll_url": "/v1/tasks/ldtask_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "status": "failed",
    "error": "Content policy violation",
    "model": "veo3.1",
    "created": 1706000000,
    "updated": 1706000060
  }
  ```
</ResponseExample>

## 폴링 모범 사례

* 5-10초마다 폴링하세요
* 장기 작업에는 지수 백오프를 구현하세요
* 최대 타임아웃을 설정하세요(예: 10분)
* `failed` 상태를 적절히 처리하세요

```python theme={null}
import time

def wait_for_video(task_id, max_wait=600, interval=5):
    """Wait for video with timeout."""
    start = time.time()

    while time.time() - start < max_wait:
        response = requests.get(
            f"https://api.tokenlab.sh/v1/tasks/{task_id}",
            headers={"Authorization": "Bearer sk-your-api-key"}
        )
        data = response.json()

        if data["status"] == "completed":
            return data["video_url"]
        elif data["status"] == "failed":
            raise Exception(data.get("error", "Video generation failed"))

        time.sleep(interval)

    raise TimeoutError("Video generation timed out")
```
