Getting Started

Quickstart

Create your first AI-generated video in under 5 minutes. This guide walks you through authentication, creating a character, and generating a video.

Prerequisites

You'll need a Twin.Actor account to get started. Sign up for free to receive your initial credits.

Step 1: Get Your Access Token

First, authenticate to get your access token. You can do this via the login endpoint:

bash
curl -X POST https://api.twin.actor/api/v1/auth/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=your@email.com&password=your_password"

Response:

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}
Save this token! You'll use it in the Authorization header for all subsequent requests.

Step 2: Create a Person (Character)

A "Person" represents the character that will appear in your videos. Upload a photo to create one:

bash
curl -X POST https://api.twin.actor/api/v1/persons \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alex Chen",
    "description": "Tech startup founder",
    "photo_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
  }'

Response:

json
{
  "id": 1,
  "name": "Alex Chen",
  "description": "Tech startup founder",
  "photo_url": "https://storage.twin.actor/persons/1/photo.jpg",
  "has_voice": false,
  "created_at": "2024-03-20T10:00:00Z"
}

Step 3: Clone a Voice (Optional)

To add narration to your videos, clone a voice from an audio sample:

bash
curl -X POST https://api.twin.actor/api/v1/voice-clone/clone \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "person_id=1" \
  -F "provider=elevenlabs" \
  -F "audio_file=@voice_sample.mp3"
Voice cloning takes 1-2 minutes. The person's has_voice field will become true when ready. You can also use the default narrator voice if you don't want to clone a voice.

Step 4: Create a Scene Project

Now let's create a video! Start by proposing a story idea:

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 day in the life of a startup founder building the next big AI product",
    "num_scenes": 5
  }'

The API will generate scene breakdowns with prompts, narration, and descriptions:

json
{
  "id": 42,
  "status": "proposed",
  "story_idea": "A day in the life of a startup founder...",
  "scenes": [
    {
      "scene_number": 1,
      "description": "Early morning, founder coding in a dimly lit home office",
      "image_prompt": "Photorealistic, developer at desk with multiple monitors...",
      "motion_prompt": "Slow push-in, screen glow flickering...",
      "narration_text": "Every great company starts with a single line of code..."
    }
    // ... more scenes
  ]
}

Step 5: Approve and Generate

Review the proposed scenes, then approve to start generation:

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"
  }'

Step 6: Poll for Status

Video generation takes 5-15 minutes depending on the number of scenes. Poll for status:

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

Status response during generation:

json
{
  "id": 42,
  "status": "processing",
  "progress": 65,
  "current_step": "generating_videos",
  "scenes_status": [
    { "scene_number": 1, "image_status": "completed", "video_status": "completed" },
    { "scene_number": 2, "image_status": "completed", "video_status": "completed" },
    { "scene_number": 3, "image_status": "completed", "video_status": "processing" },
    { "scene_number": 4, "image_status": "completed", "video_status": "pending" },
    { "scene_number": 5, "image_status": "completed", "video_status": "pending" }
  ]
}

When complete:

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

Complete Example

Here's a complete Python script that creates a video from start to finish:

create_video.py
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162"text-violet-400">import requests
"text-violet-400">import base64
"text-violet-400">import time

# Configuration
API_BASE = "https://api.twin.actor/api/v1"
EMAIL = "your@email.com"
PASSWORD = "your_password"

# 1. Login
auth = requests.post(f"{API_BASE}/auth/login", data={
    "username": EMAIL,
    "password": PASSWORD
}).json()
token = auth["access_token"]
headers = {"Authorization": f"Bearer {token}"}

# 2. Create person
"text-violet-400">with open("founder_photo.jpg", "rb") "text-violet-400">as f:
    photo_b64 = base64.b64encode(f.read()).decode()

person = requests.post(f"{API_BASE}/persons", headers=headers, json={
    "name": "Alex Chen",
    "description": "Tech startup founder",
    "photo_base64": f"data:image/jpeg;base64,{photo_b64}"
}).json()
print(f"Created person: {person['id']}")

# 3. Create project
project = requests.post(f"{API_BASE}/stories/create", headers=headers, json={
    "person_id": person["id"],
    "story_idea": "A startup founder's journey ">from idea to product launch",
    "num_scenes": 5
}).json()
print(f"Created project ">with {len(project['scenes'])} scenes")

# 4. Approve "text-violet-400">and start generation
requests.post(
    f"{API_BASE}/scene-projects/{project['id']}/approve",
    headers=headers,
    json={"confirm_credits": "text-violet-400">True, "video_model": "kling-2.6-pro"}
)
print("Generation started...")

# 5. Wait "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']}% - {status.get('current_step', '')}")

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

    time.sleep(30)

Next Steps

1

Explore the API Reference

Learn about all available endpoints and their parameters.

2

Set up Webhooks

Get notified when your videos are ready instead of polling.

3

Try Avatar Projects

Create talking-head videos with voice-controlled lip-sync.