Face Swap API Documentation

The Prospolabs FaceSwap API lets you seamlessly swap faces in images using state-of-the-art AI models. Integrate realistic, cartoon, or fast face swaps into your applications with just a few lines of code. All endpoints return JSON and accept base64-encoded images or image URLs.

Authentication

All API requests require a Bearer token in the Authorization header. You can generate API keys from your Dashboard. Keep your keys secret and never expose them in client-side code.

1Authorization: Bearer prsp-your-api-key

Quick Start

Get started with a face swap in under a minute. Choose your preferred language below to see a complete working example.

1curl -X POST https://api.prospolabs.com/v1/swap/realistic \
2 -H "Authorization: Bearer prsp-your-api-key" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "source_image": "base64_encoded_source...",
6 "target_image": "base64_encoded_target...",
7 "output_format": "jpeg",
8 "output_quality": 95
9 }'

Model Endpoints

POST/v1/swap/realisticRealistic

Perform a photorealistic face swap between the source and target images. Produces high-fidelity output suitable for professional use cases.

Request Body

FieldTypeRequiredDescription
source_imagestring (base64 or URL)YesBase64-encoded source face image or image URL
target_imagestring (base64 or URL)YesBase64-encoded target image or image URL
promptstring | nullNoOptional text prompt to guide the face swap (default: null)
output_format"jpeg" | "png" | "webp"NoOutput image format (default: "jpeg")
output_qualityinteger (10–100)NoOutput image quality (default: 95)

Response

FieldTypeRequiredDescription
request_idstringYesUnique request identifier (UUID)
status"completed" | "failed"YesInference result status
model"realistic" | "cartoon" | "fast" | "cartoon-lite"YesModel used for inference
result_urlstring | nullYesPre-signed URL of the result image (expires after 24 hours by default)
inference_timenumber | nullYesProcessing time in seconds

Response Example

1{
2 "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
3 "status": "completed",
4 "model": "realistic",
5 "result_url": "https://storage.example.com/results/a1b2c3d4.jpeg?token=...",
6 "inference_time": 2.05
7}

Sync vs Async API

Use the standard endpoint for synchronous processing, or append /async to the path for asynchronous processing (e.g. /v1/swap/realistic/async).

POST /v1/swap/realistic

The request blocks until processing completes. The response includes the result directly with status completed. Best for interactive applications and playgrounds.

Timeout: 120 seconds max. If processing exceeds this, use async mode.

Response

1{
2 "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
3 "status": "completed",
4 "model": "realistic",
5 "result_url": "https://storage.example.com/results/a1b2c3d4.jpeg?token=...",
6 "inference_time": 2.05
7}

Webhooks

Webhooks allow you to receive real-time notifications when events occur in your account. Configure a webhook URL in your dashboard or pass it per-request via the webhook_url field.

Event Types

EventDescription
inference.completedFace swap completed successfully. Includes result_url.
inference.failedFace swap processing failed. Includes error details.

Payload Format

1{
2 "event": "inference.completed",
3 "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
4 "data": {
5 "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
6 "model": "realistic",
7 "result_url": "https://storage.example.com/results/a1b2c3d4.jpeg?token=...",
8 "processing_time_ms": 2050
9 },
10 "timestamp": "2026-02-19T14:32:27.000Z"
11}

Verifying Webhook Signatures

Every webhook includes an X-Prospo-Signature header containing an HMAC-SHA256 signature. Verify it against your webhook secret to ensure the request is authentic.

1import crypto from 'crypto';
2
3function verifyWebhook(payload, signature, secret) {
4 const expected = crypto
5 .createHmac('sha256', secret)
6 .update(payload)
7 .digest('hex');
8 return crypto.timingSafeEqual(
9 Buffer.from(signature),
10 Buffer.from(expected)
11 );
12}
13
14// In your webhook handler:
15app.post('/api/webhook', (req, res) => {
16 const signature = req.headers['x-prospo-signature'];
17 const isValid = verifyWebhook(
18 JSON.stringify(req.body),
19 signature,
20 process.env.WEBHOOK_SECRET
21 );
22 if (!isValid) return res.status(401).send('Invalid signature');
23
24 const { event, data } = req.body;
25 if (event === 'inference.completed') {
26 console.log('Result ready:', data.result_url);
27 }
28 res.status(200).send('OK');
29});

Retry Policy

If your endpoint returns a non-2xx status code, we'll retry delivery with exponential backoff:

  • 1First retry: 30 seconds after initial attempt
  • 2Second retry: 2 minutes after first retry
  • 3Third retry: 10 minutes after second retry
  • 4Final retry: 1 hour after third retry
  • 5After 4 failed attempts, the webhook is marked as failed

Rate Limits

The Prospolabs API is built for high-throughput workloads. Monitor your current usage via the response headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.

We support very high request volumes. If you need custom rate limits, dedicated throughput, or SLA guarantees for your use case, reach out and we'll work with you directly.

Contact us for higher limits →

Error Handling

The API uses standard HTTP status codes to indicate the outcome of requests. All error responses include a JSON body with a machine-readable code and a human-readable message.

StatusNameDescription
400Bad RequestInvalid request body, missing required fields, or unprocessable image
401UnauthorizedMissing or invalid API key / Bearer token
403ForbiddenInsufficient credits or account suspended
404Not FoundJob not found (for polling endpoint)
429Too Many RequestsRate limit exceeded. Check X-RateLimit-* headers
500Internal Server ErrorUnexpected server error. Your credits are automatically refunded
504Gateway TimeoutGPU service unavailable or timed out

Error Response Example

1{
2 "detail": "Insufficient credits. Please top up your balance."
3}