Developer API
The AWS for face protection. Integrate in 5 lines.
Enroll protected faces, screen every image upload, and automatically block deepfakes, directly inside your platform. No ML infrastructure required.
Quick start
Screen uploads in three lines
Install the SDK, create a client, and screen image uploads against the faces you enrolled. The SDK handles auth, retries, and type safety.
Install
npm install @unimpersonationable/sdk
When an image is uploaded to your platform
import { createClient } from '@unimpersonationable/sdk';
const uni = createClient(process.env.UNIMPERSONATIONABLE_API_KEY!);
// Called on every image upload:
const result = await uni.scan({ url: uploadedImageUrl });
if (result.action === 'block') {
rejectUpload('This image contains a protected person.');
}Response, action block
{
"scanId": "scan_01j...",
"facesDetected": 1,
"action": "block",
"processingTimeMs": 187,
"matches": [{
"faceId": "face_01j...",
"subjectId": "creator_42",
"similarity": 0.96,
"confidence": "high",
"action": "block"
}]
}Response, action allow
{
"scanId": "scan_01j...",
"facesDetected": 0,
"action": "allow",
"processingTimeMs": 112,
"matches": []
}Base URL
https://www.unimpersonationable.com/api/v1Auth header
X-Api-Key: uk_xxxxxxxxxxxxxAPI keys are prefixed with uk_. Generate them in Dashboard, Settings, API Keys (Enterprise plan required).
Platform integration
Enroll a face, then screen the uploads you choose
Enroll once per protected person, then call scan when an image comes in. Use verify to compare two images, and batch to process an archive in one request.
POST /faces/enrollPOST /faces/searchPOST /faces/verifyPOST /scan/batchPOST /detectGET /violations, /scans, …/api/v1/faces/enrollStore a face embedding for a protected subject. Call once per person. The returned faceId is stable and used in all future scan results.
Request body
imageUrlstringPublicly accessible image URLimageBase64string?Alternative: base64-encoded imagesubjectIdstring?Your stable ID for this personmetadataobject?Arbitrary key-value pairsResponse
{
"faceId": "face_01j...",
"subjectId": "creator_42",
"embeddingDim": 512,
"detectionConfidence": 0.97,
"enrolledAt": "2026-04-15T10:00:00Z"
}const face = await uni.enroll({
imageUrl: 'https://cdn.example.com/subject.jpg',
subjectId: 'creator_42',
metadata: { name: 'Jane Doe', tier: 'pro' },
});
console.log(face.faceId); // face_01j...curl -X POST "https://www.unimpersonationable.com/api/v1/faces/enroll" \
-H "X-Api-Key: uk_your_key" \
-H "Content-Type: application/json" \
-d '{
"imageUrl": "https://cdn.example.com/subject.jpg",
"subjectId": "creator_42"
}'/api/v1/faces/searchScreen an uploaded image against the face embeddings you enrolled. Returns a per-match list and an overall action recommendation. Call this when an image comes in at your platform.
Request body
urlstringPublicly accessible image URL to screenbase64string?Alternative: base64-encoded imagewebhookUrlstring?Receive result async via webhookaction values
blockHigh-confidence match, reject the uploadreviewMedium-confidence, flag for human reviewallowNo protected face found, permit the upload// In your upload handler:
const result = await uni.scan({ url: uploadedImageUrl });
if (result.action === 'block') {
rejectUpload('Protected person detected.');
} else if (result.action === 'review') {
flagForModeration(uploadId, result.matches);
}curl -X POST "https://www.unimpersonationable.com/api/v1/faces/search" \
-H "X-Api-Key: uk_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourplatform.com/uploads/img.jpg"
}'/api/v1/searchReverse-image search across public sources in one call, returned as structured JSON. The endpoint is CORS-enabled, so you can call it from a browser.
Request body
image_urlstring?Publicly fetchable image URL (server-side fetched, max 10 MB)image_base64string?Alternative: base64-encoded image bytes (no data URI prefix)Result fields
similarity0 to 1 score, 0.99 is a byte-identical matchface_verifiedtrue if ArcFace cosine confirmedsource_engineyandex / face_index / plebs_image / etc// From any browser dev tool (CORS-enabled):
const res = await fetch('https://www.unimpersonationable.com/api/v1/search', {
method: 'POST',
headers: {
'X-Api-Key': 'uk_your_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({ image_url: 'https://example.com/face.jpg' }),
});
const { results, metadata } = await res.json();
// Filter for face-verified URLs only:
const verified = results.filter(r => r.face_verified);curl -X POST "https://www.unimpersonationable.com/api/v1/search" \
-H "X-Api-Key: uk_your_key" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/face.jpg"
}'/api/v1/faces/verifyCompare two images and determine whether they depict the same person. Useful for identity-verification or content deduplication flows.
Request body
imageAUrlstringURL of first imageimageBUrlstringURL of second imageResponse
{
"samePerson": true,
"similarity": 0.91,
"confidence": "high"
}const result = await uni.verify(
'https://cdn.example.com/profile.jpg',
'https://cdn.example.com/upload.jpg',
);
if (result.samePerson && result.confidence === 'high') {
flagAsDuplicate();
}/api/v1/scan/batchEnqueue up to 500 image URLs for face screening in a single request. Results are delivered to your webhookUrl when the job completes, no polling required.
Request body
urlsstring[]Image URLs to scan (max 500)webhookUrlstringHTTPS endpoint for batch resultsResponse
{
"jobId": "job_01j...",
"status": "queued",
"urlCount": 50
}const job = await uni.scanBatch(
uploadedUrls, // string[] — up to 500
'https://yourapp.com/api/webhooks/uni-batch',
);
console.log(`Queued ${job.urlCount} images — job ${job.jobId}`);Authentication
API keys
All API requests require an API key passed in the X-Api-Key header. Keys are prefixed with uk_ and available on the Enterprise plan. Generate keys in Dashboard, Settings, API Keys.
curl -X GET "https://www.unimpersonationable.com/api/v1/violations" \ -H "X-Api-Key: uk_your_api_key_here" \ -H "Content-Type: application/json"
Rate limits
Limits by plan
Rate limit headers X-RateLimit-Remaining and X-RateLimit-Reset are included in all responses.
OpenAPI
Machine-readable spec
The full OpenAPI 3.1 spec is available at the URL below. Import it into Postman, Insomnia, or any OpenAPI-compatible tool to get request builders, and use the same spec to generate SDKs.
https://www.unimpersonationable.com/api/v1/openapi.jsonGETCore API
Manage violations and pull your own analytics
Account
/api/v1/meReturn the authenticated user's account info: plan, email, created_at.
const res = await fetch('https://www.unimpersonationable.com/api/v1/me', {
headers: { 'X-Api-Key': process.env.UNIMPERSONATIONABLE_API_KEY! },
});
const { id, email, plan, created_at } = await res.json();/api/v1/statsReturn violation/scan/takedown counts for the current user.
{
"violations": { "total": 42, "detected": 5, "removed": 37 },
"scans": { "total": 120 },
"takedowns": { "total": 14, "pending": 2, "success": 12 }
}/api/v1/usageReturn metered API usage for the current billing period.
{
"period": { "start": "2026-04-01", "end": "2026-04-30" },
"usage": { "scans": 48, "scansLimit": 200, "apiRequests": 381 }
}/api/v1/keysList API keys. Requires session auth (browser only, not callable via API key). Manage keys in Dashboard, Settings.
Violations
/api/v1/violationsList violations. Filterable by status and platform.
Query parameters
limitinteger50 (max 100)offsetinteger0statusstringdetected | dmca_filed | removedplatformstringInstagram, TikTok, YouTube…Response
{
"data": [{
"id": "vio_01j...",
"platform": "Instagram",
"type": "DEEPFAKE",
"status": "detected",
"severity": "critical",
"detected_at": "2026-04-01T12:00:00Z"
}],
"pagination": {
"limit": 50, "offset": 0,
"total": 127, "hasMore": true
}
}const res = await fetch('https://www.unimpersonationable.com/api/v1/violations?status=detected&limit=10', {
headers: { 'X-Api-Key': process.env.UNIMPERSONATIONABLE_API_KEY! },
});
const { data, pagination } = await res.json();/api/v1/violations/:idFetch a single violation by ID.
/api/v1/violations/:id/takedownInitiate a DMCA takedown for a specific violation. Requires Enterprise plan.
curl -X POST "https://www.unimpersonationable.com/api/v1/violations/vio_01j.../takedown" \ -H "X-Api-Key: uk_your_api_key_here" \ -H "Content-Type: application/json"
/api/v1/violations/:id/evidenceDownload a SHA-256 signed evidence package (screenshot, metadata, chain of custody) suitable for DMCA filings or legal proceedings.
{
"violationId": "vio_01j...",
"capturedAt": "2026-04-01T12:00:00Z",
"downloadUrl": "https://...",
"expiresAt": "2026-04-08T12:00:00Z",
"metadata": {
"platform": "Instagram",
"hashSha256": "a3f7b..."
}
}Takedowns
/api/v1/takedownsList all takedown requests. Filterable by status pending | sent | success | failed.
{
"data": [{
"id": "tkd_01j...",
"violation_id": "vio_01j...",
"platform": "Instagram",
"status": "sent",
"method": "DMCA",
"sent_at": "2026-04-02T09:00:00Z"
}]
}/api/v1/takedowns/:idFetch a single takedown request, including full status history and escalation log.
Detection
/api/v1/detectRun AI/deepfake detection on an image URL. Returns confidence score and detected AI model.
Request body
imageUrlstringURL of the image to analyzeimageBase64string?Alternative: base64-encoded imageResponse
{
"isDeepfake": true,
"confidence": 0.94,
"faceMatch": 0.89,
"aiModel": "Kling",
"provider": "resemble_ai"
}/api/v1/scansTrigger a new scan job. Returns a scan ID immediately. Results available via GET /scans.
curl -X POST "https://www.unimpersonationable.com/api/v1/scans" \
-H "X-Api-Key: uk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"type": "deepfake", "imageUrl": "https://example.com/image.jpg"}'/api/v1/scansList recent scans. Poll after triggering to check status.
const res = await fetch('https://www.unimpersonationable.com/api/v1/scans', {
headers: { 'X-Api-Key': process.env.UNIMPERSONATIONABLE_API_KEY! },
});
const { data } = await res.json();
// data[0].status === 'complete' | 'pending' | 'running' | 'failed'
// data[0].score === 0.0–1.0 (deepfake confidence)Monitoring
/api/v1/watchlistList your monitoring keywords. Active keywords are used in every scheduled scan.
/api/v1/watchlistAdd a keyword to your watchlist.
curl -X POST "https://www.unimpersonationable.com/api/v1/watchlist" \
-H "X-Api-Key: uk_your_api_key_here" \
-d '{"keyword": "your public name"}'/api/v1/watchlist/:idRemove a keyword from your watchlist.
/api/v1/social-handlesList your registered social handles used for impersonation detection.
/api/v1/social-handlesRegister a social handle for impersonation monitoring.
curl -X POST "https://www.unimpersonationable.com/api/v1/social-handles" \
-H "X-Api-Key: uk_your_api_key_here" \
-d '{"platform": "Instagram", "handle": "@yourhandle"}'/api/v1/social-handles/:idRemove a social handle from monitoring.
/api/v1/platformsList all supported monitoring platforms (70+) with removal time and violation counts.
Analytics
/api/v1/reportsAggregated summary over a time period. Useful for management reports and dashboards.
Query parameters
periodstring7d | 30d (default) | 90dResponse
{
"period": "30d",
"summary": {
"violationsDetected": 14,
"violationsRemoved": 11,
"scansRun": 62
},
"generatedAt": "2026-04-07T..."
}Intel
/api/v1/intelLive threat intelligence feed and top threat signals across the platform (anonymized). Enterprise plan required.
{
"intel": [{
"id": "...",
"date": "2026-04-10",
"severity": "CRITICAL",
"title": "New deepfake marketplace on Tor",
"description": "..."
}],
"signals": [{
"domain": "tor-deepfakes.onion",
"violation_type": "DEEPFAKE",
"occurrence_count": 147
}]
}Webhooks
Get notified when an event fires
Register an HTTPS endpoint to receive POST requests whenever key events occur. Works natively with Zapier and Make.com. Use a Custom Webhook trigger and paste your endpoint URL into the dashboard.
violation.detectedviolation.removedscan.completescan.batch.completedmca.filedlicensing_request.receivedPayload structure
{
"event": "violation.detected",
"timestamp": "2026-04-07T14:22:00.000Z",
"data": {
"violationId": "vio_01j...",
"platform": "Instagram",
"url": "https://instagram.com/p/...",
"type": "DEEPFAKE",
"severity": "critical",
"detectedAt": "2026-04-07T14:22:00.000Z"
}
}Signature verification
Every delivery includes an X-Unimpersonationable-Signature header. HMAC-SHA256 of the raw request body signed with your webhook secret. Always verify before processing.
import { createHmac } from 'crypto';
export function verifyWebhookSignature(
rawBody: string,
signature: string,
secret: string,
): boolean {
const expected = createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return expected === signature;
}
export async function POST(req: Request) {
const body = await req.text();
const sig = req.headers.get('x-unimpersonationable-signature') ?? '';
if (!verifyWebhookSignature(body, sig, process.env.WEBHOOK_SECRET!)) {
return new Response('Unauthorized', { status: 401 });
}
const payload = JSON.parse(body);
// Handle payload.event ...
return new Response('OK');
}Manage webhook endpoints
Add, test, and view delivery logs from your dashboard.
SDKs
Client libraries
JavaScript / TypeScript
Availablenpm install @unimpersonationable/sdkFull TypeScript types, compatible with Node.js and the browser. It ships two client shapes:createClient() for platform integration andUnimpersonationable for full violation management.
import { createClient, Unimpersonationable } from '@unimpersonationable/sdk';
// Platform integration — upload screening:
const uni = createClient(process.env.UNIMPERSONATIONABLE_API_KEY!);
const result = await uni.scan({ url: imageUrl });
if (result.action === 'block') rejectUpload();
// Full violation management:
const client = new Unimpersonationable({ apiKey: 'uk_...' });
const { data } = await client.violations.list({ status: 'detected' });
const evidence = await client.violations.evidence(data[0].id);Python
Availablepip install unimpersonationableZero dependencies, runs on Python 3.8 and up, with typed dataclasses for every response.
from unimpersonationable import Unimpersonationable
client = Unimpersonationable(api_key="uk_...")
# List violations
violations = client.violations.list(status="detected")
print(f"{len(violations)} active violations")
# Evidence package
evidence = client.violations.evidence(violations[0]["id"])
print(evidence["download_url"])
# Takedown
client.violations.takedown(violations[0]["id"])Error reference
HTTP status codes
Get started
Ready to integrate?
API access is included in the Enterprise plan. Generate your first key and make your first request from the dashboard.