UlazAI developer docs

Developer documentation

Sora 2 Video Generation API

Professional video generation with OpenAI's Sora 2 model - Transform text prompts or images into high-quality AI videos.

πŸŽ‰ Sora 2 Launch Special: Get 20% bonus credits on all purchases! Limited time only.

✨ Sora 2 Features

βœ… Text-to-video generation

βœ… Image-to-video animation

βœ… 10-second videos at 24fps

βœ… 1080p resolution output

βœ… Multiple aspect ratios (16:9, 9:16, 1:1)

βœ… Fast processing (~2-3 minutes)

βœ… Automatic R2 storage with CDN

βœ… Email notifications when complete

POST /api/v1/sora/generate/text-to-video/

Generate Video from Text

Create a 10-second video from a text prompt using Sora 2.

Request Body

{
  "prompt": "A serene mountain landscape at sunrise with birds flying",
  "aspect_ratio": "landscape",  // Options: "landscape", "portrait", "square"
  "quality": "standard"          // Options: "standard", "high"
}

Parameters

prompt * (string)

Text description of the video to generate. Max 5000 characters. Be descriptive for best results.

aspect_ratio (string)

Video aspect ratio. Options: landscape (16:9), portrait (9:16), square (1:1). Default: landscape

quality (string)

Quality preset. Options: standard, high. High quality uses more processing time. Default: standard

prompt_directory_optin (boolean) πŸ’° -10 CREDITS

Share your video to our public Prompt Directory and get 10 credits discount! Default: true

Success Response (201)

{
  "success": true,
  "data": {
    "task_id": "sra_2_1234567890abcdef",
    "status": "processing",
    "estimated_completion": "2-3 minutes",
    "credits_charged": 80,
    "credits_remaining": 920,
    "webhook_url": "https://ulazai.com/api/v1/sora/status/sra_2_1234567890abcdef/",
    "message": "Sora 2 video generation started successfully"
  }
}

cURL Example

curl -X POST https://ulazai.com/api/v1/sora/generate/text-to-video/ \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A serene mountain landscape at sunrise with birds flying across the sky",
    "aspect_ratio": "landscape",
    "quality": "standard"
  }'
POST /api/v1/sora/generate/image-to-video/

Generate Video from Image

Animate a static image into a 10-second video using Sora 2.

Request Body

{
  "image_url": "https://example.com/your-image.jpg",
  "prompt": "Camera slowly zooms in as the character turns and smiles",
  "aspect_ratio": "landscape",
  "quality": "standard"
}

Parameters

image_url * (string)

URL of the source image to animate. Must be publicly accessible. Supported formats: JPG, PNG, WebP.

prompt * (string)

Description of how to animate the image. Max 5000 characters.

aspect_ratio (string)

Must match the source image aspect ratio for best results.

quality (string)

Quality preset. Default: standard

prompt_directory_optin (boolean) πŸ’° -10 CREDITS

Share your video to our public Prompt Directory and get 10 credits discount! Default: true

GET /api/v1/sora/status/{task_id}/

Check Generation Status

Get the current status and result of a Sora video generation task.

Response States

Processing

{
  "success": true,
  "data": {
    "task_id": "sra_2_1234567890abcdef",
    "status": "processing",
    "progress": 45,
    "estimated_completion": "1-2 minutes"
  }
}

Success

{
  "success": true,
  "data": {
    "task_id": "sra_2_1234567890abcdef",
    "status": "success",
    "video_url": "https://cdn.ulazai.com/sora/videos/sra_2_1234567890abcdef.mp4",
    "thumbnail_url": "https://cdn.ulazai.com/sora/thumbnails/sra_2_1234567890abcdef.jpg",
    "duration": 10,
    "resolution": "1920x1080",
    "file_size": "15.2 MB",
    "created_at": "2025-01-03T10:15:30Z"
  }
}

Failed

{
  "success": false,
  "error": "Video generation failed",
  "error_details": "Content policy violation detected in prompt",
  "credits_refunded": 80
}

cURL Example

curl -X GET https://ulazai.com/api/v1/sora/status/sra_2_1234567890abcdef/ \
  -H "Authorization: Token YOUR_API_KEY"

πŸ’° Sora 2 Pricing

Text-to-Video

80 credits

Per 10-second video

β€’ 1080p resolution

β€’ All aspect ratios

β€’ 2-3 minutes processing

Image-to-Video

80 credits

Per 10-second animation

β€’ Animate any image

β€’ Custom motion prompts

β€’ 2-3 minutes processing

πŸ’‘ Example: €25 = 2,500 credits β‰ˆ 31 Sora videos

πŸ“š Best Practices

Prompt Guidelines

  • Be specific about camera movements (pan, zoom, tilt)
  • Describe lighting and atmosphere
  • Include character actions and expressions
  • Specify timing for key moments
  • Avoid copyrighted characters or brands

Image-to-Video Tips

  • Use high-quality source images (min 1024px)
  • Match aspect ratio to avoid cropping
  • Describe realistic motion for the scene
  • Consider physics and natural movement

Webhook Integration

  • Videos are automatically stored in R2 with CDN delivery
  • Email notifications sent when generation completes
  • Poll the status endpoint every 30 seconds for updates
  • Failed generations automatically refund credits

⚠️ Error Codes

400 Invalid request parameters or prompt too long
401 Invalid or missing API key
402 Insufficient credits
422 Content policy violation
429 Rate limit exceeded (max 10 concurrent)
500 Server error - credits will be refunded

πŸ’» Code Examples

Python

import requests
import time

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

# Generate video
response = requests.post(
    f"{BASE_URL}/sora/generate/text-to-video/",
    headers={"Authorization": f"Token {API_KEY}"},
    json={
        "prompt": "A beautiful sunset over the ocean with waves",
        "aspect_ratio": "landscape",
        "quality": "standard"
    }
)

if response.status_code == 201:
    task_id = response.json()["data"]["task_id"]

    # Poll for status
    while True:
        status_response = requests.get(
            f"{BASE_URL}/sora/status/{task_id}/",
            headers={"Authorization": f"Token {API_KEY}"}
        )

        status_data = status_response.json()["data"]

        if status_data["status"] == "success":
            print(f"Video ready: {status_data['video_url']}")
            break
        elif status_data["status"] == "failed":
            print("Generation failed")
            break

        time.sleep(30)  # Wait 30 seconds before next check

JavaScript (Node.js)

const axios = require('axios');

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

async function generateSoraVideo() {
    try {
        // Generate video
        const response = await axios.post(
            `${BASE_URL}/sora/generate/text-to-video/`,
            {
                prompt: 'A beautiful sunset over the ocean with waves',
                aspect_ratio: 'landscape',
                quality: 'standard'
            },
            {
                headers: { 'Authorization': `Token ${API_KEY}` }
            }
        );

        const taskId = response.data.data.task_id;
        console.log(`Generation started: ${taskId}`);

        // Poll for status
        const checkStatus = async () => {
            const statusResponse = await axios.get(
                `${BASE_URL}/sora/status/${taskId}/`,
                { headers: { 'Authorization': `Token ${API_KEY}` } }
            );

            const status = statusResponse.data.data.status;

            if (status === 'success') {
                console.log(`Video ready: ${statusResponse.data.data.video_url}`);
            } else if (status === 'failed') {
                console.log('Generation failed');
            } else {
                setTimeout(checkStatus, 30000); // Check again in 30 seconds
            }
        };

        setTimeout(checkStatus, 30000);

    } catch (error) {
        console.error('Error:', error.response?.data || error.message);
    }
}

generateSoraVideo();

πŸš€ Ready to Start?

πŸŽ‰ Limited time: Get 20% bonus credits on all purchases!