Seedance 2.5 is live — 30-second cinematic video with native audio & real-person references
rreAPI Docs

Head Swap

Head Swap on reAPI — send a target photo and a source head, get one image back with the entire head replaced (face, hair, ears, outline) and the target's pose, lighting and background kept. Seed control, flat price per image, playground and API.

Head Swap replaces the entire head in a target photo — face, hair, ears and outline — with the head from a source image, keeping the target's body, pose, lighting and background. Two public image URLs in, one image out; pin a seed to repeat a result. Submit returns a task_id; poll until ready. Try it in the playground on the model page, which also shows current pricing. For the facial region only, see Face Swap.

Content filtering

Content filtering is always off on this model, and there is no filter parameter: the request schema has no content_filter field, and a request that includes it is rejected with 400. Use it on people whose likeness you have the right to use; platform terms apply to everything you generate.

Generated images are stored in an isolated bucket and their URLs stay valid for 30 days. Mirror the files to your own storage if you need them longer.

Quick example

curl https://reapi.ai/api/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "head-swap",
    "image_url": "https://example.com/target-photo.jpg",
    "head_image_url": "https://example.com/source-head.jpg"
  }'
import requests

resp = requests.post(
    "https://reapi.ai/api/v1/images/generations",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "head-swap",
        "image_url": "https://example.com/target-photo.jpg",
        "head_image_url": "https://example.com/source-head.jpg",
    },
    timeout=30,
)
print(resp.json())
const r = await fetch("https://reapi.ai/api/v1/images/generations", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "head-swap",
    image_url: "https://example.com/target-photo.jpg",
    head_image_url: "https://example.com/source-head.jpg",
  }),
});
console.log(await r.json());
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]any{
        "model":          "head-swap",
        "image_url":      "https://example.com/target-photo.jpg",
        "head_image_url": "https://example.com/source-head.jpg",
    })
    req, _ := http.NewRequest("POST",
        "https://reapi.ai/api/v1/images/generations", bytes.NewReader(body))
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    out, _ := io.ReadAll(resp.Body)
    fmt.Println(string(out))
}

Submit response

{
  "id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
  "model": "head-swap",
  "status": "processing",
  "created_at": 1735000000
}

Poll GET /api/v1/tasks/{id} (see the Tasks reference) until status === "completed". The completed payload's output.image_urls holds the swapped image URL.


Authentication

Every call needs a Bearer token. Generate keys at reapi.ai/settings/apikeys.

Authorization: Bearer YOUR_API_KEY

Endpoint

POST /api/v1/images/generations
GET  /api/v1/tasks/{id}

Submission is async. The POST returns immediately with a task_id; the task endpoint returns the same envelope until completion. Polling does not consume credits.

Head Swap is image-to-image only — there is no prompt and no size control; the output keeps the target photo's frame. Each request produces exactly one image (no n parameter) and handles one still image (no video).


Request body

model — string, required

Must be head-swap.

image_url — string, required

Public http(s) URL of the target photo: the image whose head will be replaced. The body, pose, framing, lighting and background are kept. Base64 and data: URIs are rejected.

head_image_url — string, required

Public http(s) URL of the source head: the face, hair, ears and outline that are placed onto the target. A head-and-shoulders shot with the full hair visible, facing roughly the same way as the target, gives the strongest result. Base64 and data: URIs are rejected.

seed — integer or null, optional

0 to 2147483647. Pin a seed to reproduce a result for the same two images. 0, null, or omitting the field all mean a random seed.


Pricing

Head Swap bills a flat rate per generated image, independent of the input sizes and of seed. Each request produces one image:

credits = ceil(per_image_usd × 1000)

where 1 credit = $0.001 USD. Failed and rejected requests are not charged.

The exact per-image credit cost surfaces on the model page.


Response

The poll envelope returns the image URL in output.image_urls:

{
  "id": "task_019dfd44b7fd74168541552a3260a623",
  "model": "head-swap",
  "status": "completed",
  "output": {
    "image_urls": [
      "https://...png"
    ]
  }
}

Output URLs are valid for 30 days — mirror them to your own storage if you need long-term retention.


Errors

Failures return the standard reAPI envelope { error: { code, message, request_id } }. Common cases:

  • Invalid input (a missing or non-http(s) image_url / head_image_url, a seed outside 0–2147483647, or an unknown field such as content_filter) → 400.
  • Insufficient credits → 402.
  • Rate limited → 429.
  • Upstream could not detect a usable head or failed to generate → the task ends failed and the reserved credits are refunded.

See the full catalog at /docs/api/errors.


Tips

  • Head swap vs face swap: Face Swap keeps the target's hair and head shape and changes the facial features; Head Swap replaces the whole head, hairstyle included. Pick by whether the hair should stay.
  • Source head: the full head visible, hair not cropped, no hat, facing roughly the same direction as the target. Strong angle mismatches weaken the blend at the neck.
  • Target photo: the head should be clearly visible and not tiny in the frame; the neckline and shoulders are where the swap has to join, so keep them unobstructed.
  • Batches: submit many tasks in parallel and poll the ids; pin seed when you want to re-create a specific result later.
  • Output URLs expire after 30 days — copy the file into your own storage as part of the same job.

Table of Contents