Face Swap
Face Swap on reAPI — send a target photo and a source face, get one swapped image back with the target's pose, lighting and background kept. Seed control, flat price per image, playground and API.
Face Swap replaces the face in a target photo with the face from a
source image, keeping the target's 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.
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": "face-swap",
"image_url": "https://example.com/target-photo.jpg",
"face_image_url": "https://example.com/source-face.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": "face-swap",
"image_url": "https://example.com/target-photo.jpg",
"face_image_url": "https://example.com/source-face.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: "face-swap",
image_url: "https://example.com/target-photo.jpg",
face_image_url: "https://example.com/source-face.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": "face-swap",
"image_url": "https://example.com/target-photo.jpg",
"face_image_url": "https://example.com/source-face.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": "face-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_KEYEndpoint
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.
Face 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 face-swap.
image_url — string, required
Public http(s) URL of the target photo: the image whose face will be
replaced. Everything else in it — pose, framing, lighting, hair, background —
is kept. Base64 and data: URIs are rejected.
face_image_url — string, required
Public http(s) URL of the source face: the face that is placed onto the
target. A clear, front-facing shot in even light gives the strongest result.
Base64 and data: URIs are rejected.
seed — integer or null, optional
Pin a seed to reproduce a result for the same two images. 0, null, or
omitting the field all mean a random seed. No range is enforced beyond it
being an integer.
Pricing
Face 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": "face-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/face_image_url, a non-integerseed, or an unknown field such ascontent_filter) →400. - Insufficient credits →
402. - Rate limited →
429. - Upstream could not detect a usable face or failed to generate → the task
ends
failedand the reserved credits are refunded.
See the full catalog at /docs/api/errors.
Tips
- Source face: front-facing, evenly lit, unobstructed (no sunglasses, no hand over the mouth). The larger and sharper the face, the better the transfer.
- Target photo: the face should be clearly visible and not tiny in the frame. Strong side angles and heavy occlusion weaken the swap.
- What stays: hair, head shape, skin tone of the body, pose and background all come from the target. If you need the whole head replaced, that is a head swap, a different operation.
- Batches: submit many tasks in parallel and poll the ids; pin
seedwhen 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.
Related
- Z-Image Pro — text-to-image on the same API-key-only terms
- Qwen Image 3 — prompt-driven image editing
- Tasks API
- Error codes