Skip to main content
Async API: Best for batch processing scenarios. Submit tasks and retrieve results via polling. For real-time interaction, use the synchronous API.

Models & Pricing

VEO 3.1 offers 8 model variants with the following naming convention:
  • Base name: veo-3.1
  • -landscape: Landscape mode (1280x720), default is portrait (720x1280)
  • -fast: Fast generation, quicker speed and lower price
  • -fl: Frame-to-Video mode, supports first/last frame input
ModelDescriptionResolutionPrice
veo-3.1Default portrait video720 x 1280$0.25
veo-3.1-flPortrait + frame-to-video720 x 1280$0.25
veo-3.1-fastPortrait + fast720 x 1280$0.15
veo-3.1-fast-flPortrait + fast + frame-to-video720 x 1280$0.15
veo-3.1-landscapeLandscape video1280 x 720$0.25
veo-3.1-landscape-flLandscape + frame-to-video1280 x 720$0.25
veo-3.1-landscape-fastLandscape + fast1280 x 720$0.15
veo-3.1-landscape-fast-flLandscape + fast + frame-to-video1280 x 720$0.15
Pay on success: Only charged for successfully generated videos. All models generate 8-second videos with auto-generated audio tracks.

API Endpoints

1. Create Video Task

/v1/videos
Create an async video generation task
Request Headers
Content-Type: application/json
Authorization: sk-APIKEY
Request Parameters
prompt
string
required
Text description for video generation
model
string
required
Model name, e.g., veo-3.1, veo-3.1-fast, etc.
Request Examples
curl --location --request POST 'https://api.apiyi.com/v1/videos' \
--header 'Authorization: sk-your-api-key' \
--header 'Content-Type: application/json' \
--data-raw '{
    "prompt": "A cute kitten playing",
    "model": "veo-3.1"
}'
Response Example
{
  "id": "video_abc123",
  "object": "video",
  "created": 1762181811,
  "status": "queued",
  "model": "veo-3.1"
}

2. Query Task Status

/v1/videos/{video_id}
Query the current status of a video generation task
Path Parameters
video_id
string
required
Video task ID (returned from the create endpoint)
Request Examples
curl --location --request GET 'https://api.apiyi.com/v1/videos/video_abc123' \
--header 'Authorization: sk-your-api-key'
Status Reference
StatusDescriptionNext Action
queuedTask is queuedContinue polling
processingTask is processingContinue polling
completedGeneration completeCall content endpoint
failedGeneration failedCheck error message

3. Get Video Content

/v1/videos/{video_id}/content
Get the actual content of a generated video
Request Examples
curl --location --request GET 'https://api.apiyi.com/v1/videos/video_abc123/content' \
--header 'Authorization: sk-your-api-key'
Response Example
{
  "id": "video_abc123",
  "object": "video",
  "created": 1762181811,
  "status": "completed",
  "model": "veo-3.1",
  "prompt": "A cute kitten playing",
  "url": "https://veo-video.gptkey.asia/assets/flow/xxx.mp4",
  "duration": 8,
  "resolution": "720x1280"
}
Video URLs are typically valid for 24 hours. Download and save promptly.

Complete Workflow

1

Create Task

Call POST /v1/videos to create a video generation task and get the video_id
2

Poll Status

Use GET /v1/videos/{video_id} to poll task status (recommended: every 5-10 seconds) until status is completed
3

Get Video

Call GET /v1/videos/{video_id}/content to get the video URL
4

Download Video

Download and save the video file from the returned URL

Python Complete Example

import requests
import time

class VEOClient:
    """VEO 3.1 Async API Client"""

    def __init__(self, api_key: str, base_url: str = "https://api.apiyi.com"):
        self.base_url = base_url
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": api_key
        }

    def create_video(self, prompt: str, model: str = "veo-3.1") -> str:
        """Create video task, returns video_id"""
        response = requests.post(
            f"{self.base_url}/v1/videos",
            headers=self.headers,
            json={"prompt": prompt, "model": model}
        )
        response.raise_for_status()
        return response.json()["id"]

    def get_status(self, video_id: str) -> dict:
        """Query task status"""
        response = requests.get(
            f"{self.base_url}/v1/videos/{video_id}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def get_content(self, video_id: str) -> dict:
        """Get video content"""
        response = requests.get(
            f"{self.base_url}/v1/videos/{video_id}/content",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def wait_for_completion(self, video_id: str, timeout: int = 600, interval: int = 5) -> dict:
        """Wait for task completion"""
        start_time = time.time()
        while time.time() - start_time < timeout:
            status_data = self.get_status(video_id)
            status = status_data.get("status")

            if status == "completed":
                return self.get_content(video_id)
            elif status == "failed":
                raise Exception(f"Video generation failed: {status_data}")

            print(f"Task in progress... Status: {status}")
            time.sleep(interval)

        raise TimeoutError("Timeout waiting for completion")


# Usage example
if __name__ == "__main__":
    client = VEOClient("sk-your-api-key")

    try:
        # 1. Create task
        video_id = client.create_video(
            prompt="A kitten walking in a sunny garden",
            model="veo-3.1-fast"
        )
        print(f"Task created, ID: {video_id}")

        # 2. Wait for completion and get result
        result = client.wait_for_completion(video_id)
        print(f"Video generated successfully!")
        print(f"Video URL: {result['url']}")
        print(f"Resolution: {result['resolution']}")

    except Exception as e:
        print(f"Error: {e}")

Frame-to-Video Mode

Models with the -fl suffix support frame-to-video functionality, converting static images into dynamic videos.
ModeImagesDescription
First Frame1Use image as video start, AI generates the continuation
First & Last Frame2Use first image as start, second as end, AI generates transition

Request Parameters

Frame-to-video requests require multipart/form-data format (not JSON) because image files need to be uploaded.
prompt
string
required
Video description. Describe how the scene should move (e.g., “camera slowly zooms in”, “person walks forward”)
model
string
required
Must use a model with -fl suffix, e.g., veo-3.1-fl, veo-3.1-landscape-fl
input_reference
file
required
Image file. Pass once for first-frame mode, twice for first-and-last-frame mode

First Frame Mode (Single Image)

Use one image as the video start, AI automatically generates the continuation.
curl --location --request POST 'https://api.apiyi.com/v1/videos' \
--header 'Authorization: sk-your-api-key' \
--form 'prompt="Bring this scene to life, camera slowly zooms in"' \
--form 'model="veo-3.1-landscape-fl"' \
--form 'input_reference=@"/path/to/image.jpg"'

First & Last Frame Mode (Two Images)

Specify the start and end frames, AI generates the transition animation between them.
curl --location --request POST 'https://api.apiyi.com/v1/videos' \
--header 'Authorization: sk-your-api-key' \
--form 'prompt="Transition from day to night, camera stays still"' \
--form 'model="veo-3.1-landscape-fl"' \
--form 'input_reference=@"/path/to/first-frame.jpg"' \
--form 'input_reference=@"/path/to/last-frame.jpg"'

Response & Next Steps

The response format is the same as text-to-video. After receiving video_id, poll for results:
{
  "id": "video_xyz789",
  "object": "video",
  "created": 1762181811,
  "status": "queued",
  "model": "veo-3.1-landscape-fl"
}
For subsequent steps, refer to the Complete Workflow section above.

Usage Recommendations

First Frame Mode Use Cases

  • Bring static images to life
  • Product showcase animations
  • Generate dynamic video from portraits

First & Last Frame Use Cases

  • Scene transitions (day→night, seasonal changes)
  • Expression change animations
  • Object morphing transitions
Prompt Tips: When using frame-to-video, describe “how the scene moves” rather than “what’s in the scene”. Examples: “camera slowly zooms in”, “person turns head and smiles”, “flower gradually blooms”.

Error Handling

Error CodeDescriptionSolution
invalid_api_keyInvalid API keyCheck if API key is correct
invalid_modelModel not foundUse a supported model name
invalid_promptInvalid promptCheck prompt length and content
video_not_foundVideo task not foundVerify video_id is correct
video_not_readyVideo not yet generatedContinue polling status
quota_exceededQuota exceededContact support to increase quota
Error Response Format
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key provided",
    "type": "authentication_error"
  }
}

FAQ

  • Best value: Choose -fast series ($0.15/video)
  • Quality first: Choose standard series ($0.25/video)
  • Image-to-video: Choose -fl series
  • Landscape content: Choose -landscape series
  • Fast models (-fast): ~30-60 seconds
  • Standard models: ~1-2 minutes
Recommended polling interval: 5-10 seconds.
Video URLs are typically valid for 24 hours. Download and save promptly after generation.
For bulk usage, contact support for enterprise pricing: [email protected]

Technical Specifications

ItemSpecification
Video Duration8 seconds
Portrait Resolution720 x 1280 (9:16)
Landscape Resolution1280 x 720 (16:9)
Audio TrackAuto-included
URL Validity24 hours
Recommended Poll Interval5-10 seconds
Maximum Wait Time10 minutes