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

# Async API (Temporarily Unavailable)

> The Veo-3.1 asynchronous video API has been temporarily unavailable since May 14, 2026; this page is kept for historical task-queue examples and pre-recovery troubleshooting.

<Warning>
  **Veo-3.1 legacy route incident notice**

  The `veo-3.1` series legacy route began experiencing failures on May 14, 2026 and is temporarily unavailable. Pause new async video tasks from the examples on this page until recovery is announced on this site or in the console.
</Warning>

<Info>
  **Async Endpoint:** `https://api2.laozhang.ai/v1/videos`

  **Workflow:** Three steps (Create Task → Query Status → Get Video)

  **Advantages:** More Stable | Task Queue | Long Tasks Support | No Charge on Failure
</Info>

## Why Choose Async API?

<CardGroup cols={2}>
  <Card title="Higher Stability" icon="shield-check">
    Based on task queue, avoids long connection timeout issues
  </Card>

  <Card title="No Charge on Failure ⭐" icon="badge-dollar-sign">
    **Major Advantage**: No charge for any failure

    * ✓ Content violation → No charge
    * ✓ Queue timeout → No charge
    * ✓ Generation failed → No charge

    Sync API charges as long as request succeeds (HTTP 200), even if generation fails!
  </Card>

  <Card title="Flexible Polling" icon="refresh-ccw">
    Query task status and progress anytime
  </Card>

  <Card title="Batch Processing" icon="layers">
    Suitable for batch generation and background tasks
  </Card>
</CardGroup>

## Sync vs Async Comparison

| Feature               | Sync API                            | Async API (Recommended)      |
| --------------------- | ----------------------------------- | ---------------------------- |
| **Workflow**          | Single request waits for completion | Create task then poll        |
| **Endpoint**          | `/v1/chat/completions`              | `/v1/videos`                 |
| **Model Selection**   | Via model parameter                 | Via model parameter          |
| **Image-to-Video**    | Supports URL and Base64             | Supports URL                 |
| **Charge on Failure** | Charges even if generation fails    | ⭐ No charge on failure       |
| **Stability**         | Depends on long connections         | ⭐⭐⭐⭐⭐ More stable            |
| **Progress View**     | Streaming output                    | Poll progress percentage     |
| **Timeout Handling**  | Needs long timeout                  | Tasks run independently      |
| **Use Cases**         | Quick testing, real-time feedback   | Production, batch generation |

<Tip>
  **Recommend using Async API**, especially in production environments or when batch generating videos for better stability.
</Tip>

## Quick Start

Async workflow consists of three steps:

<Steps>
  <Step title="Create Video Task">
    POST request to create task, get task ID
  </Step>

  <Step title="Query Task Status">
    Periodically poll for generation progress
  </Step>

  <Step title="Download Video">
    Get video file after task completes
  </Step>
</Steps>

### Complete Example

<CodeGroup>
  ```bash Step 1: Create Task (Text-to-Video) theme={null}
  curl -X POST "https://api2.laozhang.ai/v1/videos" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "veo-3.1",
      "prompt": "A cute cat playing with a ball in a sunny garden"
    }'

  # Response example
  {
    "id": "video_abc123",
    "object": "video",
    "created": 1762181811,
    "status": "queued",
    "model": "veo-3.1"
  }
  ```

  ```bash Step 1: Create Task (Image-to-Video - Single Image) theme={null}
  # Note: Use multipart/form-data for image uploads
  curl -X POST "https://api2.laozhang.ai/v1/videos" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: multipart/form-data" \
    -F "model=veo-3.1-fl" \
    -F "prompt=Make this cat blink slowly" \
    -F "input_reference=@original_image.jpg"

  # Response example
  {
    "id": "video_def456",
    "object": "video",
    "created": 1762181822,
    "status": "queued",
    "model": "veo-3.1-fl"
  }
  ```

  ```bash Step 1: Create Task (Image-to-Video - First/Last Frame) theme={null}
  # Use two images as first and last frames for smooth transition video
  curl -X POST "https://api2.laozhang.ai/v1/videos" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: multipart/form-data" \
    -F "model=veo-3.1-landscape-fl" \
    -F "prompt=Animate this scene with futuristic tech effects" \
    -F "input_reference=@start_frame.jpg" \
    -F "input_reference=@end_frame.jpg"

  # Response example
  {
    "id": "video_xyz789",
    "object": "video",
    "created": 1762181833,
    "status": "queued",
    "model": "veo-3.1-landscape-fl"
  }
  ```

  ```bash Step 2: Query Status theme={null}
  curl -X GET "https://api2.laozhang.ai/v1/videos/video_abc123" \
    -H "Authorization: Bearer YOUR_API_KEY"

  # In-progress response
  {
    "id": "video_abc123",
    "object": "video",
    "model": "veo-3.1",
    "status": "processing",
    "created": 1762181811
  }

  # Completed response
  {
    "id": "video_abc123",
    "object": "video",
    "model": "veo-3.1",
    "status": "completed",
    "prompt": "A cute cat playing with a ball in a sunny garden",
    "created": 1762181811
  }
  ```

  ```bash Step 3: Get Video theme={null}
  curl -X GET "https://api2.laozhang.ai/v1/videos/video_abc123/content" \
    -H "Authorization: Bearer YOUR_API_KEY"

  # Response example
  {
    "id": "video_abc123",
    "object": "video",
    "created": 1762181811,
    "status": "completed",
    "model": "veo-3.1",
    "prompt": "A cute cat playing with a ball in a sunny garden",
    "url": "https://veo-video.example.com/assets/xxx.mp4",
    "duration": 8,
    "resolution": "720x1280"
  }
  ```
</CodeGroup>

## API Endpoints

### 1. Create Video Task

<Info>
  **POST** `https://api2.laozhang.ai/v1/videos`

  Create a new video generation task
</Info>

#### Request Parameters

| Parameter         | Type   | Required | Description                                                                               |
| ----------------- | ------ | -------- | ----------------------------------------------------------------------------------------- |
| `model`           | string | ✓        | Model name (see model list below)                                                         |
| `prompt`          | string | ✓        | Video generation prompt                                                                   |
| `input_reference` | file   | ❌        | Image file, supports 1-2 images (2 images for first/last frame mode, multipart/form-data) |

#### Available Models

| Model Name                  | Aspect    | Speed    | Image-to-Video | Price          |
| --------------------------- | --------- | -------- | -------------- | -------------- |
| `veo-3.1`                   | Portrait  | Standard | ❌              | \$0.25/request |
| `veo-3.1-fl`                | Portrait  | Standard | ✅              | \$0.25/request |
| `veo-3.1-fast`              | Portrait  | Fast     | ❌              | \$0.15/request |
| `veo-3.1-fast-fl`           | Portrait  | Fast     | ✅              | \$0.15/request |
| `veo-3.1-landscape`         | Landscape | Standard | ❌              | \$0.25/request |
| `veo-3.1-landscape-fl`      | Landscape | Standard | ✅              | \$0.25/request |
| `veo-3.1-landscape-fast`    | Landscape | Fast     | ❌              | \$0.15/request |
| `veo-3.1-landscape-fast-fl` | Landscape | Fast     | ✅              | \$0.15/request |

<Note>
  **Model Naming Convention:**

  * `landscape` = Landscape (16:9)
  * `fast` = Fast version
  * `fl` = Supports frame-to-video (image-to-video)
</Note>

<Tip>
  **First/Last Frame Feature**

  Image-to-video models (with `-fl` suffix) support uploading 2 images:

  * **First image**: Video start frame
  * **Second image**: Video end frame

  The API will automatically generate a smooth transition animation from start frame to end frame.
</Tip>

#### Response Fields

| Field     | Type    | Description                                   |
| --------- | ------- | --------------------------------------------- |
| `id`      | string  | Unique task identifier for subsequent queries |
| `object`  | string  | Fixed as `"video"`                            |
| `model`   | string  | Model used                                    |
| `status`  | string  | Task status: `"queued"`                       |
| `created` | integer | Creation timestamp                            |

### 2. Query Task Status

<Info>
  **GET** `https://api2.laozhang.ai/v1/videos/{video_id}`

  Query the current status of a video generation task
</Info>

#### Path Parameters

| Parameter  | Type   | Required | Description                         |
| ---------- | ------ | -------- | ----------------------------------- |
| `video_id` | string | ✓        | Task ID returned when creating task |

#### Response Fields

| Field     | Type    | Description             |
| --------- | ------- | ----------------------- |
| `id`      | string  | Task ID                 |
| `object`  | string  | Fixed as `"video"`      |
| `model`   | string  | Model used              |
| `status`  | string  | Task status (see below) |
| `prompt`  | string  | Original prompt         |
| `created` | integer | Creation timestamp      |

#### Task Status Description

| Status       | Description         | Next Action               |
| ------------ | ------------------- | ------------------------- |
| `queued`     | Task queued         | Continue polling          |
| `processing` | Generating          | Continue polling          |
| `completed`  | Generation complete | Call get content endpoint |
| `failed`     | Generation failed   | Check error message       |

### 3. Get Video Content

<Info>
  **GET** `https://api2.laozhang.ai/v1/videos/{video_id}/content`

  Get the actual content of a completed video
</Info>

#### Path Parameters

| Parameter  | Type   | Required | Description |
| ---------- | ------ | -------- | ----------- |
| `video_id` | string | ✓        | Task ID     |

#### Response Fields

| Field        | Type    | Description              |
| ------------ | ------- | ------------------------ |
| `id`         | string  | Task ID                  |
| `object`     | string  | Fixed as `"video"`       |
| `status`     | string  | Task status              |
| `model`      | string  | Model used               |
| `prompt`     | string  | Original prompt          |
| `url`        | string  | Video download URL       |
| `duration`   | integer | Video duration (seconds) |
| `resolution` | string  | Video resolution         |
| `created`    | integer | Creation timestamp       |

<Warning>
  **Important**

  Video URLs are typically valid for **24 hours**. Please download and save locally promptly!
</Warning>

## Complete Code Examples

### Python Example (with Polling Logic)

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

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api2.laozhang.ai/v1"

# Step 1: Create video task
def create_video_task(prompt, model="veo-3.1", image_paths=None):
    """Create video generation task

    Args:
        prompt: Video generation prompt
        model: Model name
        image_paths: Image path(s), can be:
            - None: Text-to-video
            - str: Single image path
            - list: Multiple image paths (first/last frame mode, max 2)
    """
    url = f"{BASE_URL}/videos"
    headers = {"Authorization": f"Bearer {API_KEY}"}

    if image_paths:
        # Convert to list for uniform handling
        if isinstance(image_paths, str):
            image_paths = [image_paths]

        # Image-to-Video: Use multipart/form-data to upload images
        files = []
        for path in image_paths:
            if not os.path.exists(path):
                raise FileNotFoundError(f"Image file not found: {path}")
            files.append(("input_reference", (os.path.basename(path), open(path, 'rb'), "image/jpeg")))

        data = {"model": model, "prompt": prompt}
        response = requests.post(url, headers=headers, files=files, data=data)

        # Close file handles
        for _, (_, f, _) in files:
            f.close()
    else:
        # Text-to-Video: Use JSON format
        headers["Content-Type"] = "application/json"
        data = {"model": model, "prompt": prompt}
        response = requests.post(url, headers=headers, json=data)

    response.raise_for_status()
    return response.json()

# Step 2: Poll for status
def wait_for_video(video_id, poll_interval=5, timeout=600):
    """Wait for video generation to complete"""
    url = f"{BASE_URL}/videos/{video_id}"
    headers = {"Authorization": f"Bearer {API_KEY}"}
    start_time = time.time()

    while True:
        # Check timeout
        if time.time() - start_time > timeout:
            raise TimeoutError(f"Video generation timeout ({timeout}s)")

        # Query status
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        task = response.json()

        status = task["status"]
        print(f"Status: {status}")

        if status == "completed":
            return task
        elif status == "failed":
            raise Exception("Generation failed")

        # Wait and retry
        time.sleep(poll_interval)

# Step 3: Get video content
def get_video_content(video_id):
    """Get video content and URL"""
    url = f"{BASE_URL}/videos/{video_id}/content"
    headers = {"Authorization": f"Bearer {API_KEY}"}

    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()

# Step 4: Download video
def download_video(video_url, save_path="video.mp4"):
    """Download video file"""
    response = requests.get(video_url, stream=True)
    response.raise_for_status()

    with open(save_path, 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            if chunk:
                f.write(chunk)

    print(f"Video saved to: {save_path}")

# Complete workflow
def generate_video_async(prompt, model="veo-3.1"):
    """Complete async video generation workflow"""
    print("1. Creating video task...")
    task = create_video_task(prompt, model)
    video_id = task["id"]
    print(f"   Task ID: {video_id}")

    print("\n2. Waiting for video generation...")
    completed_task = wait_for_video(video_id)
    print("   Generation complete!")

    print("\n3. Getting video content...")
    content = get_video_content(video_id)
    video_url = content["url"]
    print(f"   Video URL: {video_url}")

    print("\n4. Downloading video...")
    download_video(video_url)
    print("\n✅ Done!")

# Usage example
if __name__ == "__main__":
    # Text-to-video - Portrait standard
    # Text-to-video - Portrait standard
    generate_video_async(
        prompt="A cute cat playing with a ball in a sunny garden",
        model="veo-3.1"
    )

    # Image-to-Video - Single image mode
    # task = create_video_task(
    #     prompt="Make this cat blink slowly",
    #     model="veo-3.1-fl",
    #     image_paths="test.jpg"
    # )

    # Image-to-Video - First/Last frame mode (2 images)
    # First image = start frame, Second image = end frame
    # task = create_video_task(
    #     prompt="Smoothly transition from start to end frame with dynamic effects",
    #     model="veo-3.1-landscape-fl",
    #     image_paths=["start_frame.jpg", "end_frame.jpg"]
    # )
```

### JavaScript/Node.js Example

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

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api2.laozhang.ai/v1';

// Create video task
async function createVideoTask(prompt, model = 'veo-3.1') {
  const response = await axios.post(`${BASE_URL}/videos`, {
    model,
    prompt
  }, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  return response.data;
}

// Poll for status
async function waitForVideo(videoId, pollInterval = 5000, timeout = 600000) {
  const startTime = Date.now();

  while (true) {
    // Check timeout
    if (Date.now() - startTime > timeout) {
      throw new Error(`Video generation timeout (${timeout/1000}s)`);
    }

    // Query status
    const response = await axios.get(`${BASE_URL}/videos/${videoId}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    });

    const task = response.data;
    const { status } = task;

    console.log(`Status: ${status}`);

    if (status === 'completed') {
      return task;
    } else if (status === 'failed') {
      throw new Error('Generation failed');
    }

    // Wait and retry
    await new Promise(resolve => setTimeout(resolve, pollInterval));
  }
}

// Get video content
async function getVideoContent(videoId) {
  const response = await axios.get(`${BASE_URL}/videos/${videoId}/content`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  return response.data;
}

// Download video
async function downloadVideo(videoUrl, savePath = 'video.mp4') {
  const response = await axios.get(videoUrl, { responseType: 'stream' });

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

  return new Promise((resolve, reject) => {
    writer.on('finish', () => {
      console.log(`Video saved to: ${savePath}`);
      resolve();
    });
    writer.on('error', reject);
  });
}

// Complete workflow
async function generateVideoAsync(prompt, model = 'veo-3.1') {
  try {
    console.log('1. Creating video task...');
    const task = await createVideoTask(prompt, model);
    const videoId = task.id;
    console.log(`   Task ID: ${videoId}`);

    console.log('\n2. Waiting for video generation...');
    await waitForVideo(videoId);
    console.log('   Generation complete!');

    console.log('\n3. Getting video content...');
    const content = await getVideoContent(videoId);
    const videoUrl = content.url;
    console.log(`   Video URL: ${videoUrl}`);

    console.log('\n4. Downloading video...');
    await downloadVideo(videoUrl);
    console.log('\n✅ Done!');

  } catch (error) {
    console.error('Error:', error.message);
  }
}

// Usage example
generateVideoAsync(
  'A cute cat playing with a ball in a sunny garden',
  'veo-3.1'
);
```

## Best Practices

<AccordionGroup>
  <Accordion title="Polling Interval Settings" icon="timer">
    **Recommended polling interval: 5-10 seconds**

    ```python theme={null}
    # Recommended
    poll_interval = 5  # Query every 5 seconds

    # Not recommended
    poll_interval = 1  # Too frequent, wastes requests
    poll_interval = 30 # Too slow, poor user experience
    ```

    **Reasons:**

    * Video generation typically takes 2-5 minutes
    * 5-10 seconds provides timely feedback
    * Avoids excessive requests
  </Accordion>

  <Accordion title="Timeout Handling" icon="timer">
    **Recommended timeout: 10 minutes (600 seconds)**

    ```python theme={null}
    def wait_for_video(video_id, timeout=600):
        start_time = time.time()

        while True:
            if time.time() - start_time > timeout:
                # Handle timeout
                print(f"Task {video_id} timed out, can query later")
                break

            # Query logic...
    ```

    **Note:**

    * Task timeout doesn't auto-cancel
    * Can continue querying the same video\_id later
    * Tasks are valid for 24 hours
  </Accordion>

  <Accordion title="Error Retry Strategy" icon="refresh-cw">
    **Recommended retry logic:**

    ```python theme={null}
    def create_video_with_retry(prompt, model, max_retries=3):
        for i in range(max_retries):
            try:
                return create_video_task(prompt, model)
            except Exception as e:
                if i < max_retries - 1:
                    print(f"Creation failed, retrying in 5s... ({i+1}/{max_retries})")
                    time.sleep(5)
                else:
                    raise
    ```

    **Retry scenarios:**

    * ✓ Network error → Retry
    * ✓ Service busy (503) → Retry
    * ✗ Content violation → Don't retry, modify prompt
    * ✗ Insufficient balance → Don't retry, confirm account credit first
  </Accordion>

  <Accordion title="Batch Generation Optimization" icon="list">
    **Concurrency control suggestions:**

    ```python theme={null}
    import concurrent.futures

    def batch_generate_videos(prompts, model="veo-3.1", max_workers=5):
        """Batch generate videos with concurrency control"""
        with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
            # Create all tasks
            future_to_prompt = {
                executor.submit(create_video_task, prompt, model): prompt
                for prompt in prompts
            }

            video_ids = []
            for future in concurrent.futures.as_completed(future_to_prompt):
                task = future.result()
                video_ids.append(task['id'])

            # Wait for all tasks concurrently
            futures = [executor.submit(wait_for_video, vid) for vid in video_ids]
            results = [f.result() for f in concurrent.futures.as_completed(futures)]

            return results
    ```

    **Suggestions:**

    * Task creation: Can be highly concurrent (10-30)
    * Status query: Recommend concurrency ≤ 10
    * Video download: Recommend concurrency ≤ 5
  </Accordion>
</AccordionGroup>

## Pricing

<Info>
  Async API has **same pricing** as Sync API, charged per request.
</Info>

| Model Type               | Price          |
| ------------------------ | -------------- |
| Standard (veo-3.1 etc.)  | \$0.25/request |
| Fast (veo-3.1-fast etc.) | \$0.15/request |

**Billing Rules:**

* ✓ Only charge when video **successfully generates** (status = "completed")
* ✗ Failure, timeout, and cancellation billing follows console order status
* ✗ Content safety failure billing follows console order status (major difference from sync API ⭐)
* ✗ Status queries are free

<Tip>
  **Major advantage of Async API**: No charge for failures of any kind, including content safety review failures. Sync API charges as long as request succeeds, even if generation ultimately fails.
</Tip>

## FAQ

<AccordionGroup>
  <Accordion title="How long are tasks valid?" icon="calendar">
    **Task validity: 24 hours**

    * Can query task status anytime within 24 hours after creation
    * Video files are stored for 24 hours after generation completes
    * Tasks and videos are automatically cleaned up after 24 hours

    **Recommendations:**

    * Download immediately after video generation completes
    * Don't rely on server for long-term storage
  </Accordion>

  <Accordion title="Why am I getting 404 when querying?" icon="search">
    **Possible reasons:**

    1. **Incorrect video\_id** - Check if copied completely
    2. **Task expired** - Over 24 hours
    3. **Network issue** - Retry the request

    **Solution:**

    ```python theme={null}
    try:
        response = requests.get(f"{BASE_URL}/videos/{video_id}", headers=headers)
        task = response.json()
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 404:
            print("Task doesn't exist or has expired")
        else:
            raise
    ```
  </Accordion>

  <Accordion title="Can I mix async and sync APIs?" icon="git-merge">
    **Yes, they're completely independent**

    The two API systems are completely separate:

    * Different endpoints
    * Different workflows
    * Same pricing
    * Share the same API Key and balance

    **Usage recommendations:**

    * Quick testing → Use Sync API
    * Production → Use Async API (more stable)
    * Batch generation → Use Async API
  </Accordion>

  <Accordion title="How to choose the right model?" icon="sliders-horizontal">
    **Choose based on needs:**

    | Need                           | Recommended Model                          |
    | ------------------------------ | ------------------------------------------ |
    | Quick testing                  | `veo-3.1-fast`                             |
    | Standard portrait video        | `veo-3.1`                                  |
    | Standard landscape video       | `veo-3.1-landscape`                        |
    | Image-to-video (portrait)      | `veo-3.1-fl`                               |
    | Image-to-video (landscape)     | `veo-3.1-landscape-fl`                     |
    | Batch generation (cost-saving) | `veo-3.1-fast` or `veo-3.1-landscape-fast` |
  </Accordion>
</AccordionGroup>

## Error Handling

### Common Error Codes

| HTTP Code | Error Type            | Description                     | Solution                          |
| --------- | --------------------- | ------------------------------- | --------------------------------- |
| 400       | Bad Request           | Request parameter error         | Check parameter format and values |
| 401       | Unauthorized          | Invalid API Key                 | Check Authorization header        |
| 402       | Payment Required      | Insufficient balance            | Top up and retry                  |
| 404       | Not Found             | Task doesn't exist              | Check video\_id or task expired   |
| 429       | Too Many Requests     | Request too frequent            | Reduce polling frequency          |
| 500       | Internal Server Error | Server error                    | Retry later                       |
| 503       | Service Unavailable   | Service temporarily unavailable | Wait and retry                    |

### Error Response Format

```json theme={null}
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key provided",
    "type": "authentication_error"
  }
}
```

## Technical Support

<Card title="Need Help?" icon="headset">
  If you have questions, feel free to contact us:

  * **Email:** [hi@laozhang.ai](mailto:hi@laozhang.ai)
  * **Telegram:** [https://t.me/laozhang\_cn](https://t.me/laozhang_cn)
  * **Docs:** [https://docs.laozhang.ai](https://docs.laozhang.ai)
</Card>

## Next Steps

<CardGroup cols={2}>
  <Card title="Sync API" icon="bolt" href="/en/api-capabilities/veo/veo-31-quick-start">
    View sync calling method (OpenAI compatible)
  </Card>

  <Card title="Code Examples" icon="code" href="/en/api-capabilities/veo/veo-31-examples">
    View more application examples
  </Card>

  <Card title="Model Overview" icon="play" href="/en/api-capabilities/veo/veo-31-overview">
    Learn about Veo-3.1 model details
  </Card>

  <Card title="Troubleshooting" icon="circle-question-mark" href="/en/api-capabilities/veo/veo-31-troubleshooting">
    View more Q\&A
  </Card>
</CardGroup>
