API Reference

Scene Projects API

Scene Projects are multi-scene cinematic videos with AI-generated imagery, motion, and narration. Each scene is 10 seconds, and projects can have 2-10 scenes.

Async Generation

Video generation is asynchronous. After approval, poll the status endpoint or configure webhooks to know when your video is ready. Generation typically takes 5-15 minutes.

The Scene Project Object

json
{
  "id": 42,
  "description": "A tech startup journey",
  "ideas": "From garage to IPO",
  "status": "completed",
  "progress": 100,
  "person_id": 1,
  "user_id": 1,
  "final_video_url": "https://storage.twin.actor/videos/project_42_final.mp4",
  "final_video_url_upscaled": null,
  "total_duration_seconds": 50,
  "use_avatar_first_scene": false,
  "use_avatar_last_scene": false,
  "scenes": [
    {
      "id": 1,
      "scene_number": 1,
      "description": "Founder coding in garage",
      "image_prompt": "Photorealistic, developer at desk...",
      "motion_prompt": "Slow push-in, screen glow...",
      "narration_text": "Every great company starts...",
      "image_url": "https://storage.twin.actor/scenes/1/image.jpg",
      "video_url": "https://storage.twin.actor/scenes/1/video.mp4",
      "status": "completed"
    }
  ],
  "created_at": "2024-03-20T10:00:00Z",
  "updated_at": "2024-03-20T10:15:00Z"
}

Project Status Values

StatusDescription
draftInitial state, not yet proposed
creatingAI is generating scene proposals
proposedScenes ready for review/approval
generatingVideo generation in progress
completedVideo ready for download
failedGeneration failed (see error)

Create Project (Story)

POST/stories/create

Create a new scene project with AI-generated scene proposals

Request Body

NameTypeDescription
person_idrequiredintegerID of the person/character
story_idearequiredstringDescription of the video story (10-1000 chars)
num_scenesintegerNumber of scenes (2-10)(default: 5)
use_avatar_first_scenebooleanUse talking-head for first scene
use_avatar_last_scenebooleanUse talking-head for last scene
bash
curl -X POST https://api.twin.actor/api/v1/stories/create \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "person_id": 1,
    "story_idea": "A startup founder\'s journey from coding in a garage to ringing the IPO bell at NASDAQ. Show the highs and lows of building a company.",
    "num_scenes": 5
  }'

Response:

json
{
  "id": 42,
  "status": "proposed",
  "story_idea": "A startup founder's journey...",
  "num_scenes": 5,
  "person_id": 1,
  "scenes": [
    {
      "scene_number": 1,
      "description": "Late night in a cramped garage, a determined founder writes the first lines of code",
      "image_prompt": "Photorealistic, young entrepreneur coding at a makeshift desk in a garage, multiple monitors glowing blue, scattered energy drink cans, dim lighting, cinematic, 8K",
      "motion_prompt": "Slow push-in towards the screen, flickering monitor light, subtle keyboard typing motion",
      "narration_text": "Every billion-dollar company starts with a single line of code. This is where the dream began.",
      "status": "pending"
    },
    {
      "scene_number": 2,
      "description": "The first team meeting in a small apartment, whiteboard covered in ideas",
      "image_prompt": "Photorealistic, small team of developers in a living room, whiteboard with startup diagrams, excited expressions, laptops everywhere, natural lighting, cinematic",
      "motion_prompt": "Pan across the whiteboard, zoom into faces showing determination",
      "narration_text": "Three developers, one apartment, and a vision that would change everything.",
      "status": "pending"
    }
    // ... more scenes
  ],
  "created_at": "2024-03-20T10:00:00Z"
}
201Project created with scene proposals
400Invalid story idea or parameters
404Person not found

List Projects

GET/scene-projects

List all scene projects for the current user

Query Parameters

NameTypeDescription
person_idintegerFilter by person
status_filterstringFilter by status
bash
curl "https://api.twin.actor/api/v1/scene-projects?status_filter=completed" \
  -H "Authorization: Bearer YOUR_TOKEN"

Get Project

GET/scene-projects/{id}

Get a specific project with all scene details

bash
curl https://api.twin.actor/api/v1/scene-projects/42 \
  -H "Authorization: Bearer YOUR_TOKEN"

Update Scene

PUT/scene-projects/{project_id}/scenes/{scene_id}

Update a scene's prompts before approval

Request Body

NameTypeDescription
descriptionstringScene description
image_promptstringImage generation prompt
motion_promptstringVideo motion prompt
narration_textstringNarration text
bash
curl -X PUT https://api.twin.actor/api/v1/scene-projects/42/scenes/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "narration_text": "Updated narration for scene 1...",
    "image_prompt": "Enhanced prompt with more detail..."
  }'

Approve and Generate

POST/scene-projects/{id}/approve

Approve the project and start video generation

Request Body

NameTypeDescription
confirm_creditsrequiredbooleanAcknowledge credit deduction
video_modelstringVideo model to use(default: kling-2.6-pro)
image_modelstringImage model to use(default: flux-pro)

Credit Deduction

Approving a project will immediately reserve credits based on the number of scenes. Each scene costs approximately 100 credits (10 seconds × 10 credits/second). A 5-scene video costs ~500 credits.
bash
curl -X POST https://api.twin.actor/api/v1/scene-projects/42/approve \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "confirm_credits": true,
    "video_model": "kling-2.6-pro"
  }'

Response:

json
{
  "id": 42,
  "status": "generating",
  "progress": 0,
  "message": "Video generation started. Use GET /scene-projects/42/status to track progress."
}
202Generation started
400Project not in proposed state
403Insufficient credits

Check Status

GET/scene-projects/{id}/status

Get real-time generation progress

bash
curl https://api.twin.actor/api/v1/scene-projects/42/status \
  -H "Authorization: Bearer YOUR_TOKEN"

Response (in progress):

json
{
  "id": 42,
  "status": "generating",
  "progress": 65,
  "current_step": "generating_scene_videos",
  "scenes": [
    {
      "scene_number": 1,
      "image_status": "completed",
      "video_status": "completed",
      "image_url": "https://storage.twin.actor/scenes/1/image.jpg",
      "video_url": "https://storage.twin.actor/scenes/1/video.mp4"
    },
    {
      "scene_number": 2,
      "image_status": "completed",
      "video_status": "completed"
    },
    {
      "scene_number": 3,
      "image_status": "completed",
      "video_status": "generating"
    },
    {
      "scene_number": 4,
      "image_status": "completed",
      "video_status": "pending"
    },
    {
      "scene_number": 5,
      "image_status": "completed",
      "video_status": "pending"
    }
  ]
}

Response (completed):

json
{
  "id": 42,
  "status": "completed",
  "progress": 100,
  "final_video_url": "https://storage.twin.actor/videos/project_42_final.mp4",
  "total_duration_seconds": 50,
  "credits_used": 500
}

Regenerate Scene

POST/scene-projects/{project_id}/scenes/{scene_number}/regenerate

Regenerate a single scene's image and/or video

Request Body

NameTypeDescription
regenerate_imagebooleanRegenerate the image(default: true)
regenerate_videobooleanRegenerate the video(default: true)
updated_image_promptstringNew image prompt
updated_motion_promptstringNew motion prompt
bash
curl -X POST https://api.twin.actor/api/v1/scene-projects/42/scenes/3/regenerate \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "regenerate_image": true,
    "regenerate_video": true,
    "updated_image_prompt": "More dramatic lighting, intense expression..."
  }'
Regenerating a scene costs additional credits. The final video will be re-stitched automatically after the scene is regenerated.

Upscale Video

POST/scene-projects/{id}/upscale

Upscale the final video to higher resolution

bash
curl -X POST https://api.twin.actor/api/v1/scene-projects/42/upscale \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

json
{
  "id": 42,
  "status": "upscaling",
  "message": "Upscaling started. This may take 5-10 minutes."
}

Free Upscaling

Video upscaling is currently FREE for a limited time! The upscaled video URL will be available at final_video_url_upscaled.

Polling Example

Here's a complete example that creates a project and polls until completion:

python
123456789101112131415161718192021222324252627282930313233343536373839404142434445"text-violet-400">import requests
"text-violet-400">import time

API_BASE = "https://api.twin.actor/api/v1"
headers = {"Authorization": f"Bearer {token}"}

# Create project
project = requests.post(
    f"{API_BASE}/stories/create",
    headers=headers,
    json={
        "person_id": 1,
        "story_idea": "A day ">in the life of a startup founder",
        "num_scenes": 5
    }
).json()

project_id = project["id"]
print(f"Created project {project_id}")

# Approve
requests.post(
    f"{API_BASE}/scene-projects/{project_id}/approve",
    headers=headers,
    json={"confirm_credits": "text-violet-400">True}
)
print("Generation started")

# Poll "text-violet-400">for completion
"text-violet-400">while "text-violet-400">True:
    status = requests.get(
        f"{API_BASE}/scene-projects/{project_id}/status",
        headers=headers
    ).json()

    print(f"Progress: {status['progress']}%")

    "text-violet-400">if status["status"] == "completed":
        print(f"\nDone! Video: {status['final_video_url']}")
        break
    "text-violet-400">elif status["status"] == "failed":
        print(f"\nFailed: {status.get('error')}")
        break

    time.sleep(30)  # Poll every 30 seconds