The Video API generates videos from text prompts using models like Veo2, Veo3, and Sora-2. Video generation is asynchronous - you create a task and poll for completion.
Create Video
Creates an asynchronous video generation task.
HTTP Request
curl https://api.apertis.ai/v1/video/create \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -d '{ "model": "veo3", "prompt": "A serene lake with mountains in the background at sunset", "enhance_prompt": true, "aspect_ratio": "16:9" }'
Authentication
Header Format Example AuthorizationBearer token Authorization: Bearer sk-your-api-key
Parameters
Required Parameters
Parameter Type Description modelstring The model to use for video generation (see Supported Models below) promptstring A text description of the desired video
Optional Parameters
Parameter Type Description enhance_promptboolean Automatically enhance and translate prompts (Chinese to English). Default: false enable_upsampleboolean Upscale video quality. Default: false aspect_ratiostring Video aspect ratio: 16:9 or 9:16. Only supported by veo3 models imagesarray Reference images for frame control (model-specific limits, see below)
Image Reference Limits by Model
Model Variant Max Images Description veo2-fast-frames2 First and last frame references veo3-pro-frames1 First frame reference only veo2-fast-components3 Video element components
Sora-2 Specific Parameters
For Sora-2 models (sora-2, sora-2-pro), the following parameters are used instead:
Parameter Type Required Description modelstring Yes Model ID: sora-2, sora-2-pro promptstring Yes Text description of the desired video imagesarray Yes Array of image URLs for reference orientationstring No Video orientation: portrait or landscape sizestring No Quality level: small (~720p) or large (1080p HD) durationinteger No Video duration: 10, 15, or 25 seconds watermarkboolean No Enable watermark. Default: true privateboolean No Keep video private (unpublished). Default: false character_urlstring No Video URL (1-3 seconds) for character creation character_timestampsstring No Character timing in {start},{end} format
{ "id" : "veo3:1234567890-abcdefgh" , "status" : "pending" , "status_update_time" : 1704067200 , "enhanced_prompt" : "A tranquil mountain lake reflecting golden sunset light..." }
Response Fields
Field Type Description idstring Unique task identifier for polling status statusstring Current task status: pending, processing, completed, failed status_update_timeinteger Unix timestamp of last status update enhanced_promptstring The processed/enhanced prompt used for generation
Query Video Status
Query the status of a video generation task.
HTTP Request
curl "https://api.apertis.ai/v1/video/query?id=veo3:1234567890-abcdefgh" \ -H "Authorization: Bearer <APERTIS_API_KEY>"
Query Parameters
Parameter Type Required Description idstring Yes The task ID returned from /v1/video/create
Pending/Processing
{ "id" : "veo3:1234567890-abcdefgh" , "status" : "processing" , "video_url" : null , "enhanced_prompt" : "A tranquil mountain lake reflecting golden sunset light..." , "status_update_time" : 1704067200 }
Completed
{ "id" : "veo3:1234567890-abcdefgh" , "status" : "completed" , "video_url" : "https://storage.example.com/videos/output.mp4" , "enhanced_prompt" : "A tranquil mountain lake reflecting golden sunset light..." , "status_update_time" : 1704067500 }
Response Fields
Field Type Description idstring Task identifier statusstring Task status: pending, processing, completed, failed video_urlstring/null URL to the generated video (available when status is completed) enhanced_promptstring The processed prompt used for generation status_update_timeinteger Unix timestamp of last status update
Example Usage
Python - Complete Workflow
import httpx import time client_headers = { "Authorization" : "Bearer sk-your-api-key" , "Content-Type" : "application/json" } response = httpx . post ( "https://api.apertis.ai/v1/video/create" , headers = client_headers , json = { "model" : "veo3" , "prompt" : "A serene lake with mountains in the background at sunset" , "enhance_prompt" : True , "aspect_ratio" : "16:9" } ) task = response . json ( ) task_id = task [ "id" ] print ( f"Task created: { task_id } " ) print ( f"Enhanced prompt: { task . get ( 'enhanced_prompt' , 'N/A' ) } " ) while True : query_response = httpx . get ( f"https://api.apertis.ai/v1/video/query?id= { task_id } " , headers = client_headers ) result = query_response . json ( ) status = result [ "status" ] print ( f"Status: { status } " ) if status == "completed" : print ( f"Video URL: { result [ 'video_url' ] } " ) break elif status == "failed" : print ( "Video generation failed" ) break time . sleep ( 10 )
JavaScript - Complete Workflow
const headers = { 'Authorization' : 'Bearer sk-your-api-key' , 'Content-Type' : 'application/json' } ; const createResponse = await fetch ( 'https://api.apertis.ai/v1/video/create' , { method : 'POST' , headers , body : JSON . stringify ( { model : 'veo3' , prompt : 'A serene lake with mountains in the background at sunset' , enhance_prompt : true , aspect_ratio : '16:9' } ) } ) ; const task = await createResponse . json ( ) ; const taskId = task . id ; console . log ( 'Task created:' , taskId ) ; const pollStatus = async ( ) => { const queryResponse = await fetch ( ` https://api.apertis.ai/v1/video/query?id= ${ taskId } ` , { headers } ) ; const result = await queryResponse . json ( ) ; console . log ( 'Status:' , result . status ) ; if ( result . status === 'completed' ) { console . log ( 'Video URL:' , result . video_url ) ; return result ; } else if ( result . status === 'failed' ) { throw new Error ( 'Video generation failed' ) ; } await new Promise ( r => setTimeout ( r , 10000 ) ) ; return pollStatus ( ) ; } ; await pollStatus ( ) ;
With Frame References (veo2-fast-frames)
response = httpx . post ( "https://api.apertis.ai/v1/video/create" , headers = client_headers , json = { "model" : "veo2-fast-frames" , "prompt" : "A bird flying across the sky" , "images" : [ "https://example.com/first-frame.jpg" , "https://example.com/last-frame.jpg" ] } )
Sora-2 Complete Workflow
import httpx import time client_headers = { "Authorization" : "Bearer sk-your-api-key" , "Content-Type" : "application/json" } response = httpx . post ( "https://api.apertis.ai/v1/video/create" , headers = client_headers , json = { "model" : "sora-2" , "prompt" : "A cinematic scene of a person walking through a forest" , "images" : [ "https://example.com/reference.jpg" ] , "orientation" : "landscape" , "size" : "large" , "duration" : 10 , "watermark" : True , "private" : False } ) task = response . json ( ) task_id = task [ "id" ] print ( f"Task created: { task_id } " ) while True : query_response = httpx . get ( f"https://api.apertis.ai/v1/video/query?id= { task_id } " , headers = client_headers ) result = query_response . json ( ) status = result [ "status" ] print ( f"Status: { status } " ) if status == "completed" : print ( f"Video URL: { result [ 'video_url' ] } " ) break elif status == "failed" : print ( "Video generation failed" ) break time . sleep ( 10 )
Sora-2 with Character Creation
response = httpx . post ( "https://api.apertis.ai/v1/video/create" , headers = client_headers , json = { "model" : "sora-2-pro" , "prompt" : "A character dancing in a studio" , "images" : [ "https://example.com/reference.jpg" ] , "orientation" : "portrait" , "size" : "large" , "duration" : 15 , "character_url" : "https://example.com/character-video.mp4" , "character_timestamps" : "0,3" } )
Alternative API: /v1/videos
An alternative video generation API using multipart/form-data with reference images.
Create Video with Reference Image
Creates a video generation task with a reference image input.
HTTP Request
curl https://api.apertis.ai/v1/videos \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -F "model=veo_3_1" \ -F "prompt=A serene lake with mountains" \ -F "seconds=5" \ -F "size=16x9" \ -F "[email protected] "
Parameter Type Required Description modelstring Yes Model ID: veo_3_1, veo_3_1-fast promptstring Yes Text description of the desired video secondsstring Yes Video duration in seconds sizestring Yes Aspect ratio: 16x9 (landscape) or 720x1280 (portrait) input_referencefile Yes Reference image file (base image for video) watermarkstring No Enable watermark: true or false
{ "id" : "video_55cb73b3-60af-40c8-95fd-eae8fd758ade" , "object" : "video" , "model" : "veo_3_1" , "status" : "queued" , "progress" : 0 , "created_at" : 1704067200 , "seconds" : 5 , "size" : "16x9" }
Get Video Status
Query the status of a video generation task.
HTTP Request
curl "https://api.apertis.ai/v1/videos/video_55cb73b3-60af-40c8-95fd-eae8fd758ade" \ -H "Authorization: Bearer <APERTIS_API_KEY>"
{ "id" : "video_55cb73b3-60af-40c8-95fd-eae8fd758ade" , "status" : "completed" , "progress" : 100 , "video_url" : "https://storage.example.com/videos/output.mp4" , "enhanced_prompt" : "A serene mountain lake..." , "status_update_time" : 1704067500 }
Get Video Content
GET /v1/videos/{id}/content
Retrieve the video content directly.
HTTP Request
curl "https://api.apertis.ai/v1/videos/video_55cb73b3-60af-40c8-95fd-eae8fd758ade/content" \ -H "Authorization: Bearer <APERTIS_API_KEY>"
Example: Complete Workflow
import httpx import time headers = { "Authorization" : "Bearer sk-your-api-key" } with open ( "reference.jpg" , "rb" ) as f : response = httpx . post ( "https://api.apertis.ai/v1/videos" , headers = headers , data = { "model" : "veo_3_1" , "prompt" : "A serene lake with mountains" , "seconds" : "5" , "size" : "16x9" } , files = { "input_reference" : f } ) task = response . json ( ) video_id = task [ "id" ] print ( f"Video created: { video_id } " ) while True : status_resp = httpx . get ( f"https://api.apertis.ai/v1/videos/ { video_id } " , headers = headers ) result = status_resp . json ( ) print ( f"Status: { result [ 'status' ] } , Progress: { result . get ( 'progress' , 0 ) } %" ) if result [ "status" ] == "completed" : print ( f"Video URL: { result [ 'video_url' ] } " ) break time . sleep ( 10 )
Sora-2 Extended API
Sora-2 models support an extended set of endpoints for video generation, remixing, and character management.
Create Video (Sora)
Creates a video generation task using Sora-2 models with multipart/form-data.
HTTP Request
curl https://api.apertis.ai/v1/videos \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -F "model=sora-2" \ -F "prompt=A cinematic scene of a person walking through a forest" \ -F "seconds=10" \ -F "size=1280x720" \ -F "watermark=false" \ -F "private=false" \ -F "[email protected] "
Parameter Type Required Description modelstring Yes Model ID: sora-2, sora-2-pro promptstring Yes Text description of the desired video secondsstring Yes Video duration: 4, 8, 10, 12, 15, or 25 sizestring Yes Video dimensions: 720x1280, 1280x720, 480x480, 1080x1080 input_referencefile No Reference image file for the video watermarkstring No Enable watermark: true or false privatestring No Keep video private: true or false stylestring No Style preset for the video metadatastring No Custom metadata JSON
Character Parameters
Parameter Type Description character_urlstring URL of video (1-3 seconds) to create character from character_timestampsstring Start and end time for character extraction: "start,end" (e.g., "1,3") character_from_taskstring Task ID to use for character reference character_createobject Character creation options: create_self_portrait, save_to_library
Using Characters in Prompts
After creating a character via /sora/v1/characters, use @username in your prompt to reference that character in video generation.
{ "id" : "sora-2:1234567890-abcdefgh" , "object" : "video" , "model" : "sora-2" , "status" : "pending" , "progress" : 0 , "created_at" : 1704067200 , "seconds" : 10 , "size" : "1280x720" }
Get Video Status (Sora)
Query the status of a Sora video generation task.
HTTP Request
curl "https://api.apertis.ai/v1/videos/sora-2:1234567890-abcdefgh" \ -H "Authorization: Bearer <APERTIS_API_KEY>"
{ "id" : "sora-2:1234567890-abcdefgh" , "status" : "completed" , "progress" : 100 , "video_url" : "https://storage.example.com/videos/output.mp4" , "model" : "sora-2" , "seconds" : 10 , "size" : "1280x720" }
Response Fields
Field Type Description idstring Task identifier statusstring Task status: pending, processing, completed, failed progressinteger Generation progress (0-100) video_urlstring/null URL to the generated video (when completed) modelstring Model used for generation secondsinteger Video duration sizestring Video dimensions
Get Video Content (Sora)
GET /v1/videos/{id}/content
Retrieve the video content directly from a completed Sora generation.
HTTP Request
curl "https://api.apertis.ai/v1/videos/sora-2:1234567890-abcdefgh/content" \ -H "Authorization: Bearer <APERTIS_API_KEY>"
{ "id" : "sora-2:1234567890-abcdefgh" , "status" : "completed" , "video_url" : "https://storage.example.com/videos/output.mp4" , "enhanced_prompt" : "A cinematic scene of a person walking through a forest..." , "status_update_time" : 1704067500 }
Remix Video (Sora)
POST /v1/videos/{id}/remix
Create a new video by remixing/editing an existing Sora video.
HTTP Request
curl "https://api.apertis.ai/v1/videos/sora-2:1234567890-abcdefgh/remix" \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Add dramatic lighting and slow motion effect", "size": "1280x720" }'
Parameters
Parameter Type Required Description promptstring Yes Description of the edit/remix to apply sizestring No Override output dimensions
{ "id" : "sora-2:remix-9876543210-xyz" , "object" : "video" , "status" : "pending" , "progress" : 0 }
Create Character
Create a character from a video that can be referenced in future video generations.
HTTP Request
curl https://api.apertis.ai/sora/v1/characters \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/character-video.mp4", "timestamps": "1,3" }' curl https://api.apertis.ai/sora/v1/characters \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "from_task": "sora-2:1234567890-abcdefgh", "timestamps": "0,2" }'
Parameters
Parameter Type Required Description urlstring One of url or from_task Video URL (1-3 seconds recommended) from_taskstring One of url or from_task Task ID to extract character from timestampsstring No Start and end time: "start,end" (e.g., "1,3")
{ "id" : "char_abc123xyz" , "username" : "my_character" , "permalink" : "https://sora.example.com/characters/my_character" , "profile_picture_url" : "https://storage.example.com/characters/my_character.jpg" }
Response Fields
Field Type Description idstring Unique character identifier usernamestring Character username for prompt references (use @username) permalinkstring Public link to the character profile profile_picture_urlstring Character thumbnail image URL
Example: Complete Sora Workflow with Characters
import httpx import time headers = { "Authorization" : "Bearer sk-your-api-key" } char_response = httpx . post ( "https://api.apertis.ai/sora/v1/characters" , headers = headers , json = { "url" : "https://example.com/person-video.mp4" , "timestamps" : "1,3" } ) character = char_response . json ( ) username = character [ "username" ] print ( f"Character created: @ { username } " ) with open ( "reference.jpg" , "rb" ) as f : video_response = httpx . post ( "https://api.apertis.ai/v1/videos" , headers = headers , data = { "model" : "sora-2-pro" , "prompt" : f"@ { username } walking through a futuristic city at night" , "seconds" : "15" , "size" : "1280x720" , "watermark" : "false" } , files = { "input_reference" : f } ) task = video_response . json ( ) video_id = task [ "id" ] print ( f"Video task created: { video_id } " ) while True : status_resp = httpx . get ( f"https://api.apertis.ai/v1/videos/ { video_id } " , headers = headers ) result = status_resp . json ( ) print ( f"Status: { result [ 'status' ] } , Progress: { result . get ( 'progress' , 0 ) } %" ) if result [ "status" ] == "completed" : print ( f"Video URL: { result [ 'video_url' ] } " ) break elif result [ "status" ] == "failed" : print ( "Video generation failed" ) break time . sleep ( 10 ) remix_response = httpx . post ( f"https://api.apertis.ai/v1/videos/ { video_id } /remix" , headers = headers , json = { "prompt" : "Add cinematic color grading and dramatic lighting" } ) remix_task = remix_response . json ( ) print ( f"Remix task created: { remix_task [ 'id' ] } " )
Supported Models
Veo Models
Model Description Aspect Ratio Support veo2Veo 2 base model No veo2-fastVeo 2 fast generation No veo2-proVeo 2 professional quality No veo2-fast-framesVeo 2 with frame references (max 2 images) No veo2-fast-componentsVeo 2 with component references (max 3 images) No veo3Veo 3 base model Yes (16:9, 9:16) veo3-fastVeo 3 fast generation Yes (16:9, 9:16) veo3-proVeo 3 professional quality Yes (16:9, 9:16) veo3-pro-framesVeo 3 with frame reference (max 1 image) Yes (16:9, 9:16) veo3.1Veo 3.1 latest model Yes (16:9, 9:16) veo3.1-fastVeo 3.1 fast generation Yes (16:9, 9:16) veo_3_1Veo 3.1 (for /v1/videos API) Yes (16x9, 720x1280) veo_3_1-fastVeo 3.1 fast (for /v1/videos API) Yes (16x9, 720x1280)
Sora Models
Model Description Duration Support sora-2Sora 2 base model 10 seconds sora-2-proSora 2 professional quality 10, 15, or 25 seconds
Sora-2 models use different parameters than Veo models:
orientation : portrait or landscape (instead of aspect_ratio)
size : small (~720p) or large (1080p HD)
duration : Video length in seconds (10, 15, or 25)
images : Required array of reference image URLs
character_url / character_timestamps : Optional character creation support
Sora-2 Chat Completions API
Sora-2 models also support video generation through the standard /v1/chat/completions endpoint with streaming responses.
HTTP Request
curl https://api.apertis.ai/v1/chat/completions \ -H "Authorization: Bearer <APERTIS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "model": "sora-2", "stream": true, "messages": [ { "role": "user", "content": "Generate a video of a serene lake with mountains" } ] }'
Parameters
Parameter Type Required Description modelstring Yes Model ID: sora-2, sora-2-pro streamboolean Recommended Enable streaming responses (recommended: true) messagesarray Yes Message array with video prompt in content
Streaming Response
The response uses Server-Sent Events (SSE) format with progress updates:
data: {"choices":[{"delta":{"content":"task_id: sora-2:1234567890-abcdefgh"}}]} data: {"choices":[{"delta":{"content":"progress: 25%"}}]} data: {"choices":[{"delta":{"content":"video_url: https://storage.example.com/videos/output.mp4"}}]} data: [DONE]
Python Example
import httpx with httpx . stream ( "POST" , "https://api.apertis.ai/v1/chat/completions" , headers = { "Authorization" : "Bearer sk-your-api-key" , "Content-Type" : "application/json" } , json = { "model" : "sora-2" , "stream" : True , "messages" : [ { "role" : "user" , "content" : "Generate a video of a serene lake with mountains" } ] } ) as response : for line in response . iter_lines ( ) : if line . startswith ( "data: " ) : data = line [ 6 : ] if data == "[DONE]" : break print ( data )
JavaScript Example
const response = await fetch ( 'https://api.apertis.ai/v1/chat/completions' , { method : 'POST' , headers : { 'Authorization' : 'Bearer sk-your-api-key' , 'Content-Type' : 'application/json' } , body : JSON . stringify ( { model : 'sora-2' , stream : true , messages : [ { role : 'user' , content : 'Generate a video of a serene lake with mountains' } ] } ) } ) ; const reader = response . body . getReader ( ) ; const decoder = new TextDecoder ( ) ; while ( true ) { const { done , value } = await reader . read ( ) ; if ( done ) break ; const chunk = decoder . decode ( value ) ; const lines = chunk . split ( '\n' ) ; for ( const line of lines ) { if ( line . startsWith ( 'data: ' ) ) { const data = line . slice ( 6 ) ; if ( data === '[DONE]' ) break ; console . log ( JSON . parse ( data ) ) ; } } }
When to Use Chat Completions vs Video Create
Use /v1/chat/completions for simple video generation with streaming progress
Use /v1/video/create when you need full control over parameters like orientation, size, duration, character_url, etc.
Error Responses
Status Code Description 400 Bad Request - Invalid parameters 401 Unauthorized - Invalid API key 402 Payment Required - Insufficient quota 404 Not Found - Task ID not found 429 Rate Limited - Too many requests 500 Internal Server Error