Pika V2.2 Pikaframes API Documentation

Pika V2.2 Pikaframes API Documentation

Playground

Try it on WaveSpeedAI!

Create precise keyframe-to-video sequences with Pika V2.2 Pikaframes. Upload up to 5 keyframes, set per-transition prompts and durations, and interpolate smooth motion for storyboards, camera moves, and style-consistent animation. Supports total runtimes up to 25 seconds. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.

Features

Pika V2.2 Pickaframes turns one or more still images into a short, animated video. You provide keyframe images plus a global description, optionally set per-segment transitions, and the model fills in motion, camera moves, and in-between frames for social videos, ads, and simple storyboard clips.


Highlights

  • Image-driven animation – Start from 1+ still images and let the model create smooth motion and transitions.
  • Timeline control via transitions – Use per-segment durations to decide how long the animation lingers between images.
  • Production-ready quality – Supports up to 1080p output for most major platforms.
  • Prompt-guided style – A single high-level prompt controls look, atmosphere, and camera behaviour.

Parameters

  • images (required)

  • Upload one or more images or paste URLs.

  • Single image: the model animates around that scene (camera moves, small changes).

  • Multiple images: they act as keyframes; the video evolves from the first to the last in order.

  • prompt (required) Global description of the clip: content, motion, and style. Example: TV screen flickering in a cozy kitchen, soft camera shake, warm cinematic lighting.

  • transitions (optional) A list of segments; each item has:

  • duration – segment length in seconds

  • prompt (optional) – local override or refinement for this segment only

If transitions are provided, total video length is roughly the sum of all durations. If no transitions are set, a 5-second clip is generated by default.

  • resolution Output quality tier, for example 720p or 1080p.

  • seed

  • −1: random each run (exploration).

  • Any fixed integer: reproducible layout and motion.

Output format: MP4 video at the chosen resolution.


Pricing

Pricing is $0.04 per second for 720p or $0.06 per second for 1080p, with a minimum of 5 billable seconds.

Billable Duration720p1080p
5s$0.20$0.30
10s$0.40$0.60
15s$0.60$0.90
20s$0.80$1.20
25s$1.00$1.50

Billing Rules

  • With custom transitions, duration is the sum of all transition durations. An omitted transition duration defaults to 5 seconds.
  • Without custom transitions, duration is 5 × (number of images − 1) seconds.
  • Total duration is rounded up to the next whole second for billing.
  • Supply 2–5 images. Custom transitions must contain exactly one item per adjacent image pair.
  • Total transition duration must not exceed 25 seconds. This is an input limit, not automatic truncation.
  • prompt and seed do not add separate charges.

How to Use

  1. Write the global prompt In the prompt field, describe the overall scene and motion in one or two sentences (for example: TV screen flickering, reflections on the counter, slight handheld camera feel).

  2. Add images

  • Under images, upload at least one frame or paste image URLs.
  • Click Add Item to append more keyframes; they are used in order from top to bottom.
  1. Configure transitions (optional but recommended for multi-image stories)
  • In transitions, click Add Item.
  • Set duration in seconds for how long the animation should spend between the current and next keyframe.
  • Optionally add a local prompt to nudge that segment’s motion or style.
  • Add multiple transition items if you want a longer sequence; total length is their duration sum.
  1. Choose resolution
  • Use 720p for quick iteration and previews.
  • Switch to 1080p once you are happy with the motion and want a final render.
  1. Set seed if needed
  • Keep −1 when exploring different variations.
  • Use a fixed integer when you want to lock in a specific behaviour for future runs.
  1. Run and download
  • Check the estimated cost shown on the Run button (for example, 0.20 USD for 5 seconds at 720p).
  • Click Run, wait for processing, then download your generated MP4 from the result panel.

Tips

  • Use images with similar aspect ratios to avoid stretching during transitions.
  • To mimic flickering or jump cuts, use two very similar images with short transition durations.
  • Iterate with short, cheap runs first, then extend durations and upgrade resolution for the final version.

Authentication

For authentication details, please refer to the Authentication Guide.

API Endpoints

Submit Task & Query Result

set -euo pipefail

export WAVESPEED_API_KEY="your-api-key"

REQUEST_BODY=$(cat <<'JSON'
{
  "images": [
    "https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg",
    "https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg"
  ],
  "resolution": "720p"
}
JSON
)

# 1. Submit the prediction once. Never retry this request automatically:
# a retry after an unclear failure can create a second, billed task.
CHECK='The task may already exist. Check History or the predictions list before submitting again.'
if ! SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
  --connect-timeout 10 --max-time 60 \
  -X POST "https://api.wavespeed.ai/api/v3/pika/v2.2-pikaframes" \
  -H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "${REQUEST_BODY}"); then
  printf 'Submit failed. %s\n' "${CHECK}" >&2
  exit 1
fi

TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
  printf 'Submission response did not contain a prediction id. %s\n' "${CHECK}" >&2
  exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"

# 2. Poll until the prediction reaches a final status.
BODY_FILE=$(mktemp)
trap 'rm -f "${BODY_FILE}"' EXIT
while true; do
  # Transient errors (429, 5xx) are retried, honoring Retry-After.
  HTTP_CODE=$(curl --silent --show-error --fail-with-body \
    --connect-timeout 10 --max-time 60 --retry 5 --retry-delay 2 \
    --output "${BODY_FILE}" --write-out '%{http_code}' \
    "${RESULT_URL}" \
    -H "Authorization: Bearer ${WAVESPEED_API_KEY}" || true)
  case "${HTTP_CODE}" in
    2??) ;;
    000|429|5??)  # dropped connection or temporary error: keep polling
      printf 'Task %s: HTTP %s, polling again in 10s\n' "${PREDICTION_ID}" "${HTTP_CODE}" >&2
      sleep 10; continue ;;
    *) printf 'Task %s: HTTP %s\n' "${PREDICTION_ID}" "${HTTP_CODE}" >&2
      cat "${BODY_FILE}" >&2; exit 1 ;;
  esac
  RESULT=$(jq 'if type == "object" and has("data") then .data else . end' "${BODY_FILE}")
  STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')

  case "${STATUS}" in
    completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
    failed|cancelled|timeout|deleted)
      printf 'Task %s ended with status %s\n' "${PREDICTION_ID}" "${STATUS}" >&2
      printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
    *) sleep 2 ;;
  esac
done

Retry temporary errors only while polling, never the submit request. Errors, retries and timeouts

Parameters

Task Submission Parameters

Request Parameters

ParameterTypeRequiredDefaultRangeDescription
imagesarray<string>Yes-2 ~ 5 itemsURL of ref images to use while generating the video.
promptstringNo-The positive prompt for the generation.
transitionsarray<object>No-0 ~ 5 itemsConfiguration for each transition. Length must be len(image_urls) - 1. Total duration of all transitions must not exceed 25 seconds. If not provided, uses default 5-second transitions with the global prompt
transitions[].durationnumberNo55 ~ 25Duration of this transition in seconds
transitions[].promptstringNo--Specific prompt for this transition. Overrides the global prompt if provided.
resolutionstringNo720p720p, 1080pThe resolution of the generated video.
seedintegerNo--The random seed to use for the generation. -1 means a random seed will be used.

Response Parameters

ParameterTypeDescription
codeintegerHTTP status code (e.g., 200 for success)
messagestringStatus message (e.g., “success”)
data.idstringUnique identifier for the prediction, Task Id
data.modelstringModel ID used for the prediction
data.outputsarrayOutput values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed)
data.urlsobjectObject containing related API endpoints
data.statusstringTask status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses.
data.created_atstringISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”)
data.errorstringError message (empty if no error occurred)
data.timingsobjectObject containing timing details
data.timings.inferenceintegerInference time in milliseconds

Result Request Parameters

ParameterTypeRequiredDefaultDescription
idstringYes-Task ID

Result Response Parameters

ParameterTypeDescription
codeintegerHTTP status code (e.g., 200 for success)
messagestringStatus message (e.g., “success”)
dataobjectThe prediction data object containing all details
data.idstringUnique identifier for the prediction
data.modelstringModel ID used for the prediction
data.outputsarray<string | object>Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model.
data.urlsobjectObject containing related API endpoints
data.statusstringStatus: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses
data.created_atstringISO timestamp of when the request was created
data.errorstringError message (empty if no error occurred)
data.timingsobjectObject containing timing details
data.timings.inferenceintegerInference time in milliseconds
© 2026 WaveSpeedAI. All rights reserved.