Skip to main content
Async Endpoint: https://api.laozhang.ai/v1/videosWorkflow: Three steps (Create Task → Query Status → Get Video)Advantages: More Stable | Task Queue | Long Tasks Support | No Charge on Failure

Why Choose Async API?

Higher Stability

Based on task queue, avoids long connection timeout issues

No Charge on Failure ⭐

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!

Flexible Polling

Query task status and progress anytime

Batch Processing

Suitable for batch generation and background tasks

Sync vs Async Comparison

FeatureSync APIAsync API (Recommended)
WorkflowSingle request waits for completionCreate task then poll
Endpoint/v1/chat/completions/v1/videos
Model SelectionVia model parameterVia model parameter
Image-to-VideoSupports URL and Base64Supports URL
Charge on FailureCharges even if generation fails⭐ No charge on failure
StabilityDepends on long connections⭐⭐⭐⭐⭐ More stable
Progress ViewStreaming outputPoll progress percentage
Timeout HandlingNeeds long timeoutTasks run independently
Use CasesQuick testing, real-time feedbackProduction, batch generation
Recommend using Async API, especially in production environments or when batch generating videos for better stability.

Quick Start

Async workflow consists of three steps:
1

Create Video Task

POST request to create task, get task ID
2

Query Task Status

Periodically poll for generation progress
3

Download Video

Get video file after task completes

Complete Example

curl -X POST "https://api.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"
}

API Endpoints

1. Create Video Task

POST https://api.laozhang.ai/v1/videosCreate a new video generation task

Request Parameters

ParameterTypeRequiredDescription
modelstringModel name (see model list below)
promptstringVideo generation prompt

Available Models

Model NameAspectSpeedImage-to-VideoPrice
veo-3.1PortraitStandard$0.25/request
veo-3.1-flPortraitStandard$0.25/request
veo-3.1-fastPortraitFast$0.15/request
veo-3.1-fast-flPortraitFast$0.15/request
veo-3.1-landscapeLandscapeStandard$0.25/request
veo-3.1-landscape-flLandscapeStandard$0.25/request
veo-3.1-landscape-fastLandscapeFast$0.15/request
veo-3.1-landscape-fast-flLandscapeFast$0.15/request
Model Naming Convention:
  • landscape = Landscape (16:9)
  • fast = Fast version (cheaper)
  • fl = Supports frame-to-video (image-to-video)

Response Fields

FieldTypeDescription
idstringUnique task identifier for subsequent queries
objectstringFixed as "video"
modelstringModel used
statusstringTask status: "queued"
createdintegerCreation timestamp

2. Query Task Status

GET https://api.laozhang.ai/v1/videos/{video_id}Query the current status of a video generation task

Path Parameters

ParameterTypeRequiredDescription
video_idstringTask ID returned when creating task

Response Fields

FieldTypeDescription
idstringTask ID
objectstringFixed as "video"
modelstringModel used
statusstringTask status (see below)
promptstringOriginal prompt
createdintegerCreation timestamp

Task Status Description

StatusDescriptionNext Action
queuedTask queuedContinue polling
processingGeneratingContinue polling
completedGeneration completeCall get content endpoint
failedGeneration failedCheck error message

3. Get Video Content

GET https://api.laozhang.ai/v1/videos/{video_id}/contentGet the actual content of a completed video

Path Parameters

ParameterTypeRequiredDescription
video_idstringTask ID

Response Fields

FieldTypeDescription
idstringTask ID
objectstringFixed as "video"
statusstringTask status
modelstringModel used
promptstringOriginal prompt
urlstringVideo download URL
durationintegerVideo duration (seconds)
resolutionstringVideo resolution
createdintegerCreation timestamp
ImportantVideo URLs are typically valid for 24 hours. Please download and save locally promptly!

Complete Code Examples

Python Example (with Polling Logic)

import requests
import time

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

# Step 1: Create video task
def create_video_task(prompt, model="veo-3.1"):
    """Create video generation task"""
    url = f"{BASE_URL}/videos"
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "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
    generate_video_async(
        prompt="A cute cat playing with a ball in a sunny garden",
        model="veo-3.1"
    )

JavaScript/Node.js Example

const axios = require('axios');
const fs = require('fs');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.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

Recommended polling interval: 5-10 seconds
# 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
Recommended timeout: 10 minutes (600 seconds)
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
Recommended retry logic:
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, top up first
Concurrency control suggestions:
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

Pricing

Async API has same pricing as Sync API, charged per request.
Model TypePriceWith $100 top-up
Standard (veo-3.1 etc.)$0.25/request≈ ¥1.7/request
Fast (veo-3.1-fast etc.)$0.15/request≈ ¥1.0/request
Billing Rules:
  • ✓ Only charge when video successfully generates (status = “completed”)
  • ✗ Failure, timeout, cancellation no charge
  • ✗ Content safety failure also no charge (major difference from sync API ⭐)
  • ✗ Status queries are free
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.

FAQ

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
Possible reasons:
  1. Incorrect video_id - Check if copied completely
  2. Task expired - Over 24 hours
  3. Network issue - Retry the request
Solution:
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
Yes, they’re completely independentThe 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
Choose based on needs:
NeedRecommended Model
Quick testingveo-3.1-fast
Standard portrait videoveo-3.1
Standard landscape videoveo-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

Error Handling

Common Error Codes

HTTP CodeError TypeDescriptionSolution
400Bad RequestRequest parameter errorCheck parameter format and values
401UnauthorizedInvalid API KeyCheck Authorization header
402Payment RequiredInsufficient balanceTop up and retry
404Not FoundTask doesn’t existCheck video_id or task expired
429Too Many RequestsRequest too frequentReduce polling frequency
500Internal Server ErrorServer errorRetry later
503Service UnavailableService temporarily unavailableWait and retry

Error Response Format

{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key provided",
    "type": "authentication_error"
  }
}

Technical Support

Need Help?

If you have questions, feel free to contact us:

Next Steps