Video Face Swap

Video Face Swap

Playground

Try it on WaveSpeedAI!

Swap faces in any video by uploading a video and an image — perform unlimited, seamless face replacements quickly. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.

Features

Seamlessly swap faces in videos with just a few clicks. Upload your video and a reference face image, and the model will intelligently replace faces while preserving natural motion, lighting, and expressions. No complex editing software required.

Why It Looks Great

  • Natural blending: Automatically matches skin tone, lighting, and shadows for seamless face integration.
  • Expression preservation: Retains the original facial movements, emotions, and lip sync from the source video.
  • Temporal consistency: Minimizes flickering and artifacts across frames for stable, realistic results.
  • Multi-face support: Handle videos with multiple people — target specific faces by index.
  • High fidelity output: Maintains video quality with sharp facial details and smooth edges.

Parameters

ParameterRequiredDescription
videoYesSource video file (upload or public URL). Max 10 minutes.
face_imageYesReference face image to swap in (upload or public URL).
target_indexNoSelect which face to swap when multiple faces exist. 0 = largest face, 1 = second largest, etc. Default: 0.
target_genderNoOnly swap faces matching this gender: all, male, or female. Default: all.

How to Use

  1. Upload your video — drag and drop or paste a public URL.
  2. Upload the face image — provide the face you want to swap in.
  3. Set target index (optional):
  • Use target_index to select a specific face (0 = largest face).
  • Use target_gender to only swap faces of a specific gender (male / female).
  1. Run — click the button and wait for processing.
  2. Download — preview and save your swapped video.

Pricing

Per-second billing with a 5-second minimum. Maximum video length: 10 minutes.

DurationCost
Per 5 seconds$0.05
Per second$0.01

Billing Rules

  • Minimum charge: 5 seconds ($0.05)
  • Per-second rate: $0.01
  • Billed duration: Video length in seconds (rounded up), with 5-second minimum
  • Total cost: Billed duration × $0.01

Examples

Video LengthCalculationTotal Cost
3s5s minimum × $0.01$0.05
15s15 × $0.01$0.15
1m 30s (90s)90 × $0.01$0.90
5m (300s)300 × $0.01$3.00

Best Use Cases

  • Content Creation — Create entertaining face-swap videos for social media and viral content.
  • Film & Video Production — Replace stunt doubles or create special effects without expensive post-production.
  • Marketing & Advertising — Personalize video ads with localized faces for different markets.
  • Entertainment & Memes — Generate fun, shareable content with celebrity or character face swaps.
  • Privacy Protection — Anonymize faces in videos for privacy-sensitive content.

Pro Tips for Best Results

  • Use a clear, front-facing reference image with good lighting for the best match.
  • Source videos with stable, well-lit faces produce smoother results.
  • For videos with multiple people, use target_index to precisely control which face gets swapped.
  • Keep the reference face angle similar to the faces in the video for more natural blending.

Notes

  • If using a URL for the face image, ensure it is publicly accessible. A preview thumbnail in the interface confirms successful loading.
  • Processing time varies based on video length and current queue load.
  • For videos longer than 10 minutes, split into segments and process separately.

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'
{
  "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
  "face_image": "https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg",
  "target_index": 0,
  "target_gender": "all"
}
JSON
)

# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
  -X POST "https://api.wavespeed.ai/api/v3/wavespeed-ai/video-face-swap" \
  -H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "${REQUEST_BODY}")

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
' >&2
  exit 1
fi
RESULT_URL=$(printf '%s' "${TASK}" | jq -r '.urls.get // empty')
if [ -z "${RESULT_URL}" ]; then RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"; fi

# 2. Poll until the prediction finishes.
while true; do
  RESPONSE=$(curl --silent --show-error --fail-with-body \
    "${RESULT_URL}" \
    -H "Authorization: Bearer ${WAVESPEED_API_KEY}")
  RESULT=$(printf '%s' "${RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
  STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')

  case "${STATUS}" in
    completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
    failed|cancelled|timeout) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
    created|processing) sleep 2 ;;
    *) printf 'Unexpected status: %s
' "${STATUS}" >&2; exit 1 ;;
  esac
done

Parameters

Task Submission Parameters

Request Parameters

ParameterTypeRequiredDefaultRangeDescription
videostringYes-The video that contains the face to be replaced.
face_imagestringYes--The face image as reference.
target_indexintegerNo00 ~ 100 = largest face. To switch to another target face - switch to index 1, e.t.c.
target_genderstringNoallall, male, femaleOnly swap target faces matching this gender. 'all' swaps regardless of gender.

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.urls.getstringURL to retrieve the prediction result
data.statusstringStatus of the task: created, processing, completed, or failed
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.urls.getstringURL to poll for the prediction result
data.statusstringStatus: created, processing, completed, or failed
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.