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

# Sora 2 视频生成（异步）

> Sora 2 异步视频生成 API - 完整的三步流程：提交请求、轮询状态、下载视频

## 概述

Sora 2 异步 API 采用标准的异步处理机制，适合需要更精细控制视频生成流程的场景。与同步流式 API 不同，异步 API 将视频生成分为三个独立步骤，让您可以更灵活地管理任务状态和下载时机。

<Info>
  异步 API 特别适合批量处理、后台任务、以及需要长时间等待的场景。如果您需要实时进度反馈，建议使用[同步流式 API](/api-capabilities/sora-2-video)。
</Info>

## 核心特性

<CardGroup cols={2}>
  <Card title="独立的任务管理" icon="list-check">
    提交后获得任务 ID，可随时查询状态
  </Card>

  <Card title="灵活的轮询策略" icon="refresh-cw">
    自定义轮询间隔，避免不必要的请求
  </Card>

  <Card title="可靠的视频下载" icon="download">
    生成完成后独立下载，支持断点续传
  </Card>

  <Card title="批量处理支持" icon="layers">
    同时提交多个任务，并发处理更高效
  </Card>
</CardGroup>

## 完整流程

异步 API 采用三步流程：

```
第一步：提交请求
POST /v1/videos
↓
返回 video_id

第二步：轮询状态（建议每 30 秒）
GET /v1/videos/{video_id}
↓
submitted → in_progress → completed

第三步：下载视频
GET /v1/videos/{video_id}/content
↓
保存 MP4 文件
```

<Note>
  典型生成时间：3-5 分钟。建议轮询间隔设置为 30 秒，最长等待时间设置为 10 分钟。
</Note>

## 模型定价

| 模型名                         | 描述        | 分辨率                     | 价格       | 稳定性    |
| --------------------------- | --------- | ----------------------- | -------- | ------ |
| `sora_video2`               | 默认竖屏版本    | 720 × 1280              | \$0.12/次 | 高      |
| `sora_video2-landscape`     | 横屏版本      | 1280 × 720              | \$0.12/次 | 高      |
| `sora_video2-15s`           | 竖屏15s 视频  | 720 × 1280              | \$0.12/次 | 高      |
| `sora_video2-landscape-15s` | 横屏 15s 视频 | 1280 × 720              | \$0.12/次 | 高      |
| `sora-2-pro`                | Pro账号版本   | 1024 × 1792,1792 × 1024 | \$0.8/次  | 正常可用了！ |

<Note>
  * 推荐异步调用，各种错误而不计费；
  * 若同步调用，则支持流式输出查看进度；
  * 视频存储时效为 1 天，请及时转存或下载；
  * sora 2 普通版本的分辨率输出其实为 704 px（而非 720 px），是官方的实际表现；
</Note>

## 端点地址

```
https://api.apiyi.com/v1/videos
```

## 第一步：提交视频生成请求

### 请求参数

| 参数                | 类型     | 必填 | 说明                             |
| ----------------- | ------ | -- | ------------------------------ |
| `prompt`          | string | ✅  | 视频生成的文本描述，建议详细描述场景、动作、风格       |
| `model`           | string | ✅  | 固定值：`sora-2`                   |
| `size`            | string | ✅  | `1280x720`（横屏）或 `720x1280`（竖屏） |
| `seconds`         | string | ✅  | 视频时长，可选值：`10` 或 `15`           |
| `input_reference` | file   | ❌  | 参考图片文件（PNG/JPG/JPEG），可选，用于图生视频 |

### 文生视频示例

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.apiyi.com/v1/videos" \
    -H "Content-Type: multipart/form-data" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "model=sora-2" \
    -F "prompt=一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天" \
    -F "size=1280x720" \
    -F "seconds=10"
  ```

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

  BASE_URL = "https://api.apiyi.com/v1/videos"
  API_KEY = "YOUR_API_KEY"

  # 提交文生视频请求
  files = {
      'prompt': (None, '一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天'),
      'model': (None, 'sora-2'),
      'size': (None, '1280x720'),
      'seconds': (None, '10')
  }

  headers = {
      'Accept': 'application/json',
      'Authorization': API_KEY
  }

  response = requests.post(BASE_URL, headers=headers, files=files)
  result = response.json()
  video_id = result['id']

  print(f"视频ID: {video_id}")
  print(f"状态: {result['status']}")
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios');
  const FormData = require('form-data');

  const BASE_URL = 'https://api.apiyi.com/v1/videos';
  const API_KEY = 'YOUR_API_KEY';

  async function submitRequest() {
      const formData = new FormData();
      formData.append('prompt', '一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天');
      formData.append('model', 'sora-2');
      formData.append('size', '1280x720');
      formData.append('seconds', '10');

      const response = await axios.post(BASE_URL, formData, {
          headers: {
              ...formData.getHeaders(),
              'Authorization': API_KEY
          }
      });

      const videoId = response.data.id;
      console.log(`视频ID: ${videoId}`);
      console.log(`状态: ${response.data.status}`);
      return videoId;
  }

  submitRequest();
  ```
</CodeGroup>

### 图生视频示例

支持上传参考图片，生成基于图片的视频。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.apiyi.com/v1/videos" \
    -H "Content-Type: multipart/form-data" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "model=sora-2" \
    -F "prompt=参考配图，使得动物们活跃起来，在场地里绕场一周的追逐" \
    -F "size=1280x720" \
    -F "seconds=10" \
    -F "input_reference=@/path/to/image.png"
  ```

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

  BASE_URL = "https://api.apiyi.com/v1/videos"
  API_KEY = "YOUR_API_KEY"

  # 提交图生视频请求
  with open('/path/to/image.png', 'rb') as f:
      files = {
          'prompt': (None, '参考配图，使得动物们活跃起来，在场地里绕场一周的追逐'),
          'model': (None, 'sora-2'),
          'size': (None, '1280x720'),
          'seconds': (None, '10'),
          'input_reference': ('image.png', f, 'image/png')
      }

      headers = {
          'Accept': 'application/json',
          'Authorization': API_KEY
      }

      response = requests.post(BASE_URL, headers=headers, files=files)
      result = response.json()
      video_id = result['id']

      print(f"视频ID: {video_id}")
  ```
</CodeGroup>

### 响应格式

```json theme={null}
{
  "id": "video_abc123def456",
  "status": "submitted",
  "progress": 0,
  "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天",
  "model": "sora-2",
  "size": "1280x720",
  "seconds": "10",
  "created_at": 1704067200,
  "url": null,
  "completed_at": null
}
```

## 第二步：轮询查询视频状态

提交请求后，需要定期轮询查询视频生成状态。

### 请求方式

```bash theme={null}
GET /v1/videos/{video_id}
```

### 查询示例

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.apiyi.com/v1/videos/video_abc123def456" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

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

  BASE_URL = "https://api.apiyi.com/v1/videos"
  API_KEY = "YOUR_API_KEY"
  POLL_INTERVAL = 30  # 30 秒查询一次
  MAX_WAIT_TIME = 600  # 最长等待 10 分钟

  def poll_status(video_id):
      headers = {'Authorization': API_KEY}
      status_url = f"{BASE_URL}/{video_id}"
      start_time = time.time()

      while True:
          elapsed_time = time.time() - start_time

          # 检查超时
          if elapsed_time > MAX_WAIT_TIME:
              print(f"超时：已等待 {MAX_WAIT_TIME} 秒")
              return False

          # 查询状态
          response = requests.get(status_url, headers=headers)
          result = response.json()
          status = result.get('status')
          progress = result.get('progress', 0)

          print(f"状态: {status}, 进度: {progress}%")

          if status == 'completed':
              print(f"视频生成完成! URL: {result.get('url')}")
              return True
          elif status == 'failed':
              print(f"视频生成失败")
              return False
          elif status in ['submitted', 'in_progress']:
              print(f"生成中，等待 {POLL_INTERVAL} 秒后继续查询...")
              time.sleep(POLL_INTERVAL)
          else:
              print(f"未知状态: {status}")
              time.sleep(POLL_INTERVAL)

  # 使用示例
  poll_status("video_abc123def456")
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios');

  const BASE_URL = 'https://api.apiyi.com/v1/videos';
  const API_KEY = 'YOUR_API_KEY';
  const POLL_INTERVAL = 30000; // 30 秒
  const MAX_WAIT_TIME = 600000; // 10 分钟

  async function pollStatus(videoId) {
      const startTime = Date.now();

      while (true) {
          const elapsedTime = Date.now() - startTime;

          // 检查超时
          if (elapsedTime > MAX_WAIT_TIME) {
              console.log('超时：已等待 10 分钟');
              return false;
          }

          // 查询状态
          const response = await axios.get(`${BASE_URL}/${videoId}`, {
              headers: { 'Authorization': API_KEY }
          });

          const { status, progress, url } = response.data;
          console.log(`状态: ${status}, 进度: ${progress}%`);

          if (status === 'completed') {
              console.log(`视频生成完成! URL: ${url}`);
              return true;
          } else if (status === 'failed') {
              console.log('视频生成失败');
              return false;
          }

          // 等待后继续
          await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL));
      }
  }

  // 使用示例
  pollStatus('video_abc123def456');
  ```
</CodeGroup>

### 状态说明

| 状态            | 说明         | 下一步操作           |
| ------------- | ---------- | --------------- |
| `submitted`   | 请求已提交，等待处理 | 继续轮询查询          |
| `in_progress` | 视频生成中      | 继续轮询查询，可查看进度百分比 |
| `completed`   | 视频生成完成     | 可以下载视频          |
| `failed`      | 视频生成失败     | 检查错误信息，重新提交     |

### 生成中的响应示例

```json theme={null}
{
  "id": "video_abc123def456",
  "status": "in_progress",
  "progress": 45,
  "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天",
  "model": "sora-2",
  "size": "1280x720",
  "seconds": "10",
  "created_at": 1704067200,
  "url": null,
  "completed_at": null
}
```

### 完成后的响应示例

```json theme={null}
{
  "id": "video_abc123def456",
  "status": "completed",
  "progress": 100,
  "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘，阳光明媚，背景是绿树和蓝天",
  "model": "sora-2",
  "size": "1280x720",
  "seconds": "10",
  "created_at": 1704067200,
  "url": "https://api.apiyi.com/v1/videos/video_abc123def456/content",
  "completed_at": 1704067500
}
```

## 第三步：下载生成的视频

视频生成完成后（`status` 为 `completed`），可以下载视频文件。

### 请求方式

```bash theme={null}
GET /v1/videos/{video_id}/content
```

### 下载示例

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.apiyi.com/v1/videos/video_abc123def456/content" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -o video.mp4
  ```

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

  BASE_URL = "https://api.apiyi.com/v1/videos"
  API_KEY = "YOUR_API_KEY"

  def download_video(video_id, output_path='video.mp4'):
      headers = {'Authorization': API_KEY}
      content_url = f"{BASE_URL}/{video_id}/content"

      print(f"开始下载视频...")
      response = requests.get(content_url, headers=headers, stream=True)

      if response.status_code == 200:
          # 获取文件大小
          total_size = int(response.headers.get('content-length', 0))

          with open(output_path, 'wb') as f:
              if total_size == 0:
                  f.write(response.content)
              else:
                  downloaded = 0
                  for chunk in response.iter_content(chunk_size=8192):
                      if chunk:
                          f.write(chunk)
                          downloaded += len(chunk)
                          percent = (downloaded / total_size) * 100
                          print(f"\r下载进度: {percent:.1f}%", end='')

          print(f"\n视频下载成功! 保存到: {output_path}")
          print(f"文件大小: {total_size} 字节")
          return True
      else:
          print(f"下载失败: {response.status_code}")
          print(f"响应: {response.text}")
          return False

  # 使用示例
  download_video("video_abc123def456", "my_video.mp4")
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios');
  const fs = require('fs');

  const BASE_URL = 'https://api.apiyi.com/v1/videos';
  const API_KEY = 'YOUR_API_KEY';

  async function downloadVideo(videoId, outputPath = 'video.mp4') {
      const contentUrl = `${BASE_URL}/${videoId}/content`;

      console.log('开始下载视频...');

      const response = await axios.get(contentUrl, {
          headers: { 'Authorization': API_KEY },
          responseType: 'stream'
      });

      const writer = fs.createWriteStream(outputPath);
      response.data.pipe(writer);

      return new Promise((resolve, reject) => {
          writer.on('finish', () => {
              console.log(`视频下载成功! 保存到: ${outputPath}`);
              resolve();
          });
          writer.on('error', reject);
      });
  }

  // 使用示例
  downloadVideo('video_abc123def456', 'my_video.mp4');
  ```
</CodeGroup>

<Warning>
  视频文件可能在一段时间后过期，建议生成完成后立即下载并保存到本地。
</Warning>

## 完整流程示例

以下是完整的三步流程集成示例：

<CodeGroup>
  ```python Python 完整流程 theme={null}
  import requests
  import time
  import os
  from datetime import datetime

  # API 配置
  BASE_URL = "https://api.apiyi.com/v1/videos"
  API_KEY = "YOUR_API_KEY"

  # 参数配置
  IMAGE_PATH = './dog-and-cat.png'  # 参考图片路径，设为 None 则为文生视频
  PROMPT = '参考配图，使得动物们活跃起来，在场地里绕场一周的追逐'
  MODEL = 'sora-2'
  SIZE = '1280x720'
  SECONDS = '10'

  # 轮询配置
  POLL_INTERVAL = 30
  MAX_WAIT_TIME = 600


  def step1_submit_request():
      """第一步：提交视频生成请求"""
      print("=" * 60)
      print("第一步：提交视频生成请求")
      print("=" * 60)

      files = {
          'prompt': (None, PROMPT),
          'model': (None, MODEL),
          'size': (None, SIZE),
          'seconds': (None, SECONDS)
      }

      headers = {
          'Accept': 'application/json',
          'Authorization': API_KEY
      }

      # 如果有图片，添加到请求中
      if IMAGE_PATH and os.path.exists(IMAGE_PATH):
          print(f"模式：图片生成视频")
          print(f"图片: {IMAGE_PATH}")
          with open(IMAGE_PATH, 'rb') as f:
              files['input_reference'] = (
                  os.path.basename(IMAGE_PATH),
                  f,
                  'image/png'
              )
              response = requests.post(BASE_URL, headers=headers, files=files)
      else:
          print(f"模式：文字生成视频")
          response = requests.post(BASE_URL, headers=headers, files=files)

      if response.status_code == 200:
          result = response.json()
          video_id = result.get('id')
          print(f"✅ 请求提交成功!")
          print(f"   视频ID: {video_id}")
          print(f"   状态: {result.get('status')}")
          print(f"   预计生成时间: 3-5 分钟")
          return video_id
      else:
          print(f"❌ 请求失败: {response.status_code}")
          print(f"   响应: {response.text}")
          return None


  def step2_poll_status(video_id):
      """第二步：轮询查询视频生成状态"""
      print("\n" + "=" * 60)
      print("第二步：查询视频生成状态")
      print("=" * 60)

      headers = {'Authorization': API_KEY}
      status_url = f"{BASE_URL}/{video_id}"
      start_time = time.time()

      while True:
          elapsed_time = time.time() - start_time

          if elapsed_time > MAX_WAIT_TIME:
              print(f"⏱️ 超时：已等待 {MAX_WAIT_TIME} 秒")
              return False

          response = requests.get(status_url, headers=headers)

          if response.status_code == 200:
              result = response.json()
              status = result.get('status')
              progress = result.get('progress', 0)

              print(f"\n🔍 查询状态... (已等待 {int(elapsed_time)} 秒)")
              print(f"   状态: {status}")
              print(f"   进度: {progress}%")

              if status == 'completed':
                  print(f"✅ 视频生成完成!")
                  print(f"   视频URL: {result.get('url')}")
                  return True
              elif status == 'failed':
                  print(f"❌ 视频生成失败")
                  return False
              else:
                  print(f"⏳ 等待 {POLL_INTERVAL} 秒后继续查询...")
                  time.sleep(POLL_INTERVAL)
          else:
              print(f"❌ 状态查询失败: {response.status_code}")
              time.sleep(POLL_INTERVAL)


  def step3_download_video(video_id, output_path=None):
      """第三步：下载生成的视频"""
      print("\n" + "=" * 60)
      print("第三步：下载视频")
      print("=" * 60)

      if output_path is None:
          output_path = f"sora_video_{video_id.split('_')[-1]}.mp4"

      headers = {'Authorization': API_KEY}
      content_url = f"{BASE_URL}/{video_id}/content"

      print(f"📥 开始下载视频...")
      response = requests.get(content_url, headers=headers, stream=True)

      if response.status_code == 200:
          total_size = int(response.headers.get('content-length', 0))

          with open(output_path, 'wb') as f:
              if total_size == 0:
                  f.write(response.content)
              else:
                  downloaded = 0
                  for chunk in response.iter_content(chunk_size=8192):
                      if chunk:
                          f.write(chunk)
                          downloaded += len(chunk)
                          percent = (downloaded / total_size) * 100
                          print(f"\r   下载进度: {percent:.1f}%", end='')

          print(f"\n✅ 视频下载成功!")
          print(f"   保存路径: {os.path.abspath(output_path)}")
          print(f"   文件大小: {os.path.getsize(output_path)} 字节")
          return True
      else:
          print(f"❌ 下载失败: {response.status_code}")
          return False


  def main():
      """完整的异步流程"""
      print("\n🎬 开始 Sora-2 视频生成完整流程")
      print(f"⏰ 开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")

      # 第一步：提交请求
      video_id = step1_submit_request()
      if not video_id:
          print("\n❌ 流程终止：视频请求提交失败")
          return

      # 第二步：轮询状态
      success = step2_poll_status(video_id)
      if not success:
          print("\n❌ 流程终止：视频生成未完成")
          return

      # 第三步：下载视频
      success = step3_download_video(video_id)

      if success:
          print("\n" + "=" * 60)
          print("🎉 完整流程执行成功!")
          print("=" * 60)
          print(f"⏰ 结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")


  if __name__ == "__main__":
      main()
  ```

  ```bash Bash 完整流程 theme={null}
  #!/bin/bash

  # API 配置
  API_KEY="YOUR_API_KEY"
  BASE_URL="https://api.apiyi.com/v1/videos"

  # 参数配置
  IMAGE_PATH="./dog-and-cat.png"
  PROMPT="参考配图,使得动物们活跃起来,在场地里绕场一周的追逐"
  MODEL="sora-2"
  SIZE="1280x720"
  SECONDS="10"

  # 轮询配置
  POLL_INTERVAL=30
  MAX_WAIT_TIME=600

  echo "=============================="
  echo "第一步：提交视频生成请求"
  echo "=============================="

  # 提交请求
  if [ -f "$IMAGE_PATH" ]; then
      echo "模式：图片生成视频"
      response=$(curl -s -X POST "$BASE_URL" \
          -H "Content-Type: multipart/form-data" \
          -H "Authorization: Bearer $API_KEY" \
          -F "model=$MODEL" \
          -F "prompt=$PROMPT" \
          -F "size=$SIZE" \
          -F "seconds=$SECONDS" \
          -F "input_reference=@$IMAGE_PATH")
  else
      echo "模式：文字生成视频"
      response=$(curl -s -X POST "$BASE_URL" \
          -H "Content-Type: multipart/form-data" \
          -H "Authorization: Bearer $API_KEY" \
          -F "model=$MODEL" \
          -F "prompt=$PROMPT" \
          -F "size=$SIZE" \
          -F "seconds=$SECONDS")
  fi

  # 提取 video_id
  video_id=$(echo "$response" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)

  if [ -z "$video_id" ]; then
      echo "❌ 请求失败"
      exit 1
  fi

  echo "✅ 请求提交成功!"
  echo "   视频ID: $video_id"

  echo ""
  echo "=============================="
  echo "第二步：查询视频生成状态"
  echo "=============================="

  # 轮询状态
  start_time=$(date +%s)
  while true; do
      current_time=$(date +%s)
      elapsed=$((current_time - start_time))

      if [ $elapsed -gt $MAX_WAIT_TIME ]; then
          echo "⏱️ 超时：已等待 $MAX_WAIT_TIME 秒"
          exit 1
      fi

      response=$(curl -s -X GET "$BASE_URL/$video_id" \
          -H "Authorization: Bearer $API_KEY")

      status=$(echo "$response" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
      progress=$(echo "$response" | grep -o '"progress":[0-9]*' | cut -d':' -f2)

      echo "🔍 状态: $status, 进度: $progress% (已等待 $elapsed 秒)"

      if [ "$status" = "completed" ]; then
          echo "✅ 视频生成完成!"
          break
      elif [ "$status" = "failed" ]; then
          echo "❌ 视频生成失败"
          exit 1
      fi

      sleep $POLL_INTERVAL
  done

  echo ""
  echo "=============================="
  echo "第三步：下载视频"
  echo "=============================="

  # 下载视频
  output_file="sora_video_${video_id##*_}.mp4"
  echo "📥 开始下载视频..."

  curl -X GET "$BASE_URL/$video_id/content" \
      -H "Authorization: Bearer $API_KEY" \
      -o "$output_file"

  if [ -f "$output_file" ]; then
      file_size=$(ls -lh "$output_file" | awk '{print $5}')
      echo "✅ 视频下载成功!"
      echo "   保存路径: $(pwd)/$output_file"
      echo "   文件大小: $file_size"
  else
      echo "❌ 下载失败"
      exit 1
  fi

  echo ""
  echo "=============================="
  echo "🎉 完整流程执行成功!"
  echo "=============================="
  ```
</CodeGroup>

## 最佳实践

### Prompt 编写建议

<Tip>
  好的 Prompt 应该包含：场景描述、主体动作、镜头风格、艺术风格。
</Tip>

**优秀示例**：

```
一只可爱的金毛犬在绿色草地上追逐红色飞盘，阳光明媚，
背景是蓝天白云和绿树，运动流畅，特写镜头跟随犬的动作，
电影级画质，暖色调
```

**不佳示例**：

```
狗追飞盘
```

### 参考图片建议

* **分辨率**：建议 1280x720 或更高
* **格式**：PNG 或 JPG
* **文件大小**：\< 10MB
* **内容**：清晰、主体明确、光线良好
* **匹配度**：图片内容应与 prompt 描述相关

### 轮询策略建议

<CardGroup cols={2}>
  <Card title="推荐设置" icon="check">
    * 轮询间隔：30 秒
    * 最长等待：10 分钟（600 秒）
    * 典型耗时：3-5 分钟
  </Card>

  <Card title="避免设置" icon="x">
    * 轮询间隔：\< 30 秒（可能触发限流）
    * 最长等待：\< 5 分钟（可能提前放弃）
  </Card>
</CardGroup>

### 错误重试策略

```python theme={null}
import time

def retry_with_backoff(func, max_retries=3):
    """指数退避重试策略"""
    for i in range(max_retries):
        try:
            return func()
        except Exception as e:
            if i == max_retries - 1:
                raise
            wait_time = 2 ** i  # 1s, 2s, 4s
            print(f"重试 {i+1}/{max_retries}，等待 {wait_time} 秒...")
            time.sleep(wait_time)
```

## 配额和限制

| 限制项       | 值          | 说明            |
| --------- | ---------- | ------------- |
| 请求速率      | 10 次/分钟    | 超过会返回 429 错误  |
| 并发任务      | 5 个        | 同时处理的视频数量     |
| 视频时长      | 10 或 15 秒  | 不支持其他时长       |
| 图片大小      | \< 10MB    | 建议 \< 5MB     |
| Prompt 长度 | \< 1000 字符 | 建议 100-300 字符 |

## 错误处理

### 常见错误码

| 状态码 | 说明     | 解决方案                 |
| --- | ------ | -------------------- |
| 200 | 成功     | -                    |
| 400 | 请求参数错误 | 检查必填参数是否完整           |
| 401 | 认证失败   | 检查 API Key 是否正确      |
| 403 | 无权限    | 检查 API Key 是否有效或余额不足 |
| 404 | 资源不存在  | 检查 video\_id 是否正确    |
| 429 | 请求过于频繁 | 增加轮询间隔               |
| 500 | 服务器错误  | 稍后重试                 |

## 常见问题

<AccordionGroup>
  <Accordion title="视频生成需要多长时间？">
    通常需要 3-5 分钟，具体时间取决于服务器负载和视频复杂度。建议设置轮询间隔为 30 秒，最长等待时间为 10 分钟。
  </Accordion>

  <Accordion title="异步 API 和同步 API 有什么区别？">
    * **异步 API**：三步流程（提交→轮询→下载），适合批量处理和后台任务，需要自己管理轮询逻辑
    * **同步 API**：流式输出，实时返回进度，适合需要即时反馈的场景

    详见：[同步流式 API 文档](/api-capabilities/sora-2-video)
  </Accordion>

  <Accordion title="可以同时提交多个视频生成任务吗？">
    可以，支持最多 50 个并发任务（不够用可以联系技术客服加）。您可以同时提交多个请求，分别轮询它们的状态。注意不要超过请求速率限制（10 次/分钟）。
  </Accordion>

  <Accordion title="视频文件会保存多久？">
    建议视频生成完成后立即下载，避免文件过期。具体保存时长请咨询技术支持。
  </Accordion>

  <Accordion title="生成失败如何处理？">
    检查响应中的错误信息，常见原因：

    * 内容违规（修改 prompt 或更换图片）
    * 配额不足（充值或升级套餐）
    * 参数错误（检查参数格式和值）
    * 服务器负载过高（稍后重试）
  </Accordion>

  <Accordion title="如何控制视频的横竖屏？">
    通过 `size` 参数控制：

    * `1280x720`：横屏
    * `720x1280`：竖屏
  </Accordion>
</AccordionGroup>

## 相关资源

<CardGroup cols={2}>
  <Card title="同步流式 API" icon="bolt" href="/api-capabilities/sora-2-video">
    实时进度反馈，适合交互式应用
  </Card>

  <Card title="API 基础手册" icon="code" href="/api-manual">
    了解 API 认证、请求格式等基础知识
  </Card>

  <Card title="常见问题 FAQ" icon="circle-question" href="/faq/model-selection-guide">
    查看更多常见问题解答
  </Card>
</CardGroup>
