Sora-2 - Text To Video
Flagship sora 2 text to video. Superior cinematic quality and smooth motion for advanced video creators.
POST
/
v1
/
videos
sora-2 (Text To Video)
curl --request POST \
--url https://gptproto.com/v1/videosimport requests
url = "https://gptproto.com/v1/videos"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://gptproto.com/v1/videos', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gptproto.com/v1/videos",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://gptproto.com/v1/videos"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gptproto.com/v1/videos")
.asString();require 'uri'
require 'net/http'
url = URI("https://gptproto.com/v1/videos")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyAuthentication
- Sign up for a GPTProto account at https://gptproto.com
- Navigate to the API Keys section in your dashboard
- Generate a new API key (sk-xxxxx)
- Copy and securely store your API key For authentication details, please refer to the Authentication section.
Initiate Request
curl --location 'https://gptproto.com/v1/videos' \
--header 'Authorization: GPTPROTO_API_KEY' \
--form 'model="sora-2"' \
--form 'prompt="Put a hat on the cat"'
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('model', 'sora-2');
data.append('prompt', 'Put a hat on the cat');
let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://gptproto.com/v1/videos',
headers: {
'Authorization': 'GPTPROTO_API_KEY',
...data.getHeaders()
},
data : data
};
axios.request(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
import http.client
import mimetypes
from codecs import encode
conn = http.client.HTTPSConnection("gptproto.com")
dataList = []
boundary = 'wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T'
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=model;'))
dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))
dataList.append(encode("sora-2"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=prompt;'))
dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))
dataList.append(encode("Put a hat on the cat"))
dataList.append(encode('--'+boundary+'--'))
dataList.append(encode(''))
body = b'\r\n'.join(dataList)
payload = body
headers = {
'Authorization': 'GPTPROTO_API_KEY',
'Content-type': 'multipart/form-data; boundary={}'.format(boundary)
}
conn.request("POST", "/v1/videos", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
package main
import (
"fmt"
"bytes"
"mime/multipart"
"net/http"
"io"
)
func main() {
url := "https://gptproto.com/v1/videos"
method := "POST"
payload := &bytes.Buffer{}
writer := multipart.NewWriter(payload)
_ = writer.WriteField("model", "sora-2")
_ = writer.WriteField("prompt", "Put a hat on the cat")
err := writer.Close()
if err != nil {
fmt.Println(err)
return
}
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Authorization", "GPTPROTO_API_KEY")
req.Header.Set("Content-Type", writer.FormDataContentType())
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
Query result
How to obtain the id
After submitting your video generation request to/v1/videos, the response will contain the id you need for querying results.
Query Task Status
Retrieve detailed information about the video generation task, including status, progress, and video URL.curl --location --request GET 'https://gptproto.com/v1/videos/{{id}}' \
--header 'Authorization: GPTPROTO_API_KEY'
import requests
import json
url = "https://gptproto.com/v1/videos/{{id}}"
headers = {
"Authorization": "GPTPROTO_API_KEY"
}
response = requests.get(url, headers=headers)
result = response.json()
print(json.dumps(result, indent=2))
const url = "https://gptproto.com/v1/videos/{{id}}";
const headers = {
"Authorization": "GPTPROTO_API_KEY"
};
fetch(url, {
method: "GET",
headers: headers
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://gptproto.com/v1/videos/{{id}}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "GPTPROTO_API_KEY")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
{
"id": "video_****",
"size": "720x1280",
"error": null,
"model": "sora-2",
"object": "video",
"prompt": "Put a hat on the cat",
"status": "completed",
"seconds": "4",
"progress": 100,
"created_at": "1770098584",
"expires_at": "1770184984",
"completed_at": "1770098708",
"remixed_from_video_id": null
}
Query Video Content
Directly output the video content for immediate use or download.curl --location --request GET 'https://gptproto.com/v1/videos/{{id}}/content' \
--header 'Authorization: GPTPROTO_API_KEY'
import requests
import os
url = "https://gptproto.com/v1/videos/{{id}}/content"
headers = {
"Authorization": "GPTPROTO_API_KEY"
}
response = requests.get(url, headers=headers, stream=True)
if response.status_code == 200:
with open("video_output.mp4", "wb") as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print("Video downloaded successfully")
else:
print(f"Failed to download video: {response.status_code}")
const url = "https://gptproto.com/v1/videos/{{id}}/content";
const headers = {
"Authorization": "GPTPROTO_API_KEY"
};
fetch(url, {
method: "GET",
headers: headers
})
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'video_output.mp4';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
})
.catch(error => console.error("Error:", error));
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
url := "https://gptproto.com/v1/videos/{{id}}/content"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "GPTPROTO_API_KEY")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
out, err := os.Create("video_output.mp4")
if err != nil {
panic(err)
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
panic(err)
}
fmt.Println("Video downloaded successfully")
} else {
fmt.Printf("Failed to download video: %d\n", resp.StatusCode)
}
}
Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
prompt | string | ✅ Yes | - | - | Text prompt that describes the video to generate. |
input_reference | file | ❌ No | - | - | Optional image reference that guides generation. |
model | string | ❌ No | sora-2 | sora-2sora-2-pro | The video generation model to use. Defaults to sora-2. |
seconds | string | ❌ No | 4 | 4812 | Clip duration in seconds. Defaults to 4 seconds. |
size | string | ❌ No | 720x1280 | 720x12801280x7201024x17921792x1024 | Output resolution formatted as width x height. Defaults to 720x1280.Note: 1024x1792 and 1792x1024 are only supported by sora2-pro model. |
Error Codes
Common Error Codes
| Error Code | Error Name | Description |
|---|---|---|
| 401 | Unauthorized | API key is missing or invalid |
| 403 | Forbidden | Your API key doesn’t have permission to access this resource, or insufficient balance for the requested operation |
| 429 | Too Many Requests | You’ve exceeded your rate limit |
| 500 | Internal server error | An internal server error occurred |
| 503 | Content policy violation | Content blocked due to safety concerns (actual status code is 400) |
⌘I

