Meteor AI
API Documentation

Videos API

Video generation API usage guide with multi-language examples

Videos API

The Videos API provides AI video generation capabilities, supporting video creation from text descriptions, remixing existing videos, and querying video generation status.

Basic Information

API Endpoints

  • Create video: https://api.routin.ai/v1/videos
  • Remix video: https://api.routin.ai/v1/videos/{id}/remix
  • Get video details: https://api.routin.ai/v1/videos/{id}

Authentication Add your API Key in the request header:

Authorization: Bearer YOUR_API_KEY

MeteorAI is fully compatible with the OpenAI Videos API, supporting GPT-4o Video and other video generation models.

1. Create Video

Generate brand new videos from text descriptions.

Request Parameters

ParameterTypeRequiredDescription
promptstringYesVideo description text
modelstringNoModel name, defaults to gpt-4o-video
sizestringNoVideo size, e.g., 1080x1920, 1920x1080
secondsstringNoVideo duration in seconds
input_referencefile[]NoArray of reference files, supports multiple file uploads

Response Format

{
  "id": "video_abc123",
  "object": "video",
  "created": 1677652288,
  "status": "processing",
  "model": "gpt-4o-video",
  "prompt": "A cute cat playing in a garden",
  "url": null
}

Status Values:

  • processing: Generation in progress
  • completed: Generation completed
  • failed: Generation failed

Code Examples

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

# Create video
response = client.videos.create(
    model="gpt-4o-video",
    prompt="A cute orange kitten chasing butterflies in a sunny garden, slow motion"
)

print(f"Video ID: {response.id}")
print(f"Status: {response.status}")
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function main() {
  // Create video
  const response = await client.videos.create({
    model: 'gpt-4o-video',
    prompt: 'A cute orange kitten chasing butterflies in a sunny garden, slow motion',
  });

  console.log(`Video ID: ${response.id}`);
  console.log(`Status: ${response.status}`);
}

main();
const OpenAI = require('openai');

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

client.videos.create({
  model: 'gpt-4o-video',
  prompt: 'A cute orange kitten chasing butterflies in a sunny garden, slow motion',
}).then(response => {
  console.log(`Video ID: ${response.id}`);
  console.log(`Status: ${response.status}`);
});
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");

var request = new
{
    model = "gpt-4o-video",
    prompt = "A cute orange kitten chasing butterflies in a sunny garden, slow motion"
};

var content = new StringContent(
    JsonSerializer.Serialize(request),
    Encoding.UTF8,
    "application/json"
);

var response = await httpClient.PostAsync(
    "https://api.routin.ai/v1/videos",
    content
);

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response: {result}");
curl https://api.routin.ai/v1/videos \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "gpt-4o-video",
    "prompt": "A cute orange kitten chasing butterflies in a sunny garden, slow motion"
  }'

Video Generation with Reference Files

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

# Create video with reference file
with open("reference_image.jpg", "rb") as ref_file:
    response = client.videos.create(
        model="gpt-4o-video",
        prompt="Based on the reference image, generate a video of a kitten playing in a garden",
        files={
            'input_reference': ref_file
        }
    )

print(f"Video ID: {response.id}")
import OpenAI from 'openai';
import fs from 'fs';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function main() {
  const response = await client.videos.create({
    model: 'gpt-4o-video',
    prompt: 'Based on the reference image, generate a video of a kitten playing in a garden',
    input_reference: fs.createReadStream('reference_image.jpg'),
  });

  console.log(`Video ID: ${response.id}`);
}

main();
curl https://api.routin.ai/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model="gpt-4o-video" \
  -F prompt="Based on the reference image, generate a video of a kitten playing in a garden" \
  -F input_reference="@reference_image.jpg"

2. Remix Video

Generate new variations or modifications based on existing videos.

Request Parameters

ParameterTypeRequiredDescription
promptstringYesRemix description text
modelstringNoModel name, defaults to gpt-4o-video
sizestringNoVideo size
secondsstringNoVideo duration in seconds
input_referencefile[]NoArray of reference files

Response Format

{
  "id": "video_xyz789",
  "object": "video",
  "created": 1677652388,
  "status": "processing",
  "model": "gpt-4o-video",
  "prompt": "Add falling leaves effect",
  "url": null
}

Code Examples

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

# Remix video
video_id = "video_abc123"
response = client.videos.remix(
    video_id=video_id,
    model="gpt-4o-video",
    prompt="Add autumn falling leaves effect, enhance warm tones"
)

print(f"New video ID: {response.id}")
print(f"Status: {response.status}")
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function main() {
  const videoId = 'video_abc123';
  const response = await client.videos.remix(videoId, {
    model: 'gpt-4o-video',
    prompt: 'Add autumn falling leaves effect, enhance warm tones',
  });

  console.log(`New video ID: ${response.id}`);
  console.log(`Status: ${response.status}`);
}

main();
const OpenAI = require('openai');

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

const videoId = 'video_abc123';
client.videos.remix(videoId, {
  model: 'gpt-4o-video',
  prompt: 'Add autumn falling leaves effect, enhance warm tones',
}).then(response => {
  console.log(`New video ID: ${response.id}`);
  console.log(`Status: ${response.status}`);
});
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");

var videoId = "video_abc123";
var request = new
{
    model = "gpt-4o-video",
    prompt = "Add autumn falling leaves effect, enhance warm tones"
};

var content = new StringContent(
    JsonSerializer.Serialize(request),
    Encoding.UTF8,
    "application/json"
);

var response = await httpClient.PostAsync(
    $"https://api.routin.ai/v1/videos/{videoId}/remix",
    content
);

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response: {result}");
curl https://api.routin.ai/v1/videos/video_abc123/remix \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "gpt-4o-video",
    "prompt": "Add autumn falling leaves effect, enhance warm tones"
  }'

3. Get Video Details

Retrieve video generation status and download URL.

Response Format

{
  "id": "video_abc123",
  "object": "video",
  "created": 1677652288,
  "status": "completed",
  "model": "gpt-4o-video",
  "prompt": "A cute cat playing in a garden",
  "url": "https://example.com/videos/video_abc123.mp4",
  "duration": 5.2,
  "size": "1920x1080"
}

Code Examples

from openai import OpenAI
import time

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

video_id = "video_abc123"

# Poll for video status
while True:
    video = client.videos.retrieve(video_id)
    print(f"Status: {video.status}")

    if video.status == "completed":
        print(f"Video URL: {video.url}")
        break
    elif video.status == "failed":
        print("Video generation failed")
        break

    time.sleep(5)  # Wait 5 seconds before checking again
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function checkVideoStatus(videoId: string) {
  while (true) {
    const video = await client.videos.retrieve(videoId);
    console.log(`Status: ${video.status}`);

    if (video.status === 'completed') {
      console.log(`Video URL: ${video.url}`);
      break;
    } else if (video.status === 'failed') {
      console.log('Video generation failed');
      break;
    }

    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}

checkVideoStatus('video_abc123');
const OpenAI = require('openai');

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function checkVideoStatus(videoId) {
  while (true) {
    const video = await client.videos.retrieve(videoId);
    console.log(`Status: ${video.status}`);

    if (video.status === 'completed') {
      console.log(`Video URL: ${video.url}`);
      break;
    } else if (video.status === 'failed') {
      console.log('Video generation failed');
      break;
    }

    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}

checkVideoStatus('video_abc123');
using System.Net.Http.Headers;
using System.Text.Json;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");

var videoId = "video_abc123";

while (true)
{
    var response = await httpClient.GetAsync(
        $"https://api.routin.ai/v1/videos/{videoId}"
    );

    var result = await response.Content.ReadAsStringAsync();
    var video = JsonSerializer.Deserialize<JsonDocument>(result);
    var status = video.RootElement.GetProperty("status").GetString();

    Console.WriteLine($"Status: {status}");

    if (status == "completed")
    {
        var url = video.RootElement.GetProperty("url").GetString();
        Console.WriteLine($"Video URL: {url}");
        break;
    }
    else if (status == "failed")
    {
        Console.WriteLine("Video generation failed");
        break;
    }

    await Task.Delay(5000);
}
curl https://api.routin.ai/v1/videos/video_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Download Video

from openai import OpenAI
import requests
from pathlib import Path

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

video = client.videos.retrieve("video_abc123")

if video.status == "completed" and video.url:
    # Download video
    video_data = requests.get(video.url).content

    # Save locally
    output_path = Path("generated_video.mp4")
    output_path.write_bytes(video_data)
    print(f"Video saved to: {output_path}")
import OpenAI from 'openai';
import fs from 'fs';
import https from 'https';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function downloadVideo(videoId: string) {
  const video = await client.videos.retrieve(videoId);

  if (video.status === 'completed' && video.url) {
    const file = fs.createWriteStream('generated_video.mp4');

    https.get(video.url, (response) => {
      response.pipe(file);
      file.on('finish', () => {
        file.close();
        console.log('Video saved to: generated_video.mp4');
      });
    });
  }
}

downloadVideo('video_abc123');
using System.Net.Http.Headers;
using System.Text.Json;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");

var videoId = "video_abc123";
var response = await httpClient.GetAsync(
    $"https://api.routin.ai/v1/videos/{videoId}"
);

var result = await response.Content.ReadAsStringAsync();
var video = JsonSerializer.Deserialize<JsonDocument>(result);
var status = video.RootElement.GetProperty("status").GetString();

if (status == "completed")
{
    var url = video.RootElement.GetProperty("url").GetString();

    // Download video
    var videoBytes = await httpClient.GetByteArrayAsync(url);

    // Save locally
    await File.WriteAllBytesAsync("generated_video.mp4", videoBytes);
    Console.WriteLine("Video saved to: generated_video.mp4");
}

Supported Models

GPT-4o Video

  • Sizes: Supports multiple resolutions (e.g., 1920x1080, 1080x1920, 1280x720)
  • Duration: Configurable video duration
  • Features: High-quality video generation, supports reference file input, supports video remixing

Video generation is computationally intensive and typically requires significant processing time. Use asynchronous polling to check video generation status.

Best Practices

1. Write Effective Prompts

# ❌ Poor prompt
prompt = "a cat"

# ✅ Good prompt
prompt = "A fluffy orange Persian cat chasing butterflies in a sunny garden, slow motion, cinematic quality, warm natural lighting"

Prompt Elements:

  • Subject: Describe the main object in the video
  • Action: Clear action description
  • Environment: Background, scene, lighting
  • Style: Shooting method, visual style
  • Details: Colors, textures, atmosphere

2. Use Asynchronous Processing

from openai import OpenAI
import time

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

# Submit video generation request
response = client.videos.create(
    model="gpt-4o-video",
    prompt="A futuristic city at sunrise with busy air traffic, sci-fi style"
)

video_id = response.id
print(f"Video generation submitted, ID: {video_id}")

# Asynchronous polling for status
max_retries = 60  # Check up to 60 times (5 minutes)
retry_count = 0

while retry_count < max_retries:
    video = client.videos.retrieve(video_id)

    if video.status == "completed":
        print(f"Video generation completed: {video.url}")
        break
    elif video.status == "failed":
        print("Video generation failed")
        break

    retry_count += 1
    time.sleep(5)

3. Use Reference Files Appropriately

# Use reference image to ensure style consistency
with open("style_reference.jpg", "rb") as ref_file:
    response = client.videos.create(
        model="gpt-4o-video",
        prompt="Based on the reference image style, generate a city street video",
        files={'input_reference': ref_file}
    )

4. Optimize Content with Video Remixing

# Generate base video first
base_video = client.videos.create(
    model="gpt-4o-video",
    prompt="A peaceful forest"
)

# After generation completes, remix to optimize
remix_video = client.videos.remix(
    video_id=base_video.id,
    prompt="Add morning mist effect, bird sounds, soft morning light"
)

5. Error Handling and Retry Mechanism

from openai import OpenAI, APIError
import time

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

max_retries = 3
retry_count = 0

while retry_count < max_retries:
    try:
        response = client.videos.create(
            model="gpt-4o-video",
            prompt="Test video generation"
        )
        print(f"Success: {response.id}")
        break
    except APIError as e:
        retry_count += 1
        if retry_count >= max_retries:
            print(f"Max retries reached: {e}")
            break
        print(f"Retry {retry_count}/{max_retries}...")
        time.sleep(2 ** retry_count)  # Exponential backoff
    except Exception as e:
        print(f"Unknown error: {e}")
        break

Use Cases

  1. Content Creation: Generate short video content for social media
  2. Product Marketing: Create product demos and advertising videos
  3. Education: Generate educational demonstration animations
  4. Game Development: Quickly generate cutscenes and concept videos
  5. Film Pre-production: Create storyboards and concept previews
  6. Virtual Events: Generate event promotions and background videos

Error Handling

Video generation may fail due to content policy, resource limitations, or technical issues. Implement proper error handling and user notifications.

from openai import OpenAI, APIError

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.routin.ai/v1"
)

try:
    response = client.videos.create(
        model="gpt-4o-video",
        prompt="Test video"
    )
    print(f"Video ID: {response.id}")
except APIError as e:
    if "content_policy_violation" in str(e):
        print("Prompt violates content policy")
    elif "rate_limit_exceeded" in str(e):
        print("Rate limit exceeded, please retry later")
    else:
        print(f"API error: {e}")
except Exception as e:
    print(f"Unknown error: {e}")
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.routin.ai/v1',
});

async function main() {
  try {
    const response = await client.videos.create({
      model: 'gpt-4o-video',
      prompt: 'Test video',
    });
    console.log(`Video ID: ${response.id}`);
  } catch (error: any) {
    if (error.code === 'content_policy_violation') {
      console.error('Prompt violates content policy');
    } else if (error.code === 'rate_limit_exceeded') {
      console.error('Rate limit exceeded, please retry later');
    } else {
      console.error(`Error: ${error.message}`);
    }
  }
}

main();
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");

try
{
    var request = new
    {
        model = "gpt-4o-video",
        prompt = "Test video"
    };

    var content = new StringContent(
        JsonSerializer.Serialize(request),
        Encoding.UTF8,
        "application/json"
    );

    var response = await httpClient.PostAsync(
        "https://api.routin.ai/v1/videos",
        content
    );

    if (!response.IsSuccessStatusCode)
    {
        var error = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Error: {error}");
    }
    else
    {
        var result = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Success: {result}");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Exception: {ex.Message}");
}

Common Error Codes

Error CodeDescriptionSolution
400Invalid request parametersCheck if prompt is empty, model name is correct
401Invalid API KeyCheck Authorization header
404Video ID not foundVerify video ID is correct
429Rate limit exceededReduce request frequency or increase retry interval
500Server errorRetry later, contact support if issue persists

Content Policy

Ensure generated video content complies with the following guidelines:

  • No violent, pornographic, hateful, or illegal content
  • No infringement of others' copyright, portrait rights, or other rights
  • No misleading or false information
  • Comply with local laws and regulations

Requests violating content policy will be rejected. Frequent violations may result in API Key suspension.

Performance Recommendations

1. Batch Processing

# Submit multiple video generation requests in batch
video_ids = []
prompts = [
    "Scene 1: Sunrise",
    "Scene 2: Forest",
    "Scene 3: Beach"
]

for prompt in prompts:
    response = client.videos.create(
        model="gpt-4o-video",
        prompt=prompt
    )
    video_ids.append(response.id)

# Check all video statuses together
for video_id in video_ids:
    video = client.videos.retrieve(video_id)
    print(f"{video_id}: {video.status}")

2. Set Appropriate Polling Intervals

# Adjust polling interval based on video duration
def get_poll_interval(seconds):
    if seconds <= 5:
        return 5  # Check every 5 seconds for short videos
    elif seconds <= 30:
        return 10  # Check every 10 seconds for medium videos
    else:
        return 30  # Check every 30 seconds for long videos

poll_interval = get_poll_interval(video_seconds)

More Resources