API Documentation
The Prospolabs FaceSwap API lets you seamlessly swap faces in images using state-of-the-art AI models. Integrate realistic or cartoon-style face swaps into your applications with just a few lines of code. All endpoints return JSON and accept base64-encoded images.
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 sk-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 sk-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": "png"8 }'
Model Endpoints
/v1/swap/realisticRealisticPerform a photorealistic face swap between the source and target images. Produces high-fidelity output suitable for professional use cases.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
source_image | string (base64) | Yes | Base64-encoded source face image |
target_image | string (base64) | Yes | Base64-encoded target image |
output_format | "png" | "jpg" | No | Output image format (default: png) |
webhook_url | string | No | URL to receive completion callback |
Response
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique inference identifier |
status | "completed" | "processing" | "failed" | Yes | Current inference status |
model | "realistic" | "cartoon" | Yes | Model used for inference |
result_url | string | null | Yes | URL of the result image (null if not yet complete) |
processing_time_ms | number | Yes | Processing time in milliseconds |
created_at | string | Yes | ISO 8601 timestamp of creation |
Response Example
1{2 "id": "inf_abc123def456",3 "status": "completed",4 "model": "realistic",5 "result_url": "https://cdn.prospolabs.com/results/inf_abc123def456.png",6 "processing_time_ms": 11234,7 "created_at": "2026-02-19T14:32:15.000Z"8}
Sync vs Async API
Set the processing mode via the X-Processing-Mode header. Default is sync.
X-Processing-Mode: syncThe request blocks until processing completes. The response includes the result directly with status completed. Best for interactive applications and playgrounds.
Timeout: 60 seconds max. If processing exceeds this, use async mode.
Response
1{2 "id": "inf_abc123def456",3 "status": "completed",4 "model": "realistic",5 "result_url": "https://cdn.prospolabs.com/results/inf_abc123def456.png",6 "processing_time_ms": 11234,7 "created_at": "2026-02-19T14:32:15.000Z"8}
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
| Event | Description |
|---|---|
inference.completed | Face swap completed successfully. Includes result_url. |
inference.failed | Face swap processing failed. Includes error details. |
credits.low | Account credits dropped below threshold ($1.00). |
Payload Format
1{2 "event": "inference.completed",3 "job_id": "job_abc123def456",4 "data": {5 "id": "inf_abc123def456",6 "status": "completed",7 "model": "realistic",8 "result_url": "https://cdn.prospolabs.com/results/inf_abc123def456.png",9 "processing_time_ms": 11234,10 "created_at": "2026-02-19T14:32:15.000Z"11 },12 "timestamp": "2026-02-19T14:32:27.000Z"13}
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';23function verifyWebhook(payload, signature, secret) {4 const expected = crypto5 .createHmac('sha256', secret)6 .update(payload)7 .digest('hex');8 return crypto.timingSafeEqual(9 Buffer.from(signature),10 Buffer.from(expected)11 );12}1314// 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_SECRET21 );22 if (!isValid) return res.status(401).send('Invalid signature');2324 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
API requests are rate-limited to ensure fair usage. Limits vary by plan. Check the response headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset to monitor your current usage.
| Plan | Rate Limit | Daily Limit |
|---|---|---|
| Free | 3 requests total | 3 total (trial) |
| Standard | 10 requests / minute | 1,000 requests / day |
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.
| Status | Name | Description |
|---|---|---|
| 400 | Bad Request | Invalid request body or missing required fields |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Insufficient credits or account suspended |
| 413 | Payload Too Large | Image exceeds 10MB size limit |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
Error Response Example
1{2 "error": {3 "code": "INVALID_IMAGE",4 "message": "The source image could not be processed. Ensure it contains a detectable face.",5 "status": 4006 }7}