curl --request GET \
--url 'https://toapis.com/v1/videos/generations/task_01K9S419324DREZFBWNSVXYR6H' \
--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_video_status(task_id):
response = requests.get(f'{API_BASE}/v1/videos/generations/{task_id}', headers=headers)
return response.json()
def wait_for_video(task_id, max_attempts=60, interval=10):
for _ in range(max_attempts):
result = get_video_status(task_id)
status = result.get('status')
progress = result.get('progress', 0)
print(f"Status: {status}, Progress: {progress}%")
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_01K9S419324DREZFBWNSVXYR6H"
result = wait_for_video(task_id)
print(f"Video URL: {result['result']['data'][0]['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getVideoStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/videos/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForVideo(taskId, maxAttempts = 60, interval = 10000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getVideoStatus(taskId);
const status = result.status;
const progress = result.progress || 0;
console.log(`Status: ${status}, Progress: ${progress}%`);
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_01K9S419324DREZFBWNSVXYR6H';
waitForVideo(taskId).then(result => {
console.log('Video URL:', result.result.data[0].url);
console.log('Format:', result.result.data[0].format);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getVideoStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/videos/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_01K9S419324DREZFBWNSVXYR6H"
for i := 0; i < 60; i++ {
result, _ := getVideoStatus(taskId)
status := result["status"].(string)
progress := int(result["progress"].(float64))
fmt.Printf("Status: %s, Progress: %d%%\n", status, progress)
if status == "completed" {
fmt.Println("Video generation completed!")
resultData := result["result"].(map[string]interface{})
dataArray := resultData["data"].([]interface{})
videoData := dataArray[0].(map[string]interface{})
fmt.Println("Video URL:", videoData["url"])
break
}
time.Sleep(10 * time.Second)
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1768380222
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "in_progress",
"progress": 65,
"created_at": 1768380222
}
{
"id": "tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX",
"object": "generation.task",
"model": "seedance-2",
"status": "completed",
"progress": 100,
"created_at": 1778569600,
"finished_at": 1778569900,
"completed_at": 1778569900,
"expires_at": 1778656300,
"result": {
"type": "video",
"data": [
{
"url": "https://files.toapis.com/videos/tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX/********_********.mp4",
"format": "mp4"
}
]
},
"billing": {
"status": "settled",
"credits": "100",
"cost_usd": "0.5"
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "failed",
"progress": 0,
"created_at": 1768380222,
"error": {
"code": "generation_failed",
"message": "Generation failed: Content violates the content policy"
}
}
{
"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"
}
}
{
"id": "task_seedance_example",
"object": "generation.task",
"model": "seedance-2-global",
"client_business_id": "order_123",
"status": "completed",
"progress": 100,
"created_at": 1792400000,
"updated_at": 1792400061,
"finished_at": 1792400060,
"completed_at": 1792400060,
"expires_at": 1792486460,
"result": {
"type": "video",
"data": [
{
"url": "https://cdn.example/result.mp4",
"fallback_url": "https://files.toapis.com/videos/task_seedance_example/result.mp4",
"format": "mp4",
"last_frame_url": "https://cdn.example/last-frame.jpg",
"fallback_last_frame_url": "https://files.toapis.com/videos/task_seedance_example/last-frame.jpg"
}
]
},
"usage": {
"charge_type": "per_token",
"billed_tokens": 87300,
"completion_tokens": 87300,
"total_tokens": 87300
},
"billing": {
"status": "settled",
"credits": "87.3",
"cost_usd": "0.4365"
},
"generation": {
"duration": 5,
"resolution": "720p",
"ratio": "16:9",
"generate_audio": true,
"usage": {
"completion_tokens": 87300,
"total_tokens": 87300
}
}
}
작업 관리
Get Video Task 상태
Query video generation task status and results
GET
/
v1
/
videos
/
generations
/
{task_id}
curl --request GET \
--url 'https://toapis.com/v1/videos/generations/task_01K9S419324DREZFBWNSVXYR6H' \
--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_video_status(task_id):
response = requests.get(f'{API_BASE}/v1/videos/generations/{task_id}', headers=headers)
return response.json()
def wait_for_video(task_id, max_attempts=60, interval=10):
for _ in range(max_attempts):
result = get_video_status(task_id)
status = result.get('status')
progress = result.get('progress', 0)
print(f"Status: {status}, Progress: {progress}%")
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_01K9S419324DREZFBWNSVXYR6H"
result = wait_for_video(task_id)
print(f"Video URL: {result['result']['data'][0]['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getVideoStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/videos/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForVideo(taskId, maxAttempts = 60, interval = 10000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getVideoStatus(taskId);
const status = result.status;
const progress = result.progress || 0;
console.log(`Status: ${status}, Progress: ${progress}%`);
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_01K9S419324DREZFBWNSVXYR6H';
waitForVideo(taskId).then(result => {
console.log('Video URL:', result.result.data[0].url);
console.log('Format:', result.result.data[0].format);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getVideoStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/videos/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_01K9S419324DREZFBWNSVXYR6H"
for i := 0; i < 60; i++ {
result, _ := getVideoStatus(taskId)
status := result["status"].(string)
progress := int(result["progress"].(float64))
fmt.Printf("Status: %s, Progress: %d%%\n", status, progress)
if status == "completed" {
fmt.Println("Video generation completed!")
resultData := result["result"].(map[string]interface{})
dataArray := resultData["data"].([]interface{})
videoData := dataArray[0].(map[string]interface{})
fmt.Println("Video URL:", videoData["url"])
break
}
time.Sleep(10 * time.Second)
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1768380222
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "in_progress",
"progress": 65,
"created_at": 1768380222
}
{
"id": "tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX",
"object": "generation.task",
"model": "seedance-2",
"status": "completed",
"progress": 100,
"created_at": 1778569600,
"finished_at": 1778569900,
"completed_at": 1778569900,
"expires_at": 1778656300,
"result": {
"type": "video",
"data": [
{
"url": "https://files.toapis.com/videos/tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX/********_********.mp4",
"format": "mp4"
}
]
},
"billing": {
"status": "settled",
"credits": "100",
"cost_usd": "0.5"
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "failed",
"progress": 0,
"created_at": 1768380222,
"error": {
"code": "generation_failed",
"message": "Generation failed: Content violates the content policy"
}
}
{
"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"
}
}
{
"id": "task_seedance_example",
"object": "generation.task",
"model": "seedance-2-global",
"client_business_id": "order_123",
"status": "completed",
"progress": 100,
"created_at": 1792400000,
"updated_at": 1792400061,
"finished_at": 1792400060,
"completed_at": 1792400060,
"expires_at": 1792486460,
"result": {
"type": "video",
"data": [
{
"url": "https://cdn.example/result.mp4",
"fallback_url": "https://files.toapis.com/videos/task_seedance_example/result.mp4",
"format": "mp4",
"last_frame_url": "https://cdn.example/last-frame.jpg",
"fallback_last_frame_url": "https://files.toapis.com/videos/task_seedance_example/last-frame.jpg"
}
]
},
"usage": {
"charge_type": "per_token",
"billed_tokens": 87300,
"completion_tokens": 87300,
"total_tokens": 87300
},
"billing": {
"status": "settled",
"credits": "87.3",
"cost_usd": "0.4365"
},
"generation": {
"duration": 5,
"resolution": "720p",
"ratio": "16:9",
"generate_audio": true,
"usage": {
"completion_tokens": 87300,
"total_tokens": 87300
}
}
}
중국 본토 사용자 안내: 중국 본토 사용자는
https://toapis.cn 를 API 엔드포인트(Base URL)로 사용해 주세요. 본 문서의 예시에서 https://toapis.com 을 https://toapis.cn 로 바꿔 주세요.- Query async video generation task execution status and results
- Real-time status updates and progress tracking
- Get generated videos when task completes
- Multi-language support (zh/en/ko/ja)
소재 심사가 필요한 Seedance 동영상 작업도 이 API로 조회합니다.
queued에는 소재 준비와 심사 대기가 포함될 수 있으며, 작업 접수가 생성 시작을 뜻하지는 않습니다. 준비 기한은 기본 라운드당 20분이며 이후 동영상 생성 시간은 별도입니다. 실패 시 error.message를 확인하세요.GET /v1/tasks/{task_id}로도 조회할 수 있으며 usage와 billing의 정의는 같습니다. 이 페이지는 상단에 표시된 생성 작업 조회 경로의 응답을 설명합니다.
예시는 필드 구조를 보여 주며 모델의 현재 가격이나 고정 과금 방식을 나타내지 않습니다. 실제 작업에서 반환된 필드와 금액을 확인하세요.
Seedance 원본 URL과 대체 URL
원본 URL 전달이 활성화된 Seedance 작업에서result.data[].url은 공급자의 원본 동영상 URL을 유지합니다. url을 우선 사용하고 접근할 수 없을 때만 같은 결과 항목의 fallback_url로 전환하세요. 플랫폼은 클라이언트 지역에 따라 URL을 자동 전환하지 않습니다.
대체 필드는 선택 사항이며 사본을 사용할 수 있을 때만 반환됩니다. 원본 URL 전달이 비활성화되었거나 사본을 사용할 수 없거나 이전 작업에 사본이 없으면 생략될 수 있습니다. 생략은 생성 실패를 의미하지 않습니다. 마지막 프레임도 last_frame_url을 우선 사용하고 접근할 수 없을 때만 fallback_last_frame_url을 사용하세요. 대체 URL은 원본 URL의 유효 기간을 연장하지 않습니다. 장기 보관이 필요하면 즉시 다운로드하세요.
Authorizations
string
필수
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 파라미터
string
필수
Task ID returned by the video generation API
curl --request GET \
--url 'https://toapis.com/v1/videos/generations/task_01K9S419324DREZFBWNSVXYR6H' \
--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_video_status(task_id):
response = requests.get(f'{API_BASE}/v1/videos/generations/{task_id}', headers=headers)
return response.json()
def wait_for_video(task_id, max_attempts=60, interval=10):
for _ in range(max_attempts):
result = get_video_status(task_id)
status = result.get('status')
progress = result.get('progress', 0)
print(f"Status: {status}, Progress: {progress}%")
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_01K9S419324DREZFBWNSVXYR6H"
result = wait_for_video(task_id)
print(f"Video URL: {result['result']['data'][0]['url']}")
const API_BASE = 'https://toapis.com';
const API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxx';
async function getVideoStatus(taskId) {
const response = await fetch(`${API_BASE}/v1/videos/generations/${taskId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return response.json();
}
async function waitForVideo(taskId, maxAttempts = 60, interval = 10000) {
for (let i = 0; i < maxAttempts; i++) {
const result = await getVideoStatus(taskId);
const status = result.status;
const progress = result.progress || 0;
console.log(`Status: ${status}, Progress: ${progress}%`);
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_01K9S419324DREZFBWNSVXYR6H';
waitForVideo(taskId).then(result => {
console.log('Video URL:', result.result.data[0].url);
console.log('Format:', result.result.data[0].format);
});
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func getVideoStatus(taskId string) (map[string]interface{}, error) {
url := fmt.Sprintf("https://toapis.com/v1/videos/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_01K9S419324DREZFBWNSVXYR6H"
for i := 0; i < 60; i++ {
result, _ := getVideoStatus(taskId)
status := result["status"].(string)
progress := int(result["progress"].(float64))
fmt.Printf("Status: %s, Progress: %d%%\n", status, progress)
if status == "completed" {
fmt.Println("Video generation completed!")
resultData := result["result"].(map[string]interface{})
dataArray := resultData["data"].([]interface{})
videoData := dataArray[0].(map[string]interface{})
fmt.Println("Video URL:", videoData["url"])
break
}
time.Sleep(10 * time.Second)
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1768380222
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "in_progress",
"progress": 65,
"created_at": 1768380222
}
{
"id": "tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX",
"object": "generation.task",
"model": "seedance-2",
"status": "completed",
"progress": 100,
"created_at": 1778569600,
"finished_at": 1778569900,
"completed_at": 1778569900,
"expires_at": 1778656300,
"result": {
"type": "video",
"data": [
{
"url": "https://files.toapis.com/videos/tsk_vid_01KRDG4S50XXXXXXXXXXXXXXX/********_********.mp4",
"format": "mp4"
}
]
},
"billing": {
"status": "settled",
"credits": "100",
"cost_usd": "0.5"
}
}
{
"id": "video_7497f4d5-3a88-44c7-923a-967fa7d941a0",
"object": "generation.task",
"model": "sora-2",
"status": "failed",
"progress": 0,
"created_at": 1768380222,
"error": {
"code": "generation_failed",
"message": "Generation failed: Content violates the content policy"
}
}
{
"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"
}
}
{
"id": "task_seedance_example",
"object": "generation.task",
"model": "seedance-2-global",
"client_business_id": "order_123",
"status": "completed",
"progress": 100,
"created_at": 1792400000,
"updated_at": 1792400061,
"finished_at": 1792400060,
"completed_at": 1792400060,
"expires_at": 1792486460,
"result": {
"type": "video",
"data": [
{
"url": "https://cdn.example/result.mp4",
"fallback_url": "https://files.toapis.com/videos/task_seedance_example/result.mp4",
"format": "mp4",
"last_frame_url": "https://cdn.example/last-frame.jpg",
"fallback_last_frame_url": "https://files.toapis.com/videos/task_seedance_example/last-frame.jpg"
}
]
},
"usage": {
"charge_type": "per_token",
"billed_tokens": 87300,
"completion_tokens": 87300,
"total_tokens": 87300
},
"billing": {
"status": "settled",
"credits": "87.3",
"cost_usd": "0.4365"
},
"generation": {
"duration": 5,
"resolution": "720p",
"ratio": "16:9",
"generate_audio": true,
"usage": {
"completion_tokens": 87300,
"total_tokens": 87300
}
}
}
응답
string
Unique task identifier
string
선택적 고객 업무 ID입니다. 작업 생성 시
client_business_id를 전달한 경우에만 반환합니다.string
Object type, always
generation.taskstring
Task status
queued- Queued for processingin_progress- Processingcompleted- Successfully completedfailed- Failed
integer
Task progress percentage (0-100)
string
Video generation model used
integer
선택적 플랫폼 작업 갱신 시각, Unix 타임스탬프입니다. 현재 Seedance Global에 반환합니다.
generation.updated_at는 상위 공급자의 갱신 시각입니다.integer
Task creation time (Unix timestamp)
integer
작업 종료 시각, Unix 타임스탬프입니다. 이 조회 경로에서는 성공 또는 실패한 작업에 종료 시각이 저장된 경우 반환합니다.
integer
Task completion time (Unix timestamp, only returned when completed)
integer
Video URL expiration time (Unix timestamp, only returned on completion)
object
Task result (only returned on success)
표시 Properties
표시 Properties
string
Result type, always
videoarray
Video data array
표시 Array item
표시 Array item
string
기본 동영상 URL. 원본 URL 전달이 활성화된 Seedance 작업은 공급자의 원본 URL을 유지합니다. 이 URL을 우선 사용하세요.
string
사본을 사용할 수 있을 때만 반환되는 선택적 대체 동영상 URL. 기본 URL에 접근할 수 없을 때만 사용하며
url을 대체하지 않습니다.string
Video format (for example
mp4)string
생성된 동영상의 마지막 프레임 이미지 URL입니다.
return_last_frame: true로 생성했고 모델이 프레임을 반환한 경우에만 포함됩니다.string
프레임 사본을 사용할 수 있을 때 반환되는 선택적 대체 URL.
last_frame_url에 접근할 수 없을 때만 사용하세요.object
선택적 Seedance 생성 메타데이터입니다. 저장되어 있고 공개 가능한 필드만 반환하며 기본값을 채우지 않습니다. 생성 매개변수이며 최상위
usage의 과금 수량을 대체하지 않습니다.| 필드 | 타입 | 설명 |
|---|---|---|
created_at, updated_at | number | 상위 공급자 작업 생성 및 갱신 시각, Unix 타임스탬프. 최상위 플랫폼 시각과 구분됩니다 |
seed | number | 난수 시드 |
resolution | string | 해상도 |
ratio | string | 화면 비율 |
duration | number | 생성 길이, 초 단위 |
framespersecond | number | 프레임 레이트, 초당 프레임 수 |
service_tier | string | 서비스 등급 |
execution_expires_after | number | 실행 유효 기간, 초 단위 |
generate_audio | boolean | 오디오 생성 여부 |
draft | boolean | 초안 여부 |
priority | number | 스케줄링 우선순위 |
output_format | string | 출력 형식 |
generation.usage는 기존 호환 필드이며 completion_tokens와 total_tokens를 포함할 수 있습니다. 누락되거나 최종 과금 수량과 다를 수 있습니다. 최상위 usage와 합산하지 말고 과금 수량은 최상위 usage를 사용하세요.object
선택적 과금 수량, 동영상 토큰 내역, 도구 사용 횟수입니다. 단위와 생략 조건은 작업 사용량 필드를 참고하세요.
| 필드 | 타입 | 값 |
|---|---|---|
charge_type | string | 과금 방식: per_request, per_second, per_token |
requests | integer | 과금 요청 횟수. per_request일 때 반환합니다. Midjourney 동영상의 유효한 batch_size가 반영됩니다 |
billed_tokens | integer | 가격 계산에 사용한 토큰 수. per_token일 때 반환합니다 |
output_seconds | integer | 과금 대상 출력 동영상 길이, 정수 초 단위. per_second일 때 반환합니다 |
input_seconds | integer | 과금 대상 입력 동영상 길이, 정수 초 단위. 0이면 생략합니다 |
input_images | integer | 무료 한도를 제외하고 과금 대상이 된 입력 이미지 수. 0이면 생략합니다 |
input_tokens, output_tokens, prompt_tokens, completion_tokens, total_tokens | integer | 동영상 모델이 보고한 토큰 수를 그대로 반환합니다. 토큰 과금 정산 시 total_tokens가 채워질 수 있습니다 |
tool_usage | object | 도구 사용 횟수: web_search, image_search, grounding_queries. 사용한 경우에만 반환합니다 |
charge_type부터 input_images까지는 과금 수량이며 billing.status=settled와 함께만 반환합니다. 고정 가격 동영상은 제출 시 확인된 수량을, 실제 길이나 토큰으로 정산하는 동영상은 최종 정산 수량을 반환합니다. 반환하지 않는 필드는 0으로 채우지 않고 생략합니다.object
선택적인 플랫폼 청구 상태와 확정 금액입니다. 과금 상태는 생성 상태와 별개이므로
Task Webhook의
completed여도 정산이 완료되었다고 단정할 수 없습니다. 객체가 없다고 해서 무료인 것은 아닙니다. 가격 및 실제 청구 금액을 참고하세요.표시 속성
표시 속성
string
pending은 생성 중이거나 정산 대기 중이거나 환불이 아직 확인되지 않은 상태이며 금액을 생략합니다. settled는 제출 시 한 번에 과금되는 고정 가격 동영상을 포함해 최종 청구 금액이 확정된 상태이며 실제 금액을 반환합니다. refunded는 환불되었거나 실패 후 순 청구 금액이 없는 것으로 확인된 상태이며 두 금액 모두 "0"입니다.string
실제로 청구된 ToAPIs 크레딧을 십진수 문자열로 반환합니다.
settled 또는 refunded일 때만 반환합니다.string
같은 청구의 USD 금액을 십진수 문자열로 반환합니다.
credits와 같은 조건에서 반환하며 할인과 배율을 포함하고 공급자 원가가 아닙니다.data.billing도 같은 확인 조건과 값을 사용합니다.object
Task 상태 Reference
| 상태 | 설명 | Is Final | Recommended Action |
|---|---|---|---|
queued | Task submitted, waiting in queue | ❌ | Wait 5-10 seconds, then query again |
in_progress | Task is processing | ❌ | Wait 10-15 seconds, then query again |
completed | Task completed successfully | ✅ | Get video from result.data[0].url |
failed | Task processing failed | ✅ | Check error info |
Polling Strategy
Initial wait: 5 seconds
Polling interval: 10 seconds
Max wait: 600 seconds (10 minutes)
Typical time: 1-5 minutes
Python Polling Example
import time
import random
import requests
def poll_video_task(task_id, api_key, max_wait=600):
"""Poll video generation task until completion or timeout"""
start_time = time.time()
interval = 10 # 10 second interval
# Initial 5 second wait
time.sleep(5)
while time.time() - start_time < max_wait:
response = requests.get(
f'https://toapis.com/v1/videos/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, 120)
continue
response.raise_for_status()
data = response.json()
print(f"Status: {data['status']}, Progress: {data.get('progress', 0)}%")
if data['status'] == 'completed':
return {
'url': data['result']['data'][0]['url'],
'format': data['result']['data'][0].get('format'),
'expires_at': data.get('expires_at')
}
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 video URLs are valid for 24 hours
- Please download and save videos within the validity period
expires_atfield indicates video expiration time (Unix timestamp)- Expired videos cannot be accessed; to regenerate, submit a new task
- Thumbnails expire simultaneously with videos
오류와 실패 원인
요청 오류, 작업 실패의 구체적인 원인과 복구 방법은 오류 코드 빠른 참조 를 확인하세요. 조회 성공 후에도 작업 상태를 확인하고 HTTP 상태와 비즈니스 코드를 구분하세요.Performance Tips
Video generation takes longer, recommendations:
- ToAPIs Task Webhook: Webhook을 기본으로, 조회를 대체 경로로 사용
- 조회 간격: 5~10초 이상과 지터. 429는
Retry-After를 읽고 지수 백오프 - Set Timeout: Long videos may take 5-10 minutes, set reasonable timeout
- Download Promptly: Videos expire after 24 hours, save to your storage immediately