cURL
curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}'import os
import requests
payload = {
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload := map[string]any{}
if err := json.Unmarshal([]byte(`{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}`), &payload); err != nil {
panic(err)
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(
{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}
),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Sora 2
Sora 2 Official API
Sora 2 VIP is APIPod’s official-provider routing ID for Sora 2. Its public contract supports 4-, 8-, or 12-second clips and an optional first-frame image.
POST
https://api.apipod.ai
/
v1
/
videos
/
generations
cURL
curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}'import os
import requests
payload = {
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload := map[string]any{}
if err := json.Unmarshal([]byte(`{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}`), &payload); err != nil {
panic(err)
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(
{
"model": "sora-2-vip",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"image_url": "https://cdn.example.com/reference.jpg",
"duration": 8,
"aspect_ratio": "9:16"
}
),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Authorizations
Use your APIPod API key as a Bearer token in the Authorization header.
Body
application/json
Public APIPod model ID.
Allowed value:
"sora-2-vip"Describe the content of the video to be generated.
Maximum string length:
4000URL of the image to use as the first frame. Please do not upload real portrait images, as this will most likely result in failure. The image format must be consistent with the ratio, and only 1280×720 (16:9 landscape) and 720×1280 (9:16 portrait) are supported.
The video durations
Available options:
8, 12 This parameter defines the aspect ratio of the video.
Available options:
9:16, 16:9 Was this page helpful?