Create video using first and last frames

March 31, 2025 (October 18, 2026)

Table of contents

  1. Request Headers
  2. Request Body
  3. Responses
  4. Model
  5. Examples
  6. Try It

This endpoint creates a 2-frame transition (first frame → last frame) and supports:

  • Native PixVerse: v5.6 (default), v5.5, v5, v6, pixverse-c1
  • Third-party: seedance-2.5, seedance-2.0, seedance-2.0-fast, seedance-2.0-mini, kling-o3, kling-v3, veo-3.1-lite, veo-3.1-standard, veo-3.1-fast, minimax-h3, minimax-h3-max, wan-3.0

See Model Capabilities for per-model quality and duration constraints.

To upload prompt image use POST /files.

https://api.useapi.net/v2/pixverse/videos/create-frames

Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
Request Body
{
    "email": "Optional PixVerse API account email",
    "prompt": "Optional text prompt",
    "first_frame_path": "upload/7d16f-eed2-a8f4-cef8-aa44-72807n313.jpeg",
    "last_frame_path": "upload/e7484a28-6efd-174d-7c02-316ef1a5d.jpeg",
    "duration": 8,
    "quality": "1080p",
    "seed": 654321,
    "replyUrl": "Place your call back URL here",
    "replyRef": "Place your reference id here",
    "maxJobs": 3
}
  • email is optional, if not specified API will randomly select account from available accounts.

  • model is optional. Default: v5.6. Supported values — native PixVerse: v5.6, v5.5, v5, v6, pixverse-c1. Third-party: seedance-2.5, seedance-2.0, seedance-2.0-fast, seedance-2.0-mini, kling-o3, kling-v3, veo-3.1-lite, veo-3.1-standard, veo-3.1-fast, minimax-h3, minimax-h3-max, wan-3.0. See Model Capabilities for per-model constraints.

  • prompt is optional, describe your video.
    Maximum length 5,000 characters.

  • first_frame_path is required, provide path of uploaded image via POST /files.

  • last_frame_path is required, provide path of uploaded image via POST /files.

  • duration is optional for v5, v5.5 and v5.6, where it defaults to 5. v6, pixverse-c1 and every third-party model require it. Accepted values depend on the model — see Model Capabilities.

  • quality is optional for v5, v5.5 and v5.6. v6, pixverse-c1 and every third-party model require it. Accepted values depend on the model — see Model Capabilities. Kling note: for kling-o3 / kling-v3, quality selects an upstream tier rather than an output resolution — 720p routes to Standard, 1080p to Pro, and 2160p to the 4K tier. PixVerse renders both Standard and Pro at 720p, so only 2160p changes the resolution.

  • audio is optional. Behavior depends on the model:
    • Not supported — seedance-2.5, minimax-h3 and minimax-h3-max (native audio, always on).
    • Toggle (true/false) — v5.5, v5.6, v6, pixverse-c1, seedance-2.0, seedance-2.0-fast, seedance-2.0-mini, kling-o3, kling-v3, wan-3.0.
    • Always on (cannot disable) — veo-3.1-standard, veo-3.1-fast.
    • Not supported — veo-3.1-lite rejects it. v5 accepts the field and ignores it. Supported values: not specified (default), false, true.
  • aspect_ratio is not accepted — transition derives aspect ratio from the first frame.

  • preview_mode is optional. Set to true for fast preview generation (lower quality, faster results). Preview videos can later be upscaled via POST videos/upscale. Supported values: false (default), true.

  • auto_sound is optional (v5 only). Set to true to generate videos with sound. Supported values: not specified (default), false, true.

  • sound_effect_prompt is optional (v5 only), describe the sound eg “the sound of waves hitting the shore”.

  • lip_sync_tts_prompt is optional (v5 only), enter character lines. Maximum length 140 characters.

  • lip_sync_tts_speaker_id is optional (v5 only), specify desired lipsync voice see GET videos/voices.

  • seed is optional. Only supported for the native PixVerse models accepted by this endpoint (v5, v5.5, v5.6, v6, pixverse-c1) — third-party models reject this flag. Valid range 1…2147483647.

  • off_peak_mode is optional. Set to true to generate videos during low-demand periods at a reduced credit cost. Only supported for the native PixVerse models accepted by this endpoint (v5, v5.5, v5.6, v6, pixverse-c1) — third-party models reject this flag. Discount varies by subscription plan: Pro 30% off, Premium 50% off, Ultra unlimited free. Results are usually delivered within 24 hours. Off-Peak generations are not tracked by the scheduler, don’t count toward concurrent-job limits, and the replyUrl webhook is not called — use GET videos to retrieve results.
    Supported values: false (default), true.

  • replyUrl is optional. This is the preferred and most optimal way to receive results quickly — the API polls every 10 seconds and will call the provided replyUrl once the PixVerse video is completed or failed. Maximum length 1024 characters. We recommend using sites like webhook.site to test callback URL functionality. Callback body has the same JSON shape as GET /videos/video_id response.

  • replyRef is optional, place here your reference id which will be stored and returned along with this PixVerse video response / result.
    Maximum length 1024 characters.

  • maxJobs is optional, if not specified value from selected accounts/email will be used.
    Valid range: 1…8
    It should not exceed the number of concurrent generations supported by your account subscription plan.
Responses
  • 200 OK

    Use the returned video_id to retrieve video status and results using GET /videos. Locate the video in the response array and check if the field video_status_final is true or video_status_name is COMPLETED. The field url will contain the generated video link.

    If you specify the optional parameter replyUrl, the API will call the provided replyUrl with video progress updates until the video is complete or fails.

    {
        "video_id": "user:<userid>-pixverse:<email>-video:<number>"
    }
    
  • 400 Bad Request

    {
      "error": "<Error message>"
    }
    
  • 401 Unauthorized

    {
      "error": "Unauthorized"
    }
    
  • 412 Insufficient credits

    Insufficient credits. All Credits have been used up. Please upgrade your membership or purchase credits.

    {
      "error": "All Credits have been used up. Please upgrade your membership or purchase credits."
    }
    
  • 422 Unprocessable Content

    Moderated message.

    {
      "error": "Your prompt has triggered our AI moderator, please re-enter your prompt"
    }
    
  • 429 Too Many Requests

    Wait in a loop for at least 10..30 seconds and retry again.

    There are two possible cases for API response 429:

    1. API query is full and can not accept new videos/create-frames requests. Size of query defined by maxJobs optional parameter.
      {
       "error": 
         "Account <email> is busy executing <maxJobs> tasks."
         "All configured accounts are running at maximum capacity."
      }
      
    2. The API received an HTTP response status 429 from PixVerse. Please refer to your subscription plan for the maximum allowed tasks in the queue.
      {
        "error": "Reached the limit for concurrent generations."
      }
      
  • 596 Pending mod message

    The account has a pending error, and the API does not use it until you add it again with POST accounts/email. You receive an email when this happens. There are two causes.

    PixVerse could not sign the account in, most often because its password was changed. Add the account again with the current password.

    {
      "error": "Your PixVerse account has pending error. Please address this issue at https://useapi.net/docs/api-pixverse-v2/post-pixverse-accounts-email before making any new API calls.",
      "code": 596
    }
    

    Or PixVerse suspended the account. PixVerse suspends accounts that break its content rules and does not say which generation caused it. The first response carries PixVerse’s own details in account_moderation, and later calls return the same error. Add the account again after reinstatement_at. To ask PixVerse to lift the suspension earlier, write to the support_email it gives.

    {
      "error": "PixVerse suspended account [email protected] for 30 days, from 2026-10-16 09:26 UTC until 2026-11-15 09:26 UTC. PixVerse suspends accounts that break its content rules and does not say which generation caused it. Add the account again at https://useapi.net/docs/api-pixverse-v2/post-pixverse-accounts-email after 2026-11-15 09:26 UTC. To ask PixVerse to lift it earlier, write to [email protected].",
      "code": 596,
      "account_moderation": {
        "ban_level": "suspend_30d",
        "action": "temporary_suspend",
        "duration_days": 30,
        "suspended_at": "2026-10-16 09:26:25 (UTC)",
        "reinstatement_at": "2026-11-15 09:26:25 (UTC)",
        "support_email": "[email protected]"
      }
    }
    

    If every account you have is in this state, a request without email returns 596 as well.

Model
{ // TypeScript, all fields are optional
    video_id: string
    error: string
}
Examples
  • curl -H "Accept: application/json" \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer …" \
         -X POST "https://api.useapi.net/v2/pixverse/videos/create-frames" \
         -d '{"prompt": "…", "first_frame_path": "…", "last_frame_path": "…"}'
    
  • const prompt = "text prompt";  
    const first_frame_path = "provide path of uploaded first image via POST /files";    
    const last_frame_path = "provide path of uploaded last image via POST /files";    
    const apiUrl = `https://api.useapi.net/v2/pixverse/videos/create-frames`; 
    const token = "API token";
    const data = { 
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json' }
    };
    data.body = JSON.stringify({ 
      prompt, first_frame_path, last_frame_path
    });
    const response = await fetch(apiUrl, data);
    const result = await response.json();
    console.log("response", {response, result});
    
  • import requests
    prompt = "text prompt"      
    first_frame_path = "provide path of uploaded first image via POST /files"    
    last_frame_path = "provide path of uploaded last image via POST /files"
    apiUrl = f"https://api.useapi.net/v2/pixverse/videos/create-frames" 
    token = "API token"
    headers = {
        "Content-Type": "application/json", 
        "Authorization" : f"Bearer {token}"
    }
    body = {
        "prompt": f"{prompt}",
        "first_frame_path": f"{first_frame_path}",
        "last_frame_path": f"{last_frame_path}"
    }
    response = requests.post(apiUrl, headers=headers, json=body)
    print(response, response.json())
    
Try It