Story (Legacy)

[AUTO] Idea-to-Video

Creates a complete video automatically from a text idea using AI-powered story generation.

Workflow

Once submitted, Vimmerse automatically executes the following pipeline:

  1. Storyboard Generation - Creates a structured storyboard with characters, environments, objects, and scenes
  2. Element Image Creation - Generates consistent character, object, and environment images
  3. Scene Image Generation - Produces scene images based on the storyboard
  4. Narration Generation - Creates voice narrations for each scene (if enabled)
  5. Background Music - Generates appropriate background music (if enabled)
  6. Video Animation - Animates images into videos using the specified video tool
  7. Video Composition - Composes all scene videos into a final story video

Response

The API returns a story object containing:

  • id - Unique story identifier for tracking progress
  • status - Current processing status (new, processing, success, fail)
  • progress_percentage - Completion percentage (0-100)
  • video_url - Final video URL (available when status is success)

Monitor progress using GET /story/{story_id} or configure a webhook_url for automatic notifications.

Parameters

Parameter Type Required Default Description
idea string Yes - Detailed text description of your story concept. Be specific about characters, settings, actions, and style.
scene_count integer No 3 Number of scenes to generate. Maximum varies by subscription plan.
image_tool string No "AutoI" Image generation model. Options: AutoI, Seedream, FluxTurbo, NanoBanana, QwenImage
video_tool string No "Auto" Animation method. Options: Auto, KlingAI, VeoFast, Pixverse, Seedance, Vidu, AutoT1, VeoLite, PVideo.
scene_duration integer No 5 Duration per scene in seconds: 5 or 10. Ignored when narration is enabled.
aspect_ratio string No "16:9" Video aspect ratio. Options: 16:9, 4:3, 1:1, 3:4, 9:16
is_transition boolean No false If true, creates transition videos between scene images.
elements object No null Initial elements: { "objects": [...], "characters": [...], "environments": [...] }. Useful for product placement or character consistency.
audio_option object No { "has_bg_music": true, "has_narration": true, "native_audio": false, "narrator": "AutoV" } Audio configuration: has_bg_music, has_narration, native_audio, narrator.
language string No "English" Language for narration and storyboard generation.
title string No "" Optional title for your story.
webhook_url string No null URL to receive completion notification via POST request.

The API accepts JSON body (Content-Type: application/json).

Example Request

import requests

url = "https://api.vimmerse.net/story/idea-2-video"
headers = {"X-Api-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

payload = {
    "idea": "Create a realistic winter commercial for SkinRevive Moisturiser set in snowy mountains. Three girls are on a winter camping trip. Show two girls outside the camp, dressed in warm jackets, taking fun photos together in the snowy mountains. Soft snowfall, visible cold breath, playful interaction. Meanwhile, one girl is sitting inside the tent, wrapped in a blanket, looking hesitant and afraid to step outside because of the cold and her dry, irritated hands. She peeks out while the others call her to join, but she hesitates. Then one girl comes inside the tent, sits with her, smiles, and shows SkinRevive Moisturiser. She gently applies it on her friend's dry hands. Show close-up macro shots: smooth creamy texture, instant hydration, natural skin transformation. The inside girl now feels confident. She steps outside slowly, smiles, and joins her friends. Show them laughing, posing, and taking photos of each other against the beautiful snowy mountain background. Natural warm emotions, winter glow, soft daylight. End with a clean hero shot of SkinRevive Moisturiser placed on a wooden camping table with snowflakes falling softly around it. Cinematic, high-detail, warm winter storytelling mood.",
    "title": "SkinRevive Winter Commercial",
    "aspect_ratio": "9:16",
    "scene_count": 5,
    "image_tool": "Seedream",
    "video_tool": "Auto",
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": False, "native_audio": True},
    "elements": {
        "objects": [
            {
                "name": "SkinRevive Moisturiser",
                "description": "Style:cinematic, In a sleek glass jar with a frosted finish and an elegant silver lid. The luxurious cream has a marbled white color, giving an aura of purity and soothing relief. Its rich formulation is the solution to winter's touch.",
                "image_url": "https://dev-media.vimmerse.net/vimmerse-product/ai_images/4a6b359a-c347-4453-a6ff-109cd8616dc4/8i9vvs4.png"
            }
        ]
    },
    "language": "English",
}

try:
    response = requests.post(url, headers=headers, json=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    print(f"Story ID: {story_data['id']}")
    print(f"Status: {story_data['status']}")
    print(f"Used Credits: {story_data['used_credits']}")

except requests.exceptions.HTTPError as e:
    print(f"HTTP Error: {e}")
    print(f"Response: {e.response.text}")
except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")

Complete Example with Polling

This complete example creates a story, polls for completion, and downloads the final video:

import requests
import json
import time

BASE_URL = "https://api.vimmerse.net"
API_KEY = "YOUR_API_KEY"

# Step 1: Create the story (JSON body)
url = f"{BASE_URL}/story/idea-2-video"
headers = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}

payload = {
    "idea": "Create a realistic winter commercial for SkinRevive Moisturiser set in snowy mountains. Three girls are on a winter camping trip. Show two girls outside the camp, dressed in warm jackets, taking fun photos together in the snowy mountains. Soft snowfall, visible cold breath, playful interaction. Meanwhile, one girl is sitting inside the tent, wrapped in a blanket, looking hesitant and afraid to step outside because of the cold and her dry, irritated hands. She peeks out while the others call her to join, but she hesitates. Then one girl comes inside the tent, sits with her, smiles, and shows SkinRevive Moisturiser. She gently applies it on her friend's dry hands. Show close-up macro shots: smooth creamy texture, instant hydration, natural skin transformation. The inside girl now feels confident. She steps outside slowly, smiles, and joins her friends. Show them laughing, posing, and taking photos of each other against the beautiful snowy mountain background. Natural warm emotions, winter glow, soft daylight. End with a clean hero shot of SkinRevive Moisturiser placed on a wooden camping table with snowflakes falling softly around it. Cinematic, high-detail, warm winter storytelling mood.",
    "title": "SkinRevive Winter Commercial",
    "aspect_ratio": "9:16",
    "scene_count": 5,
    "image_tool": "Seedream",
    "video_tool": "Auto",
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": False, "native_audio": True},
    "language": "English"
}

print("Creating story...")
try:
    response = requests.post(url, headers=headers, json=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]
    story_id = story_data["id"]

    print(f"✓ Story created successfully!")
    print(f"  Story ID: {story_id}")
    print(f"  Status: {story_data['status']}")
    print(f"  Used Credits: {story_data['used_credits']}")

except requests.exceptions.HTTPError as e:
    print(f"✗ HTTP Error: {e}")
    if e.response is not None:
        print(f"  Response: {e.response.text}")
    exit(1)
except requests.exceptions.RequestException as e:
    print(f"✗ Request failed: {e}")
    exit(1)

# Step 2: Poll for completion
print("\nPolling for story completion...")
max_attempts = 120  # Maximum 60 minutes (120 * 30 seconds)
attempt = 0
poll_interval = 30  # Check every 30 seconds

def get_story_status(story_id):
    """Retrieve the current status of a story."""
    url = f"{BASE_URL}/story/{story_id}"
    headers = {"X-Api-Key": API_KEY}

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        return response.json()["data"]
    except requests.exceptions.RequestException as e:
        print(f"  Warning: Error retrieving status: {e}")
        return None

while attempt < max_attempts:
    story_data = get_story_status(story_id)

    if not story_data:
        print(f"  Attempt {attempt + 1}/{max_attempts}: Failed to retrieve status, retrying...")
        time.sleep(poll_interval)
        attempt += 1
        continue

    status = story_data.get("status")
    progress = story_data.get("progress_percentage", 0)

    print(f"  Attempt {attempt + 1}/{max_attempts}: Status={status}, Progress={progress}%")

    if status == "success":
        video_url = story_data.get("video_url")
        if video_url:
            print(f"\n✓ Story completed successfully!")
            print(f"  Video URL: {video_url}")

            # Step 3: Download the video
            print("\nDownloading video...")
            try:
                video_response = requests.get(video_url, stream=True, timeout=60)
                video_response.raise_for_status()

                output_path = "story_video.mp4"
                total_size = int(video_response.headers.get('content-length', 0))
                downloaded = 0

                with open(output_path, "wb") as f:
                    for chunk in video_response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                            downloaded += len(chunk)
                            if total_size > 0:
                                percent = (downloaded / total_size) * 100
                                print(f"  Download progress: {percent:.1f}%", end="\r")

                print(f"\n✓ Video downloaded successfully!")
                print(f"  Saved to: {output_path}")
                print(f"  File size: {downloaded / (1024 * 1024):.2f} MB")

            except Exception as e:
                print(f"\n✗ Error downloading video: {e}")
            break
        else:
            print("  Warning: Story completed but video_url is not available yet. Waiting...")
            time.sleep(poll_interval)
            attempt += 1
            continue
    elif status == "fail":
        print(f"\n✗ Story generation failed.")
        print(f"  Please check the story details for more information.")
        print(f"  Story ID: {story_id}")
        exit(1)

    time.sleep(poll_interval)
    attempt += 1

if attempt >= max_attempts:
    print(f"\n⚠ Timeout: Story generation is taking longer than expected.")
    print(f"  Story ID: {story_id}")
    print(f"  Please check the status later using: GET {BASE_URL}/story/{story_id}")

Error Handling

The API may return the following HTTP status codes:

  • 200 - Success. Story creation initiated.
  • 400 - Bad Request. Invalid parameters or missing required fields.
  • 402 - Payment Required. Insufficient credits in your account.
  • 429 - Too Many Requests. Rate limit exceeded or concurrency limit reached.
  • 500 - Internal Server Error. Please retry or contact support.
SecurityAPIKeyHeader
Request
Request Body schema: application/json
required
idea
required
string (Idea)

Detailed text description of your story concept.

scene_count
integer (Number of Scenes) >= 1
Default: 3
image_tool
string (Image Generation Model)
Default: "AutoI"
Enum: "AutoI" "Seedream" "FluxTurbo" "NanoBanana" "QwenImage"
video_tool
string (Video Animation Method)
Default: "Auto"
Enum: "Auto" "KlingAI" "Seedance" "Pixverse" "VeoFast" "Vidu" "AutoT1" "VeoLite" "PVideo"
scene_duration
integer (Scene Duration) [ 1 .. 20 ]
Default: 5

Duration per scene in seconds. The supported values vary based on video tool selected.

aspect_ratio
string (Aspect Ratio)
Default: "16:9"
Enum: "16:9" "4:3" "1:1" "3:4" "9:16"
is_transition
boolean (Enable Transitions)
Default: false
Story Elements (object) or Story Elements (null) (Story Elements)
Audio Configuration (object) or Audio Configuration (string) or Audio Configuration (null) (Audio Configuration)
language
string (Language)
Default: "English"
Enum: "Arabic" "Chinese" "English" "French" "German" "Hindi" "Japanese" "Korean" "Spanish" "Turkish"
title
string (Story Title)
Default: ""
webhook_url
string (Webhook URL)
Default: ""
Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

422

Validation Error

post/story/idea-2-video
Request samples
Response samples
application/json
{
  • "data": {
    }
}

[AUTO] URL-to-Video

Creates a complete video automatically from a website URL and idea prompt.

This endpoint analyzes the provided website URL and generates a video based on your idea description. It's ideal for creating marketing videos, product showcases, or brand commercials.

Workflow

The generation pipeline is identical to idea-2-video:

  1. Storyboard Generation - Creates a structured storyboard
  2. Element Image Creation - Generates consistent visual elements
  3. Scene Image Generation - Produces scene images
  4. Narration Generation - Creates voice narrations (if enabled)
  5. Background Music - Generates background music (if enabled)
  6. Video Animation - Animates images into videos
  7. Video Composition - Composes final story video

Parameters

Parameter Type Required Default Description
idea string Yes - Text description including the website URL. Example: "Create a marketing video for https://www.example.com highlighting their product features"
scene_count integer No 3 Number of scenes to generate
image_tool string No "Seedream" Image generation model
video_tool string No "Auto" Animation method
scene_duration integer No 5 Duration per scene in seconds: 5 or 10
aspect_ratio string No "16:9" Video aspect ratio
is_transition boolean No false Enable transition videos between scenes
elements object No null Initial elements: { "objects": [...], "characters": [...], "environments": [...] }
audio_option object No See audio options Audio configuration
language string No "English" Narration language
title string No "" Story title
webhook_url string No null Webhook URL for completion notification

The API accepts JSON body (Content-Type: application/json).

Example Request

import requests

url = "https://api.vimmerse.net/story/url-2-video"
headers = {"X-Api-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

payload = {
    "idea": "Create a marketing video for https://www.vimmerse.net/ highlighting the AI Video production capabilities on platform using best AI image and video tools. Showcase the platform's features, user interface, and generated video examples.",
    "title": "Vimmerse Platform Showcase",
    "aspect_ratio": "16:9",
    "scene_count": 3,
    "image_tool": "Seedream",
    "video_tool": "Auto",
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": True, "native_audio": False, "narrator": "AutoV"},
    "elements": {
        "objects": [
            {
                "name": "Logo",
                "description": "Vimmerse Logo",
                "image_url": "https://distribution.vimmerse.net/presets/logo/vimmerse_logo.png"
            }
        ]
    },
    "language": "English"
}

try:
    response = requests.post(url, headers=headers, json=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    print(f"Story created: {result['data']['id']}")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Complete Example with Polling

This complete example creates a story from a URL, polls for completion, and downloads the final video:

import requests
import json
import time

BASE_URL = "https://api.vimmerse.net"
API_KEY = "YOUR_API_KEY"

# Step 1: Create the story (JSON body)
url = f"{BASE_URL}/story/url-2-video"
headers = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}

payload = {
    "idea": "Create a marketing video for https://www.vimmerse.net/ highlighting the AI Video production capabilities on platform using best AI image and video tools. Showcase the platform's features, user interface, and generated video examples.",
    "title": "Vimmerse Platform Showcase",
    "aspect_ratio": "16:9",
    "scene_count": 3,
    "image_tool": "Seedream",
    "video_tool": "Auto",
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": True, "native_audio": False, "narrator": "AutoV"},
    "language": "English"
}

print("Creating story from URL...")
try:
    response = requests.post(url, headers=headers, json=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]
    story_id = story_data["id"]

    print(f"✓ Story created successfully!")
    print(f"  Story ID: {story_id}")
    print(f"  Status: {story_data['status']}")
    print(f"  Used Credits: {story_data['used_credits']}")

except requests.exceptions.HTTPError as e:
    print(f"✗ HTTP Error: {e}")
    if e.response is not None:
        print(f"  Response: {e.response.text}")
    exit(1)
except requests.exceptions.RequestException as e:
    print(f"✗ Request failed: {e}")
    exit(1)

# Step 2: Poll for completion
print("\nPolling for story completion...")
max_attempts = 120  # Maximum 60 minutes
attempt = 0
poll_interval = 30  # Check every 30 seconds

def get_story_status(story_id):
    """Retrieve the current status of a story."""
    url = f"{BASE_URL}/story/{story_id}"
    headers = {"X-Api-Key": API_KEY}

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        return response.json()["data"]
    except requests.exceptions.RequestException as e:
        print(f"  Warning: Error retrieving status: {e}")
        return None

while attempt < max_attempts:
    story_data = get_story_status(story_id)

    if not story_data:
        print(f"  Attempt {attempt + 1}/{max_attempts}: Failed to retrieve status, retrying...")
        time.sleep(poll_interval)
        attempt += 1
        continue

    status = story_data.get("status")
    progress = story_data.get("progress_percentage", 0)

    print(f"  Attempt {attempt + 1}/{max_attempts}: Status={status}, Progress={progress}%")

    if status == "success":
        video_url = story_data.get("video_url")
        if video_url:
            print(f"\n✓ Story completed successfully!")
            print(f"  Video URL: {video_url}")

            # Step 3: Download the video
            print("\nDownloading video...")
            try:
                video_response = requests.get(video_url, stream=True, timeout=60)
                video_response.raise_for_status()

                output_path = "url_story_video.mp4"
                total_size = int(video_response.headers.get('content-length', 0))
                downloaded = 0

                with open(output_path, "wb") as f:
                    for chunk in video_response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                            downloaded += len(chunk)
                            if total_size > 0:
                                percent = (downloaded / total_size) * 100
                                print(f"  Download progress: {percent:.1f}%", end="\r")

                print(f"\n✓ Video downloaded successfully!")
                print(f"  Saved to: {output_path}")
                print(f"  File size: {downloaded / (1024 * 1024):.2f} MB")

            except Exception as e:
                print(f"\n✗ Error downloading video: {e}")
            break
        else:
            print("  Warning: Story completed but video_url is not available yet. Waiting...")
            time.sleep(poll_interval)
            attempt += 1
            continue
    elif status == "fail":
        print(f"\n✗ Story generation failed.")
        print(f"  Story ID: {story_id}")
        exit(1)

    time.sleep(poll_interval)
    attempt += 1

if attempt >= max_attempts:
    print(f"\n⚠ Timeout: Story generation is taking longer than expected.")
    print(f"  Story ID: {story_id}")
    print(f"  Please check the status later using: GET {BASE_URL}/story/{story_id}")
SecurityAPIKeyHeader
Request
Request Body schema: application/json
required
idea
required
string (URL)

URL of the webpage to scrape for content (e.g. product page, article).

scene_count
integer (Number of Scenes) >= 1
Default: 3
image_tool
string (Image Generation Model)
Default: "AutoI"
Enum: "AutoI" "Seedream" "FluxTurbo" "NanoBanana" "QwenImage"
video_tool
string (Video Animation Method)
Default: "Auto"
Enum: "Auto" "KlingAI" "Seedance" "Pixverse" "VeoFast" "Vidu" "AutoT1" "VeoLite" "PVideo"
scene_duration
integer (Scene Duration) [ 1 .. 20 ]
Default: 5

Duration per scene in seconds. The supported values vary based on video tool selected.

aspect_ratio
string (Aspect Ratio)
Default: "16:9"
Enum: "16:9" "4:3" "1:1" "3:4" "9:16"
is_transition
boolean (Enable Transitions)
Default: false
Story Elements (object) or Story Elements (null) (Story Elements)
Audio Configuration (object) or Audio Configuration (string) or Audio Configuration (null) (Audio Configuration)
language
string (Language)
Default: "English"
Enum: "Arabic" "Chinese" "English" "French" "German" "Hindi" "Japanese" "Korean" "Spanish" "Turkish"
title
string (Story Title)
Default: ""
webhook_url
string (Webhook URL)
Default: ""
Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

422

Validation Error

post/story/url-2-video
Request samples
Response samples
application/json
{
  • "data": {
    }
}

[AUTO] Images-to-Video

Generates a story video using both your idea and a set of existing images.

This endpoint is ideal when you want to:

  • Maintain character consistency using your own images
  • Use a specific art style as reference
  • Animate existing artwork or product photos
  • Create videos from a series of related images

Workflow

  1. Accepts Images - Takes your provided images and idea description
  2. Generates Narrations - Creates appropriate voice narrations for each scene (if enabled)
  3. Creates Background Music - Generates matching background music (if enabled)
  4. Animates Images - Converts each image into an animated video with motion
  5. Composes Final Video - Combines all scene videos into a final story video

Parameters

Parameter Type Required Default Description
idea string Yes - Text description of your story concept
image_urls array[string] Yes [] Array of publicly accessible image URLs. URLs must be accessible without authentication.
video_tool string No "Auto" Animation method
is_transition boolean No false Create transition videos between scenes
scene_duration integer No 5 Duration per scene in seconds: 5 or 10
aspect_ratio string No "16:9" Video aspect ratio
audio_option object No { "has_bg_music": true, "has_narration": true, "native_audio": false, "narrator": "AutoV" } Audio configuration
language string No "English" Narration language
title string No "" Story title
webhook_url string No null Webhook URL for completion notification

image_urls is required.

Audio Option Usage Examples

Example 1: Background Music Only

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": false
}

Example 2: Narration with Background Music

{
    "has_bg_music": true,
    "has_narration": true,
    "native_audio": false,
    "narrator": "Rachel"
}

Example 3: Native Audio (Sound Effects + Lip Sync)

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": true
}

Example 4: No Audio

{
    "has_bg_music": false,
    "has_narration": false,
    "native_audio": false
}

Available narrators: AutoV, Rachel, Aria, Roger, Sarah, Laura, Charlie, George, Callum, River, Liam, Charlotte, Alice, Matilda, Will, Jessica, Eric, Chris, Brian, Daniel, Lily, Bill

The API accepts JSON body (Content-Type: application/json) for the easiest client experience. Simply send a JSON object with your parameters:

import requests

url = "https://api.vimmerse.net/story/images-2-video"
headers = {
    "X-Api-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
}

payload = {
    "idea": "Cinematic product-only smoothie promo: fresh berries, bananas, and oranges falling onto rustic wooden table in slow-motion, glass blender mixing fruits with smoothie swirling inside, smoothie pouring from blender into glass with condensation, pink smoothie glass showcased on wooden table in top-down and angled shots, cinematic lighting, photorealistic textures, colorful and vibrant, no humans, final branding overlay with tagline 'Freshness in Every Sip', 16:9, consistent warm cinematic glow across all scenes",
    "image_urls": [
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101637_7c5ygv.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101654_jpj5wi.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101711_3tw2er.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101742_vkcfl9.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101802_75q49f.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101837_jhqbhc.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_102132_s8xzfv.jpg",
    ],
    "title": "Promo Video Showcase",
    "aspect_ratio": "16:9",
    "video_tool": "Auto",
    "is_transition": True,
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": True, "native_audio": False},
    "language": "English",
}

response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()

result = response.json()
story_data = result["data"]
print(f"Story created! ID: {story_data['id']}, Scenes: {story_data.get('scene_count', len(payload['image_urls']))}")

Complete Example with Polling

This complete example creates a story from images, polls for completion, and downloads the final video:

import requests
import json
import time

BASE_URL = "https://api.vimmerse.net"
API_KEY = "YOUR_API_KEY"

# Step 1: Create the story from images (JSON body)
url = f"{BASE_URL}/story/images-2-video"
headers = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}

payload = {
    "idea": "Cinematic product-only smoothie promo: fresh berries, bananas, and oranges falling onto rustic wooden table in slow-motion, glass blender mixing fruits with smoothie swirling inside, smoothie pouring from blender into glass with condensation, pink smoothie glass showcased on wooden table in top-down and angled shots, cinematic lighting, photorealistic textures, colorful and vibrant, no humans, final branding overlay with tagline 'Freshness in Every Sip', 16:9, consistent warm cinematic glow across all scenes",
    "image_urls": [
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101637_7c5ygv.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101654_jpj5wi.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101711_3tw2er.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101742_vkcfl9.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101802_75q49f.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_101837_jhqbhc.jpg",
        "https://media.vimmerse.net/vimmerse-product/assets/a979b86e-abf2-476e-b1ec-3a13657caee9/uploads/20250924_102132_s8xzfv.jpg",
    ],
    "title": "Promo Video Showcase",
    "aspect_ratio": "16:9",
    "video_tool": "Auto",
    "is_transition": True,
    "scene_duration": 5,
    "audio_option": {"has_bg_music": True, "has_narration": True, "native_audio": False},
    "language": "English",
}

print("Creating story from images...")
try:
    response = requests.post(url, headers=headers, json=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]
    story_id = story_data["id"]

    print(f"✓ Story created successfully!")
    print(f"  Story ID: {story_id}")
    print(f"  Status: {story_data['status']}")
    print(f"  Scenes: {story_data.get('scene_count', len(payload['image_urls']))}")
    print(f"  Used Credits: {story_data['used_credits']}")

except requests.exceptions.HTTPError as e:
    print(f"✗ HTTP Error: {e}")
    if e.response is not None:
        print(f"  Response: {e.response.text}")
    exit(1)
except requests.exceptions.RequestException as e:
    print(f"✗ Request failed: {e}")
    exit(1)

# Step 2: Poll for completion
print("\nPolling for story completion...")
max_attempts = 120  # Maximum 60 minutes
attempt = 0
poll_interval = 30  # Check every 30 seconds

def get_story_status(story_id):
    """Retrieve the current status of a story."""
    url = f"{BASE_URL}/story/{story_id}"
    headers = {"X-Api-Key": API_KEY}

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        return response.json()["data"]
    except requests.exceptions.RequestException as e:
        print(f"  Warning: Error retrieving status: {e}")
        return None

while attempt < max_attempts:
    story_data = get_story_status(story_id)

    if not story_data:
        print(f"  Attempt {attempt + 1}/{max_attempts}: Failed to retrieve status, retrying...")
        time.sleep(poll_interval)
        attempt += 1
        continue

    status = story_data.get("status")
    progress = story_data.get("progress_percentage", 0)

    print(f"  Attempt {attempt + 1}/{max_attempts}: Status={status}, Progress={progress}%")

    if status == "success":
        video_url = story_data.get("video_url")
        if video_url:
            print(f"\n✓ Story completed successfully!")
            print(f"  Video URL: {video_url}")

            # Step 3: Download the video
            print("\nDownloading video...")
            try:
                video_response = requests.get(video_url, stream=True, timeout=60)
                video_response.raise_for_status()

                output_path = "images_story_video.mp4"
                total_size = int(video_response.headers.get('content-length', 0))
                downloaded = 0

                with open(output_path, "wb") as f:
                    for chunk in video_response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                            downloaded += len(chunk)
                            if total_size > 0:
                                percent = (downloaded / total_size) * 100
                                print(f"  Download progress: {percent:.1f}%", end="\r")

                print(f"\n✓ Video downloaded successfully!")
                print(f"  Saved to: {output_path}")
                print(f"  File size: {downloaded / (1024 * 1024):.2f} MB")

            except Exception as e:
                print(f"\n✗ Error downloading video: {e}")
            break
        else:
            print("  Warning: Story completed but video_url is not available yet. Waiting...")
            time.sleep(poll_interval)
            attempt += 1
            continue
    elif status == "fail":
        print(f"\n✗ Story generation failed.")
        print(f"  Story ID: {story_id}")
        exit(1)

    time.sleep(poll_interval)
    attempt += 1

if attempt >= max_attempts:
    print(f"\n⚠ Timeout: Story generation is taking longer than expected.")
    print(f"  Story ID: {story_id}")
    print(f"  Please check the status later using: GET {BASE_URL}/story/{story_id}")

Image Requirements

  • Format: JPEG, PNG, WebP
  • Size: Recommended minimum 1024x1024 pixels
  • Aspect Ratio: Images will be cropped/resized to match the specified aspect_ratio
  • Accessibility: Image URLs must be publicly accessible (no authentication required)

Error Handling

  • 400 - Missing required parameters (idea or images)
  • 402 - Insufficient credits
  • 429 - Rate limit or concurrency limit exceeded
SecurityAPIKeyHeader
Request
Request Body schema: application/json
required
idea
string (Idea)
Default: "Create a stunning video showcasing these images with a compelling narrative"

Text description of your story concept.

image_urls
required
Array of strings (Image URLs) non-empty

Array of publicly accessible image URLs. Required.

video_tool
string (Video Animation Method)
Default: "Auto"
Enum: "Auto" "KlingAI" "Seedance" "Pixverse" "VeoFast" "Vidu" "AutoT1" "VeoLite" "PVideo"
is_transition
boolean (Enable Transitions)
Default: false
scene_duration
integer (Scene Duration) [ 1 .. 20 ]
Default: 5

Duration per scene in seconds. The supported values vary based on video tool selected.

aspect_ratio
string (Aspect Ratio)
Default: "16:9"
Enum: "16:9" "4:3" "1:1" "3:4" "9:16"
Audio Configuration (object) or Audio Configuration (string) or Audio Configuration (null) (Audio Configuration)

JSON object: {has_bg_music, has_narration, native_audio, narrator}

language
string (Language)
Default: "English"
Enum: "Arabic" "Chinese" "English" "French" "German" "Hindi" "Japanese" "Korean" "Spanish" "Turkish"
title
string (Story Title)
Default: ""
webhook_url
string (Webhook URL)
Default: ""
Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

422

Validation Error

post/story/images-2-video
Request samples
Response samples
application/json
{
  • "data": {
    }
}

[ADVANCED] Step 1 - Create Storyboard

Creates a new storyboard (Step 1 of Advanced Mode) based on your idea and/or images.

This is the first step in the Advanced Mode workflow, providing granular control over the story generation process.

What It Does

  • Generates Storyboard - Creates a complete storyboard structure with:
    • Characters with detailed descriptions
    • Environments (settings/locations)
    • Objects (props, items)
    • Scenes with image descriptions, narrations, and camera movements
  • Creates Narrations - Generates voice-over text for each scene
  • Defines Camera Work - Specifies camera angles and movements for each scene
  • Sets Audio Options - Configures background music and narration settings

Next Steps

After creating the storyboard, proceed with:

  1. Optional: POST /story/{story_id}/elements - Generate element images for visual consistency
  2. Required: POST /story/{story_id}/scenes - Generate scene images and narrations
  3. Required: POST /story/{story_id}/videos - Create videos from the scenes

Parameters

Parameter Type Required Default Description
idea string Yes - Your story concept or narrative
scene_count integer No 3 Number of scenes to generate. Ignored if images are provided.
language string No "English" Language for storyboard generation
audio_option string (JSON) No { "has_bg_music": true, "has_narration": true, "native_audio": false, "narrator": "AutoV" } Audio configuration
elements string (JSON) No null Pre-defined elements (characters, objects, environments)
image_urls array[string] No [] Array of image URLs. If provided, scene_count matches image count.
image_files array[file] No [] Upload image files directly. Alternative to image_urls.
story_id string No null Story ID to continue from (for editing existing stories)

Default Audio Options

{
    "has_bg_music": true,
    "has_narration": true,
    "native_audio": false,
    "narrator": "AutoV"
}

Example 1: Create Storyboard from Idea

import requests
import json

url = "https://api.vimmerse.net/story"
headers = {"X-Api-Key": "YOUR_API_KEY"}

payload = {
    "idea": "Create a promotional video where cute animals play musical instruments in a sunny meadow",
    "scene_count": 3,
    "title": "Musical Animals",
    "language": "English",
    "audio_option": json.dumps({
        "has_bg_music": True,
        "has_narration": True,
        "native_audio": False,
        "narrator": "AutoV"
    })
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]
    story_id = story_data["id"]

    print(f"Storyboard created! Story ID: {story_id}")
    print(f"Scenes: {len(story_data.get('storyboard', {}).get('scenes', []))}")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Example 2: Create Storyboard with Images

import requests

url = "https://api.vimmerse.net/story"
headers = {"X-Api-Key": "YOUR_API_KEY"}

payload = {
    "idea": "Create a promotional video showcasing these beautiful landscapes",
    "title": "Landscape Story",
    "image_urls": [
        "https://example.com/images/landscape1.jpg",
        "https://example.com/images/landscape2.jpg",
        "https://example.com/images/landscape3.jpg"
    ]
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    # Scene count automatically matches number of images
    print(f"Storyboard created with {len(story_data.get('storyboard', {}).get('scenes', []))} scenes")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Note: When providing images, the scene_count parameter is ignored, and scenes are generated based on the number of images provided.

SecurityAPIKeyHeader
Request
Request Body schema: multipart/form-data
required
story_id
string (Story ID)

Optional story ID to continue editing an existing story. If provided, updates the existing storyboard instead of creating a new one.

idea
required
string (Idea)

Detailed text description of your story concept. Be specific about characters, settings, actions, and visual style.

scene_count
integer (Number of Scenes)
Default: 3

Number of scenes to generate in the storyboard. Default is 3. If images are provided via 'image_files' or 'image_urls', this value is ignored and scenes are generated based on the number of images.

language
string (Language)
Default: "English"

Language used for storyboard generation and narration. Supported languages include English, Spanish, French, German, and others.

aspect_ratio
string (Aspect Ratio)

Video aspect ratio. Options: '16:9' (landscape, default), '4:3', '1:1', '3:4', '9:16' (vertical/mobile).

Enum: "16:9" "4:3" "1:1" "3:4" "9:16"
audio_option
string (Audio Configuration)

Audio configuration options for story generation.

Configure background music, narration, and native audio settings using a JSON string.

Audio Parameters

Parameter Type Default Description
narrator string "AutoV" Voice for narration. Available voices: AutoV, Rachel, Aria, Roger, Sarah, Laura, Charlie, George, Callum, River, Liam, Charlotte, Alice, Matilda, Will, Jessica, Eric, Chris, Brian, Daniel, Lily, Bill
has_narration boolean true Whether to include narration. Note: This field is ignored when native_audio is true
has_bg_music boolean true Whether to include background music
native_audio boolean false Whether to include native sound effects and lip sync. When true, narration is automatically disabled

Usage Examples

Example 1: Background Music Only

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": false
}

Example 2: Narration with Background Music

{
    "has_bg_music": true,
    "has_narration": true,
    "native_audio": false,
    "narrator": "Rachel"
}

Example 3: Native Audio (Sound Effects + Lip Sync)

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": true
}

Example 4: No Audio

{
    "has_bg_music": false,
    "has_narration": false,
    "native_audio": false
}

Python Usage

import json

audio_option = json.dumps({
    "has_bg_music": True,
    "has_narration": True,
    "native_audio": False,
    "narrator": "AutoV"
})

payload = {
    "idea": "Your story idea",
    "audio_option": audio_option,
    # ... other parameters
}

Notes

  • When native_audio is true, has_narration is automatically set to false regardless of the provided value
  • narrator is only used when has_narration is true and native_audio is false
  • Background music is generated automatically to match the story's mood and style
elements
string (Story Elements)

JSON string containing pre-defined elements (characters, environments, objects) to include in the story. Useful for maintaining consistency or including specific products/logos. Format: JSON string with 'objects', 'characters', or 'environments' arrays.

image_files
Array of strings <binary> (Image Files)
Default: []

Image files to upload directly. Supported formats: JPEG, PNG, WebP. If provided, 'image_urls' is ignored and scene count matches the number of uploaded images.

image_urls
Array of strings (Image URLs)
Default: []

Array of publicly accessible image URLs. If 'image_files' are provided, this field is ignored. Scene count automatically matches the number of image URLs provided.

Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

422

Validation Error

post/story
Request samples
Response samples
application/json
{
  • "data": {
    }
}

[ADVANCED] Step 1.5 - Create Element Images(Optional)

Generates images for storyboard elements (characters, objects, environments) to ensure visual consistency across scenes.

This is an optional step (Step 1.5) in Advanced Mode that helps maintain character and object consistency throughout your story.

What It Does

  • Generates Element Images - Creates images for characters, objects, and environments defined in your storyboard
  • Ensures Consistency - Uses the same visual style and appearance for elements across all scenes
  • Supports Custom Images - If you provide image_url or URL fields in your storyboard elements, those will be used instead

When to Use

  • Use this step when you want consistent character/object appearances across scenes
  • Skip this step if you're providing your own images or don't need element consistency

Parameters

Parameter Type Required Default Description
option string No "AutoI" Image generation model. Options: AutoI, Seedream, FluxTurbo, NanoBanana, QwenImage
aspect_ratio string No "16:9" Aspect ratio for element images. Options: 16:9, 4:3, 1:1, 3:4, 9:16
storyboard string (JSON) No null Updated storyboard JSON. If not provided, uses the existing storyboard.
enhance_image boolean No false Apply 1x super-resolution enhancement to generated images

Example Request

import requests
import json

STORY_ID = "your-story-id-here"
url = f"https://api.vimmerse.net/story/{STORY_ID}/elements"
headers = {"X-Api-Key": "YOUR_API_KEY"}

payload = {
    "aspect_ratio": "16:9",
    "option": "Seedream",
    "enhance_image": False
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=120)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    # Check generated element images
    storyboard = story_data.get("storyboard", {})
    characters = storyboard.get("characters", [])

    for char in characters:
        if "URL" in char or "image_url" in char:
            print(f"Character '{char['name']}' image: {char.get('URL') or char.get('image_url')}")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Providing Custom Element Images

You can provide your own element images by including image_url or URL fields in your storyboard:

payload = {
    "storyboard": json.dumps({
        "characters": [
            {
                "name": "Hero Character",
                "description": "A brave warrior",
                "image_url": "https://example.com/character.png"  # Your custom image
            }
        ],
        "objects": [
            {
                "name": "Magic Sword",
                "description": "A glowing blade",
                "URL": "https://example.com/sword.png"  # Alternative field name
            }
        ]
    })
}

Note: If you're generating a story with idea and images (using image_urls in Step 1), you typically don't need to call this endpoint.

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
option
string (Image Generation Model)
Default: "AutoI"

AI model used for generating element images. Options: 'AutoI' (default), 'Seedream', 'FluxTurbo', 'NanoBanana', 'QwenImage'. Each model offers different styles and quality characteristics.

Enum: "AutoI" "Seedream" "NanoBananaT2" "NanoBananaPro" "QwenImage" "GPTImage" "FluxPro" "FluxTurbo" "NanoBanana" "FluxKontextPro" "StableDiffusion3.5" "Auto"
aspect_ratio
string (Aspect Ratio)

Aspect ratio for generated element images. Options: '16:9' (landscape), '4:3' (standard), '1:1' (square), '3:4' (portrait), '9:16' (vertical/mobile). Default is '16:9'.

storyboard
string (Storyboard)

Optional JSON string of updated storyboard object. If provided, regenerates elements based on the new storyboard structure. Must contain 'characters', 'environments', 'objects', and 'scenes' arrays.

enhance_image
boolean (Image Enhancement)
Default: false

If true, applies super-resolution enhancement to generated images during post-processing, improving image quality at the cost of additional processing time.

has_bg_music
boolean (Background Music)
Default: true

Deprecated: This field is ignored. Configure background music using the 'audio_option' parameter in Step 1 (Create Storyboard).

Responses
200

Story Object with element images generated

400

Bad Request

402

Insufficient Credit

404

Not Found

422

Validation Error

post/story/{story_id}/elements
Request samples
Response samples
application/json
{
  • "data": {
    }
}

[ADVANCED] Step 2 - Create Scenes

Generates scene images, narrations, and background music based on your storyboard.

This is Step 2 of Advanced Mode and is required before creating videos.

What It Does

  • Generates Scene Images - Creates images for each scene based on storyboard descriptions
  • Creates Narrations - Generates voice-over text and audio files for each scene (if narration is enabled)
  • Generates Background Music - Creates background music matching the story mood (if enabled)
  • Updates Storyboard - Optionally accepts an updated storyboard to regenerate scenes

Parameters

Parameter Type Required Default Description
option string No "Seedream" Image generation model
aspect_ratio string No "16:9" Aspect ratio for scene images
storyboard string (JSON) No null Updated storyboard JSON. If provided, regenerates scenes based on new storyboard.
enhance_image boolean No false Apply 1x super-resolution enhancement
audio_option string (JSON) No null Override audio options. If not provided, uses options from Step 1.

Example 1: Generate Scenes Without Updating Storyboard

import requests

STORY_ID = "your-story-id-here"
url = f"https://api.vimmerse.net/story/{STORY_ID}/scenes"
headers = {"X-Api-Key": "YOUR_API_KEY"}

payload = {
    "aspect_ratio": "16:9",
    "option": "Seedream",
    "enhance_image": False
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=180)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    # Check generated scenes
    scenes = story_data.get("storyboard", {}).get("scenes", [])
    print(f"Generated {len(scenes)} scenes")

    for scene in scenes:
        if "image_url" in scene:
            print(f"Scene '{scene.get('name')}' image: {scene['image_url']}")
        if "narration_url" in scene:
            print(f"Scene '{scene.get('name')}' narration: {scene['narration_url']}")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Example 2: Generate Scenes with Updated Storyboard

import requests
import json

STORY_ID = "your-story-id-here"
url = f"https://api.vimmerse.net/story/{STORY_ID}/scenes"
headers = {"X-Api-Key": "YOUR_API_KEY"}

# Updated storyboard with modified scenes
updated_storyboard = {
    "scenes": [
        {
            "name": "Opening Scene",
            "image_description": "A wide shot of a bustling city street at dawn",
            "narrator": "Welcome to the city that never sleeps"
        }
        # ... more scenes
    ],
    "characters": [...],
    "environments": [...],
    "objects": [...]
}

payload = {
    "aspect_ratio": "16:9",
    "option": "Seedream",
    "storyboard": json.dumps(updated_storyboard)
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=180)
    response.raise_for_status()

    result = response.json()
    print("Scenes generated successfully!")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Note: This step may take several minutes depending on the number of scenes and selected options.

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
option
string (Image Generation Model)
Default: "AutoI"

AI model used for generating scene images. Options: 'AutoI' (default), 'Seedream', 'FluxTurbo', 'NanoBanana', 'QwenImage'. Each model offers different styles, quality, and generation speed.

Enum: "AutoI" "Seedream" "NanoBananaT2" "NanoBananaPro" "QwenImage" "GPTImage" "FluxPro" "FluxTurbo" "NanoBanana" "FluxKontextPro" "StableDiffusion3.5" "Auto"
aspect_ratio
string (Aspect Ratio)

Aspect ratio for generated scene images. Options: '16:9' (landscape, default), '4:3' (standard), '1:1' (square), '3:4' (portrait), '9:16' (vertical/mobile).

storyboard
string (Storyboard)

Optional JSON string of updated storyboard object. If provided, regenerates scenes based on the new storyboard structure. Must contain 'characters', 'environments', 'objects', and 'scenes' arrays.

enhance_image
boolean (Image Enhancement)
Default: false

If true, applies super-resolution enhancement to generated images during post-processing, improving image quality at the cost of additional processing time.

generate_elements
boolean (Generate Elements)
Deprecated
Default: true

Deprecated: This parameter is no longer used and will be removed in a future version.

narrator
string (Narrator Voice)
Default: "AutoV"

Deprecated: This field is ignored. Configure the narrator voice using the 'audio_option' parameter in Step 1 (Create Storyboard). Available voices: AutoV, Aria, Roger, Sarah, Laura, Charlie, George, Callum, River, Liam, Charlotte, Alice, Matilda, Will, Jessica, Eric, Chris, Brian, Daniel, Lily, Bill.

has_narration
boolean (Enable Narration)
Default: true

Deprecated: This field is ignored. Configure narration using the 'audio_option' parameter in Step 1 (Create Storyboard).

has_bg_music
boolean (Background Music)
Default: true

Deprecated: This field is ignored. Configure background music using the 'audio_option' parameter in Step 1 (Create Storyboard).

audio_option
string (Audio Configuration)

Audio configuration options for story generation.

Configure background music, narration, and native audio settings using a JSON string.

Audio Parameters

Parameter Type Default Description
narrator string "AutoV" Voice for narration. Available voices: AutoV, Rachel, Aria, Roger, Sarah, Laura, Charlie, George, Callum, River, Liam, Charlotte, Alice, Matilda, Will, Jessica, Eric, Chris, Brian, Daniel, Lily, Bill
has_narration boolean true Whether to include narration. Note: This field is ignored when native_audio is true
has_bg_music boolean true Whether to include background music
native_audio boolean false Whether to include native sound effects and lip sync. When true, narration is automatically disabled

Usage Examples

Example 1: Background Music Only

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": false
}

Example 2: Narration with Background Music

{
    "has_bg_music": true,
    "has_narration": true,
    "native_audio": false,
    "narrator": "Rachel"
}

Example 3: Native Audio (Sound Effects + Lip Sync)

{
    "has_bg_music": true,
    "has_narration": false,
    "native_audio": true
}

Example 4: No Audio

{
    "has_bg_music": false,
    "has_narration": false,
    "native_audio": false
}

Python Usage

import json

audio_option = json.dumps({
    "has_bg_music": True,
    "has_narration": True,
    "native_audio": False,
    "narrator": "AutoV"
})

payload = {
    "idea": "Your story idea",
    "audio_option": audio_option,
    # ... other parameters
}

Notes

  • When native_audio is true, has_narration is automatically set to false regardless of the provided value
  • narrator is only used when has_narration is true and native_audio is false
  • Background music is generated automatically to match the story's mood and style
Responses
200

Story Object with scene images and narrations generated

400

Bad Request

402

Insufficient Credit

404

Not Found

422

Validation Error

post/story/{story_id}/scenes
Request samples
Response samples
application/json
{}

[ADVANCED] Step 3 - Create Videos

Creates videos from your storyboard scenes (Step 3 of Advanced Mode).

This final step animates the scene images into videos and composes them into a final story video.

What It Does

  • Animates Scene Images - Converts static scene images into animated videos
  • Applies Motion - Uses the specified motion type and duration for each scene
  • Composes Final Video - Combines all scene videos into a single story video
  • Handles Transitions - Creates transition videos between scenes if is_transition is enabled

Parameters

Parameter Type Required Default Description
title string No "" Final story title
storyboard string (JSON) No null Updated storyboard. If provided, uses updated scenes.
is_transition boolean No false Create transition videos between scenes
motion_type string No "Auto" Animation method. Options: Auto, KlingAI, VeoFast, Pixverse, Seedance, Vidu, AutoT1, VeoLite, PVideo.
duration integer No 5 Duration per scene in seconds (1-10). Ignored when narration is enabled.
loop integer No 1 Number of times to repeat motion (1-6). Ignored when narrator is used.
native_audio boolean No false Include native sound effects and lip sync. Deprecated - use audio_option in Step 1.
webhook_url string No null Webhook URL for completion notification

Example Request

import requests

STORY_ID = "your-story-id-here"
url = f"https://api.vimmerse.net/story/{STORY_ID}/videos"
headers = {"X-Api-Key": "YOUR_API_KEY"}

payload = {
    "title": "My Amazing Story",
    "motion_type": "Auto",
    "duration": 5,
    "is_transition": True,
    "webhook_url": "https://your-domain.com/webhook/video-complete"
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    print(f"Video generation started for story: {story_data['id']}")
    print(f"Status: {story_data['status']}")

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Monitoring Progress

After initiating video creation, monitor progress using GET /story/{story_id}:

import requests
import time

STORY_ID = "your-story-id-here"

def check_video_status(story_id):
    url = f"https://api.vimmerse.net/story/{story_id}"
    headers = {"X-Api-Key": "YOUR_API_KEY"}

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        story_data = response.json()["data"]
        if story_data["status"] == "success" and story_data.get("video_url"):
            return story_data["video_url"]
    except requests.exceptions.RequestException:
        pass
    return None

# Poll until video is ready (max 60 minutes)
max_attempts = 120
poll_interval = 30
for attempt in range(max_attempts):
    video_url = check_video_status(STORY_ID)
    if video_url:
        print(f"Video ready: {video_url}")
        break
    time.sleep(poll_interval)
else:
    print("Timeout: Video generation is taking longer than expected. Check status later with GET /story/{story_id}")

Note: Video generation typically takes 5-15 minutes depending on the number of scenes and selected options.

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
title
string (Story Title)
Default: ""

Final title for your story video. Used for organization and display purposes. If not provided, uses the title from the storyboard.

storyboard
string (Storyboard)

Optional JSON string of updated storyboard object. If provided, uses the updated scenes for video generation. Must contain 'characters', 'environments', 'objects', and 'scenes' arrays.

is_transition
boolean (Enable Transitions)
Default: false

If true, creates smooth transition videos between scene images, providing a more cinematic flow. Default is false. Enabling transitions may increase processing time.

motion_type
string (Motion Type)
Default: "Auto"

Defines the motion style used for video animation.

Enum: "Auto" "AutoT3" "AutoT1" "Grok" "KlingAI" "KlingT3" "VeoLite" "VeoFast" "Veo" "RunwayML" "MinimaxHailuo" "Seedance" "SeedanceFast" "SeedanceT6" "Pixverse" "PixverseT3" "Hunyuan" "Vidu" "PVideo" "StaticMotion" "Wan" "Sora" "SoraPro" "LumaAI" "LumaRay2"
duration
integer (Scene Duration) [ 1 .. 20 ]
Default: 5

Duration of each scene in seconds. Range: 1-20. Default is 5. Note: This value is automatically adjusted when narration is enabled to match the narration length.

loop
integer (Motion Loop Count) [ 1 .. 6 ]
Default: 1

Number of times the same motion is repeated for each scene. Range: 1-6. Default is 1. Note: This setting is ignored when narration is enabled.

native_audio
boolean (Native Audio)
Default: false

Deprecated: This field is ignored. Configure native audio (sound effects and lip sync) using the 'audio_option' parameter in Step 1 (Create Storyboard).

webhook_url
string (Webhook URL)

URL endpoint to receive a POST request notification when video generation completes. Your endpoint must respond with a 2xx status code within 10 seconds.

Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

422

Validation Error

post/story/{story_id}/videos
Request samples
Response samples
application/json
{}

Get Story Detail

Retrieves detailed information about a story, including its current status, progress, and generated assets.

Response Fields

Field Type Description
id string Unique story identifier
status string Current status: new, processing, success, fail
progress_percentage integer Completion percentage (0-100)
video_url string URL of the final composed video (available when status is success)
storyboard object Generated storyboard with characters, environments, objects, and scenes
scenes array Array of scene objects with images, narrations, and video URLs
used_credits integer Credits consumed for this story
created_at string ISO 8601 timestamp of creation
updated_at string ISO 8601 timestamp of last update

Status Values

  • new - Story created but processing hasn't started
  • processing - Story is currently being generated
  • success - Story generation completed successfully
  • fail - Story generation failed

Example Request

import requests

BASE_URL = "https://api.vimmerse.net"
STORY_ID = "your-story-id-here"

url = f"{BASE_URL}/story/{STORY_ID}"
headers = {"X-Api-Key": "YOUR_API_KEY"}

try:
    response = requests.get(url, headers=headers, timeout=30)
    response.raise_for_status()

    result = response.json()
    story_data = result["data"]

    print(f"Story ID: {story_data['id']}")
    print(f"Status: {story_data['status']}")
    print(f"Progress: {story_data.get('progress_percentage', 0)}%")

    if story_data['status'] == 'success' and story_data.get('video_url'):
        print(f"Video URL: {story_data['video_url']}")
    elif story_data['status'] == 'fail':
        print("Story generation failed. Check the 'message' field for details.")

except requests.exceptions.HTTPError as e:
    if e.response.status_code == 404:
        print("Story not found. Please verify the story ID.")
    else:
        print(f"HTTP Error: {e}")
except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")

Error Responses

  • 404 - Story not found or you don't have access to this story
  • 400 - Invalid story ID format
SecurityAPIKeyHeader
Responses
200

Story Object

400

Bad Request

404

Not Found

422

Validation Error

get/story/{story_id}
Request samples
Response samples
application/json
{
  • "data": {
    }
}

Update Story

Update story metadata. You can update one or more of the following fields: title, description, visibility_status

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
title
string (Story Title)

New title for the story. If provided, updates the story title.

description
string (Story Description)

New description for the story. If provided, updates the story description.

visibility_status
string (Visibility Status)

Visibility Status:

Value Status
"0" Private
"1" Unlisted
"2" Public
Enum: "0" "1" "2"
additional_videos
string (Additional Videos)

JSON array of additional video URLs to associate with the story. For internal use only.

Responses
200

Updated Story Object

400

Bad Request

404

Not Found

422

Validation Error

put/story/{story_id}
Request samples
Response samples
application/json
{}

Delete Story

Delete story

SecurityAPIKeyHeader
Responses
200

Deleted Story Object

400

Bad Request

404

Not Found

422

Validation Error

delete/story/{story_id}
Request samples
Response samples
application/json
{ }

Update Story General Info

Update story general metadata: title, description, visibility_status, and/or rating. All fields are optional.

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
title
string (Story Title)

New title for the story. If provided, updates the story title.

description
string (Story Description)

New description for the story. If provided, updates the story description.

visibility_status
string (Visibility Status)

Visibility Status:

Value Status
"0" Private
"1" Unlisted
"2" Public
Enum: "0" "1" "2"
rating
number (Rating)

Rating value for the story. If provided, updates the story rating (stored as string).

Responses
200

Updated Story Object

400

Bad Request

404

Not Found

422

Validation Error

put/story/{story_id}/general
Request samples
Response samples
application/json
{}

Concat Story

Composes all generated scene videos into a single final story video.

This endpoint concatenates individual scene videos (and optionally custom video URLs) into one cohesive story video with synchronized audio.

Use Cases

  • Compose scene videos generated in Advanced Mode
  • Combine custom video URLs with generated scenes
  • Add background audio to the final composition

Parameters

Parameter Type Required Default Description
concat_video_urls array[string] No null Array of video URLs to compose. If not provided, uses generated scene videos.
audio_urls array[string] No null Array of background audio URLs to overlay on the final video

Example Request

import requests

STORY_ID = "your-story-id-here"
url = f"https://api.vimmerse.net/story/{STORY_ID}/concat"
headers = {"X-Api-Key": "YOUR_API_KEY"}

# Option 1: Compose generated scene videos (no parameters needed)
payload = {}

# Option 2: Compose custom video URLs
payload = {
    "concat_video_urls": [
        "https://example.com/video1.mp4",
        "https://example.com/video2.mp4",
        "https://example.com/video3.mp4"
    ],
    "audio_urls": [
        "https://example.com/background-music.mp3"
    ]
}

try:
    response = requests.post(url, headers=headers, data=payload, timeout=60)
    response.raise_for_status()

    result = response.json()
    print(f"Composition started for story: {result['data']['id']}")

    # Monitor progress using GET /story/{story_id}
    # The video_url field will be populated when composition completes

except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Monitoring Composition

After initiating composition, check the story status:

import requests
import time

STORY_ID = "your-story-id-here"

def get_final_video(story_id):
    url = f"https://api.vimmerse.net/story/{story_id}"
    headers = {"X-Api-Key": "YOUR_API_KEY"}
    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        return response.json()["data"].get("video_url")
    except requests.exceptions.RequestException:
        return None

# Wait for composition to complete (max ~5 minutes)
for _ in range(30):
    video_url = get_final_video(STORY_ID)
    if video_url:
        print(f"Final video: {video_url}")
        break
    print("Composition in progress...")
    time.sleep(10)
else:
    print("Timeout: Check status later with GET /story/{story_id}")

Note: Composition typically takes 1-3 minutes depending on video length and number of scenes.

SecurityAPIKeyHeader
Request
Request Body schema: application/x-www-form-urlencoded
concat_video_urls
Array of strings (Video URLs to Compose)

Array of video URLs to compose into the final story video. If not provided, uses the generated scene videos from the story.

audio_urls
Array of strings (Background Audio URLs)

Array of background audio URLs to overlay on the final composed video. Multiple audio files will be mixed together.

Responses
200

Story Object

400

Bad Request

402

Insufficient Credit

404

Not Found

422

Validation Error

post/story/{story_id}/concat
Request samples
Response samples
application/json
{ }