Skip to contentUNI

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.

REST APITypeScript SDKPython SDKWebhooksOpenAPI 3.1Defend plan required

Quick Start

Protect every upload in 3 lines

Install the SDK, create a client, and screen every image upload. The SDK handles auth, retries, and type safety.

Install

bash
npm install @unimpersonationable/sdk

On every image upload at your platform

typescript
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/v1

Auth Header

X-Api-Key: uk_xxxxxxxxxxxxx

API keys are prefixed with uk_. Generate them in Dashboard → Settings → API Keys (Defend plan required).

Platform Integration

Face enrollment & upload screening

Four endpoints. Enroll once per protected person, then call scan on every upload. Verify to compare two images. Batch to process archives.

Endpoint
Operation
Price / call
POST /faces/enroll
Store face embedding
$0.24
POST /faces/search
Screen image (all enrolled faces)
$0.24
POST /faces/verify
1:1 face comparison
$0.24
POST /scan/batch
Per URL in batch
$0.18
POST /detect
AI/deepfake detection
$0.02
GET /violations, /scans, …
CRUD + analytics
Free
POST/api/v1/faces/enroll

Store 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 URL
imageBase64string?Alternative: base64-encoded image
subjectIdstring?Your stable ID for this person
metadataobject?Arbitrary key-value pairs

Response

{
  "faceId": "face_01j...",
  "subjectId": "creator_42",
  "embeddingDim": 512,
  "detectionConfidence": 0.97,
  "enrolledAt": "2026-04-15T10:00:00Z"
}
typescript
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
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"
  }'
POST/api/v1/faces/search

Screen an uploaded image against all enrolled face embeddings. Returns a per-match list and an overall action recommendation. Call this on every image upload at your platform.

Request Body

urlstringPublicly accessible image URL to screen
base64string?Alternative: base64-encoded image
webhookUrlstring?Receive result async via webhook

action values

blockHigh-confidence match — reject the upload
reviewMedium-confidence — flag for human review
allowNo protected face found — permit the upload
typescript
// 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
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"
  }'
POST/api/v1/search

Reverse-image search across every wired engine in one call — Yandex, Bing HTML, Google Lens (via residential extension), TinEye, Mailru, Sogou, our internal face_index, 4plebs image-hash, and more. Lenso.ai-comparable response shape. CORS-enabled, browser-callable.

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–1 score · 0.99 = byte-identical match
face_verifiedtrue if ArcFace cosine confirmed
source_engineyandex / face_index / plebs_image / etc
typescript
// 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
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"
  }'
POST/api/v1/faces/verify

Compare two images and determine whether they depict the same person. Useful for identity-verification or content deduplication flows.

Request Body

imageAUrlstringURL of first image
imageBUrlstringURL of second image

Response

{
  "samePerson": true,
  "similarity": 0.91,
  "confidence": "high"
}
typescript
const result = await uni.verify(
  'https://cdn.example.com/profile.jpg',
  'https://cdn.example.com/upload.jpg',
);
if (result.samePerson && result.confidence === 'high') {
  flagAsDuplicate();
}
POST/api/v1/scan/batch

Enqueue 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 results

Response

{
  "jobId": "job_01j...",
  "status": "queued",
  "urlCount": 50
}
typescript
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 Defend plan and above. Generate keys in Dashboard → Settings → API Keys.

curl
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

Plan
Requests / hour
Scans / day
Defend
100
20
Agency
5,000
1,000
Whitelabel
20,000
5,000
Enterprise
Custom
Custom

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 into Postman, Insomnia, or any OpenAPI-compatible tool for auto-generated request builders. Also used for automatic SDK generation.

https://www.unimpersonationable.com/api/v1/openapi.jsonGET

Core API

Violation Management & Analytics

AccountViolationsTakedownsDetectionMonitoringAnalyticsLegalIntel

Account

GET/api/v1/me

Return the authenticated user's account info: plan, email, created_at.

typescript
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();
GET/api/v1/stats

Return 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 }
}
GET/api/v1/usage

Return metered API usage for the current billing period.

{
  "period": { "start": "2026-04-01", "end": "2026-04-30" },
  "usage":  { "scans": 48, "scansLimit": 200, "apiRequests": 381 }
}
GET/api/v1/keys

List API keys. Requires session auth (browser only — not callable via API key). Manage keys in Dashboard → Settings.

Violations

GET/api/v1/violations

List violations. Filterable by status and platform.

Query Parameters

limitinteger50 (max 100)
offsetinteger0
statusstringdetected | dmca_filed | removed
platformstringInstagram, 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
  }
}
typescript
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();
GET/api/v1/violations/:id

Fetch a single violation by ID.

POST/api/v1/violations/:id/takedown

Initiate a DMCA takedown for a specific violation. Requires Defend plan.

curl
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"
GET/api/v1/violations/:id/evidence

Download 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

GET/api/v1/takedowns

List 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"
  }]
}
GET/api/v1/takedowns/:id

Fetch a single takedown request, including full status history and escalation log.

Detection

POST/api/v1/detect

Run AI/deepfake detection on an image URL. Returns confidence score and detected AI model.

Request Body

imageUrlstringURL of the image to analyze
imageBase64string?Alternative: base64-encoded image

Response

{
  "isDeepfake": true,
  "confidence": 0.94,
  "faceMatch": 0.89,
  "aiModel": "Kling",
  "provider": "resemble_ai"
}
POST/api/v1/scans

Trigger a new scan job. Returns a scan ID immediately; results available via GET /scans.

curl
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"}'
GET/api/v1/scans

List recent scans. Poll after triggering to check status.

typescript
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

GET/api/v1/watchlist

List your monitoring keywords. Active keywords are used in every scheduled scan.

POST/api/v1/watchlist

Add a keyword to your watchlist.

curl
curl -X POST "https://www.unimpersonationable.com/api/v1/watchlist" \
  -H "X-Api-Key: uk_your_api_key_here" \
  -d '{"keyword": "your public name"}'
DELETE/api/v1/watchlist/:id

Remove a keyword from your watchlist.

GET/api/v1/social-handles

List your registered social handles used for impersonation detection.

POST/api/v1/social-handles

Register a social handle for impersonation monitoring.

curl
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"}'
DELETE/api/v1/social-handles/:id

Remove a social handle from monitoring.

GET/api/v1/platforms

List all supported monitoring platforms (70+) with removal time and violation counts.

Analytics

GET/api/v1/reports

Aggregated summary over a time period. Useful for management reports and dashboards.

Query Parameters

periodstring7d | 30d (default) | 90d

Response

{
  "period": "30d",
  "summary": {
    "violationsDetected": 14,
    "violationsRemoved": 11,
    "scansRun": 62
  },
  "generatedAt": "2026-04-07T..."
}

Intel

GET/api/v1/intel

Live threat intelligence feed and top threat signals across the platform (anonymized). Defend 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

Real-Time Events

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.

Event
Trigger
Plan
violation.detected
A new violation is found during scanning
All
violation.removed
Platform confirms content removed
All
scan.complete
A queued scan finishes processing
All
scan.batch.complete
A batch scan job finishes
Defend+
dmca.filed
A DMCA notice is submitted
Defend+
licensing_request.received
A brand submits a licensing request
Protect+

Payload Structure

json
{
  "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.

typescript
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.

OPEN SETTINGS →

SDKs

Client Libraries

JavaScript / TypeScript

Available
npm install @unimpersonationable/sdk

Full TypeScript types. Node.js and browser compatible. Two client shapes:createClient() for platform integration andUnimpersonationable for full violation management.

typescript
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

Available
pip install unimpersonationable

Zero dependencies. Python 3.8+. Typed dataclasses for all responses.

python
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

200
OK
Request succeeded
202
Accepted
Job queued (batch operations)
400
Bad Request
Missing or invalid parameters
401
Unauthorized
Missing or invalid API key
403
Forbidden
Plan does not include this feature
429
Too Many Requests
Rate limit exceeded — retry after X-RateLimit-Reset
500
Internal Server Error
Server-side error — contact support

Get Started

Ready to integrate?

API access is included in the Defend plan. Generate your first key and make your first request in under 5 minutes.