Sora 2 Pro API
Generate AI videos or storyboards with Sora 2 Pro through a unified endpoint accessing three powerful models
Overview
The API supports three models:
pro-text-to-video
Generate videos from text prompts
pro-image-to-video
Transform one or more images into animations
pro-storyboard
Create cinematic storyboards with scenes and durations
Authentication
All requests require an API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY You can create and manage keys in your dashboard
Create Generation Task
Credits Cost
Standard
HD (quality: "high" + no_watermark: true)
* 25s is only supported for pro-storyboard model.
HD Pricing: When both quality === "high" AND no_watermark === true, HD pricing applies; otherwise Standard pricing applies.
Credits will be automatically deducted upon task creation and refunded if the task fails (system will retry automatically).
https://sora2api.pro/api/generateapplication/jsonRequest Parameters
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✅ | Options: pro-text-to-video, pro-image-to-video, pro-storyboard |
frames | number | ❌ | Video length in seconds. Options: 10, 15, 25 (25 only for storyboard) |
ar | string | ❌ | Aspect ratio: "horizontal" or "vertical". Default: "horizontal" |
quality | string | ❌ | "standard" or "high". Default depends on model |
no_watermark | boolean | ❌ | true to remove watermark. Default false |
cb_url | string | ❌ | Optional callback URL to receive task result |
motion | string | ⚠️ | (Required for text/image models) Text description of desired motion |
images | array | ⚠️ | (Required for image/video models) Array of public image URLs |
storyboard_scenes | array | ⚠️ | (Required for storyboard model) Array of { line, duration } objects defining each shot |
Request Examples
Response Example
{
"code": 200,
"message": "success",
"data": {
"task_id": "sostfc2d56e4c9a3113m2"
}
}Get Task Status
Query the generation progress and result of a specific task.
https://sora2api.pro/api/statuscurl -X GET "https://sora2api.pro/api/status?task_id=TASK_ID" \ -H "Authorization: Bearer YOUR_API_KEY"
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
task_id | string | ✅ | Task ID (returned from /generate endpoint) |
simple | number | ❌ | Optional: Pass 1 to return only video URL (legacy mode) |
Response Examples
✅ Success
{
"code": 200,
"message": "Video generated successfully.",
"data": {
"state": "SUCCESS",
"url": "https://cdn.yourcdn.com/video.mp4",
"model": "pro-text-to-video",
"billed": {
"tier": "hd",
"seconds": 10,
"credits": 80
}
}
}🔄 In Progress
{
"code": 200,
"message": "Generation in progress. Please check again later.",
"data": {
"state": "IN_PROGRESS",
"url": null,
"model": "pro-storyboard",
"billed": {
"tier": "standard",
"seconds": 25,
"credits": 90
}
}
}❌ Failed
{
"code": 200,
"message": "Generation failed: model timed out.",
"data": {
"state": "FAILED",
"url": null,
"model": "pro-image-to-video",
"billed": {
"tier": "hd",
"seconds": 15,
"credits": 160
}
}
}Simple Mode (simple=1)
{
"code": 200,
"message": "Video generated successfully.",
"data": "https://cdn.yourcdn.com/video.mp4"
}Response Fields
| Field | Type | Description |
|---|---|---|
code | number | HTTP status code (200 means request succeeded, not task completed) |
message | string | Human-readable status message (auto-generated based on task state and errors) |
data.state | string | Current task state: IN_PROGRESS (generating) | SUCCESS (completed) | FAILED (failed) |
data.url | string | null | Video download URL. Only returned when state is SUCCESS, otherwise null |
data.model | string | Task model: pro-text-to-video | pro-image-to-video | pro-storyboard |
data.billed.tier | string | null | Billing tier: standard or hd |
data.billed.seconds | number | null | Video duration in seconds |
data.billed.credits | number | null | Credits deducted |
Error Responses
| Code | Message | Description |
|---|---|---|
400 | task_id is required | Missing task ID parameter |
404 | Task not found | Task with specified ID does not exist |
500 | Internal Server Error, please try again later or contact support. | Server-side error |
📝 Notes
- •Returning
code: 200means the API request was successful, not that the task is completed. Checkdata.stateto determine task status. - •IN_PROGRESS → Generation in progress, you can poll for updates.
- •SUCCESS → Task completed successfully,
data.urlprovides the video download link. - •FAILED → Generation failed,
messagecontains the failure reason. - •We recommend polling every 30 seconds, or using Webhook callbacks to get final results.
Webhook (Optional Callback)
If you pass a cb_url, your endpoint will receive a POST request when generation completes.
Webhook Payload
{
"task_id": "sostfc2d56e4c9a3113m2",
"state": "success",
"url": "https://files.yourcdn.com/output/video.mp4",
"model": "pro-text-to-video",
"fail_code": null,
"fail_msg": null
}Your Response Should Be
{
"code": 200,
"message": "success"
}Error Codes
| Status Code | Meaning |
|---|---|
200 | Success |
400 | Missing or invalid parameters |
401 | Invalid API key |
402 | Insufficient balance |
422 | Parameter validation failed |
429 | Too many requests |
500 | Internal server error |
Best Practices
Use HD Cautiously
Setting quality: "high" + no_watermark: true significantly increases generation time. Based on our testing, 10s HD typically takes 10-20 minutes, and 15s HD takes about 30 minutes (much slower than OpenAI's native output). We recommend using 15s HD when longer output is needed.
Start with 15s Standard
For optimal balance between quality, duration, and cost, we recommend starting with 15s Standard quality. Only switch to HD when you need higher precision output.
Image URLs & Network
Ensure your images array contains publicly accessible URLs. Avoid 403 errors or timeouts by verifying your image URLs are reachable from the internet.
Webhook Idempotency
Webhooks may be delivered multiple times due to network fluctuations. Please implement idempotent processing using task_id to avoid duplicate handling.
Important Notes
- Generation typically takes 30-90 seconds, depending on length and model
- You can poll the /status endpoint or rely on the cb_url webhook
- The response URL is a public MP4 video hosted on our CDN
- All generated videos are kept on the CDN for 7 days. We recommend downloading them promptly
