Sora 2 TVC Ad API
API for generating TVC (TV Commercial) advertisement videos using AI-powered storyboard generation and Sora 2 video synthesis.
Try it online: https://nanophoto.ai/sora-2-tvc-ad
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/sora-2-tvc/generate | Generate a TVC ad video |
| POST | /api/sora-2-tvc/check-status | Check task status |
Authentication
Authorization: Bearer YOUR_API_KEYCredits
| Duration | Credits |
|---|---|
| 10s | 8 |
| 15s | 8 |
How It Works
The TVC Ad API uses a 3-step AI pipeline to generate professional TV commercial videos:
- Storyboard Script — AI generates a 9-scene (SC1-SC9) storyboard description based on your ad theme
- Storyboard Image — AI creates a 3x3 grid black-and-white storyboard illustration
- Video Generation — Sora 2 generates the final ad video from the storyboard image
The generate endpoint returns immediately after starting the pipeline. Use the check-status endpoint to poll for progress and results.
Generate TVC Ad
POST /api/sora-2-tvc/generateHeaders
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer YOUR_API_KEY |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
adTheme | string | Yes | The ad theme or topic (e.g., "Nike running shoes") |
referenceImageUrl | string | No | Public URL of a reference image for style guidance |
voiceoverScript | string | No | Voiceover script text for the ad |
videoDuration | string | No | 10 or 15 (seconds, default: 10) |
aspectRatio | string | No | portrait (default) or landscape |
API calls only accept referenceImageUrl (public URL). Base64 image upload is not supported via API.
Examples
Basic TVC Ad
curl -X POST "https://nanophoto.ai/api/sora-2-tvc/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"adTheme": "Nike running shoes - feel the speed",
"videoDuration": "15",
"aspectRatio": "landscape"
}'With Reference Image and Voiceover
curl -X POST "https://nanophoto.ai/api/sora-2-tvc/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"adTheme": "Luxury perfume - elegance in every drop",
"referenceImageUrl": "https://example.com/perfume-reference.jpg",
"voiceoverScript": "Discover the essence of elegance. A fragrance that speaks to your soul.",
"videoDuration": "15",
"aspectRatio": "portrait"
}'TypeScript
async function generateTVCAd() {
// Step 1: Submit TVC ad generation task
const response = await fetch("https://nanophoto.ai/api/sora-2-tvc/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_API_KEY",
},
body: JSON.stringify({
adTheme: "Nike running shoes - feel the speed",
voiceoverScript: "Run faster. Run stronger. Nike.",
videoDuration: "15",
aspectRatio: "landscape",
}),
});
const data = await response.json();
if (!data.success) {
console.error("Generation failed:", data.error);
return;
}
console.log("Storyboard prompt:", data.storyboardPrompt);
console.log("Storyboard image:", data.storyboardImageUrl);
// Step 2: Poll for status using recordId
const recordId = data.recordId;
while (true) {
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5s
const statusRes = await fetch(
"https://nanophoto.ai/api/sora-2-tvc/check-status",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_API_KEY",
},
body: JSON.stringify({ recordId }),
}
);
const status = await statusRes.json();
if (status.status === "completed") {
console.log("Video URL:", status.videoUrl);
console.log("Generation time:", status.generationTime, "seconds");
return;
}
if (status.status === "failed") {
console.error("Generation failed:", status.error);
return;
}
console.log(`Step ${status.currentStep}/3: ${status.stepName}`);
}
}
generateTVCAd();Response
Processing
{
"success": true,
"status": "processing",
"taskId": "video_task_id",
"recordId": "tvc_record_id",
"storyboardPrompt": "Generated 9-scene storyboard description...",
"storyboardImageUrl": "https://static.nanophoto.ai/images/sora-tvc/storyboard-xxx.png"
}When you receive status: "processing", poll the check-status endpoint every 5-10 seconds.
Error
{
"error": "Insufficient credits",
"errorCode": "INSUFFICIENT_CREDITS",
"requiredCredits": 8
}Check Task Status
POST /api/sora-2-tvc/check-statusHeaders
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer YOUR_API_KEY |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
recordId | string | Conditional | TVC record ID from generate response |
taskId | string | Conditional | Video task ID from generate response |
Provide either recordId or taskId. Using recordId is recommended.
Example
curl -X POST "https://nanophoto.ai/api/sora-2-tvc/check-status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{"recordId": "tvc_record_id"}'Response
Step 1: Generating Storyboard Script
{
"success": true,
"status": "processing",
"recordId": "tvc_record_id",
"currentStep": 1,
"stepName": "Generating Storyboard Prompt"
}Step 2: Generating Storyboard Image
{
"success": true,
"status": "processing",
"recordId": "tvc_record_id",
"currentStep": 2,
"stepName": "Generating Storyboard",
"storyboardPrompt": "..."
}Step 3: Generating Video
{
"success": true,
"status": "processing",
"recordId": "tvc_record_id",
"currentStep": 3,
"stepName": "Generating Ad Video",
"storyboardPrompt": "...",
"storyboardImageUrl": "https://static.nanophoto.ai/images/sora-tvc/storyboard-xxx.png",
"videoTaskProgress": "generating"
}Completed
{
"success": true,
"status": "completed",
"recordId": "tvc_record_id",
"currentStep": 3,
"stepName": "Completed",
"storyboardPrompt": "...",
"storyboardImageUrl": "https://static.nanophoto.ai/images/sora-tvc/storyboard-xxx.png",
"videoUrl": "https://video.nanophoto.ai/sora/...",
"generationTime": 180
}Failed
{
"success": false,
"status": "failed",
"error": "Video generation failed",
"errorCode": "GENERATION_FAILED",
"recordId": "tvc_record_id"
}Polling Strategy
- Poll
/api/sora-2-tvc/check-statusevery 5-10 seconds - Typical generation time: 2-5 minutes (3-step pipeline: script → storyboard → video)
- Credits are automatically refunded if generation fails
Error Codes
| errorCode | HTTP Status | Description |
|---|---|---|
LOGIN_REQUIRED | 401 | Authentication required |
API_KEY_RATE_LIMIT_EXCEEDED | 429 | Rate limit exceeded (100 req/hour) |
INSUFFICIENT_CREDITS | 402 | Not enough credits |
INVALID_INPUT | 400 | Missing ad theme |
REFERENCE_IMAGE_URL_REQUIRED | 400 | API calls require referenceImageUrl (no base64) |
GENERATION_FAILED | 500 | TVC ad generation failed |
RECORD_NOT_FOUND | 404 | TVC record not found |
UNAUTHORIZED | 403 | Record not owned by user |
INTERNAL_ERROR | 500 | Internal server error |
Documentação NanoPhoto.AI