Skip to content

API > Integrate API into your product

Video Generation API

Base URL: https://api.phantaisia.com

All requests require a Bearer token in the Authorization header.

Authorization: Bearer <your_token>

Overview

There are two ways to generate a video:

Endpoint What it does
POST /v1/run/single_frame_video Animate a single image — you provide one photo and a text prompt
POST /v1/run/first_last_frame_video Transition between two images — you provide a first and last frame

Both endpoints return a job ID immediately. Use the shared status endpoint to poll until the video is ready.


Models

Both run endpoints accept a model parameter that controls quality and speed.

Model Description
simple Fastest generation, good for previews. Single frame only. 4s only.
advanced Higher quality, recommended for final output
performance Highest quality, supports custom aspect ratios. Single frame only.

For credit costs per model and duration, see Video Generation Pricing.


1. Single Frame Video

POST /v1/run/single_frame_video

Animates a single image using a text prompt. The image becomes the starting frame of the video.

Request body

{
  "prompt_image": "<base64-or-url>",
  "prompt": "The subject waves and smiles at the camera.",
  "model": "advanced",
  "duration": "4s",
  "aspect_ratio": "auto"
}
Field Type Required Description
prompt_image string Yes Starting image as a base64 data URI (data:image/jpeg;base64,...) or a publicly accessible URL
prompt string Yes Text description of the motion or scene you want generated
model string Yes "simple", "advanced", or "performance" — see Models table above
duration string Yes Video length: "4s", "6s", or "8s". simple model only supports "4s".
aspect_ratio string No (default: "auto") Output aspect ratio — only supported with performance model. Options: "auto", "16:9", "9:16", "3:2", "2:3"

Response — 200 OK

{
  "id": "job-abc123",
  "status": "IN_QUEUE"
}

Use the id to poll the status endpoint.

Errors

HTTP error_code Meaning
402 Insufficient credits
422 INVALID_ASPECT_RATIO_FOR_MODEL A non-"auto" aspect ratio was requested with a model other than "performance"
422 INVALID_VIDEO_MODEL The model value is not recognised

2. First-Last Frame Video

POST /v1/run/first_last_frame_video

Generates a video that transitions between two images. The model interpolates the motion between your first and last frame guided by your prompt.

Note: Only the advanced model is available for this endpoint. simple and performance are single-frame only.

Request body

{
  "prompt": "The subject smoothly transitions from the first frame to the last frame.",
  "model": "advanced",
  "duration": "8s",
  "first_frame": "<base64-or-url>",
  "last_frame": "<base64-or-url>"
}
Field Type Required Description
first_frame string Yes Opening frame of the video — base64 data URI or public URL
last_frame string Yes Closing frame of the video — base64 data URI or public URL
prompt string Yes Text description of the transition or action between the two frames
model string Yes Must be "advanced"
duration string Yes Video length: "4s", "6s", or "8s"

Response — 200 OK

{
  "id": "job-xyz789",
  "status": "IN_QUEUE"
}

Use the id to poll the status endpoint.

Errors

HTTP error_code Meaning
402 Insufficient credits
422 INVALID_VIDEO_MODEL The model value is not recognised, or "simple" / "performance" was specified (not supported for this endpoint)

3. Check Job Status

POST /v1/status/single_frame_video/{job_id}

Used to check the status of both single-frame and first-last-frame video jobs. This endpoint is non-blocking — it returns the current state immediately. Keep polling until the job reaches a terminal status (COMPLETED or FAILED).

Recommended polling interval: every 5–10 seconds. Video jobs typically take 1–3 minutes.

Path parameter

Parameter Type Description
job_id string The id returned from the run endpoint

Response — in progress

{
  "id": "job-abc123",
  "status": "IN_PROGRESS",
  "output": {}
}

Response — completed

{
  "id": "job-abc123",
  "status": "COMPLETED",
  "output": {
    "video_url": "https://...",
    "video_status": "completed"
  }
}

Response — failed

{
  "id": "job-abc123",
  "status": "FAILED",
  "output": {
    "video_status": "failed",
    "video_error": "VEO generation failed"
  }
}

Status values

Status Terminal Meaning
IN_QUEUE No Job is queued, not yet started
IN_PROGRESS No Job is actively generating
COMPLETED Yes Video is ready — output.video_url contains the download link
FAILED Yes Generation failed — stop polling, output.video_error has details

End-to-end example (JavaScript)

const TOKEN = 'your_token_here';
const BASE  = 'https://api.phantaisia.com';

async function generateVideo(endpoint, body) {
  // 1. Submit job
  const runRes = await fetch(`${BASE}${endpoint}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${TOKEN}`,
    },
    body: JSON.stringify(body),
  });

  if (!runRes.ok) throw new Error(`Submit failed: ${await runRes.text()}`);
  const { id } = await runRes.json();
  console.log('Job submitted:', id);

  // 2. Poll for result
  while (true) {
    await new Promise(r => setTimeout(r, 7000));

    const statusRes = await fetch(`${BASE}/v1/status/single_frame_video/${id}`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${TOKEN}` },
    });

    if (!statusRes.ok) throw new Error(`Status error: ${await statusRes.text()}`);
    const data = await statusRes.json();
    console.log('Status:', data.status);

    if (data.status === 'COMPLETED') {
      return data.output.video_url;
    }
    if (data.status === 'FAILED') {
      throw new Error(data.output?.video_error ?? 'Generation failed');
    }
  }
}

// Single frame example
const videoUrl = await generateVideo('/v1/run/single_frame_video', {
  prompt_image: 'https://example.com/photo.jpg',
  prompt: 'The subject turns and smiles.',
  model: 'advanced',
  duration: '4s',
});

// First-last frame example
const videoUrl2 = await generateVideo('/v1/run/first_last_frame_video', {
  first_frame: 'https://example.com/start.jpg',
  last_frame: 'https://example.com/end.jpg',
  prompt: 'Smooth transition from standing to sitting.',
  model: 'advanced',
  duration: '8s',
});