For decision makers: TamperCheck plugs into your existing systems via a simple API - typically one sprint to integrate, no proprietary format, and no mandatory dashboard for compliance teams. The reference below is for engineers implementing the integration.
API Documentation
REST API for document fraud analysis, deepfake detection, and scan extraction. Default mode=async or instant for a blocking response.
Authentication
Send your API key as Authorization: Bearer dt_... (or X-API-Key). Create keys under Dashboard → Developers.
API reference
Base URL: https://api.tampercheck.ai. Same auth on every route except PDF download.
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/documents/ | Analyze a document or image |
POST | /api/v1/extract-documents/ | Split a multi-document scan into crops |
GET | /api/v1/documents/list/ | List jobs for this API key |
GET | /api/v1/documents/<uuid>/status/ | Lightweight async poll |
GET | /api/v1/documents/<uuid>/ | Full job result |
POST | /api/v1/documents/<uuid>/report-link/ | Mint single-use PDF report URL |
GET | /api/v1/reports/download/ | Download PDF via token (no API key) |
GET | /api/v1/usage/ | Job usage summary |
GET | /api/v1/wallet/usage/ | Wallet ledger (free) |
Strategies
Choose what kind of work a job does. Analyze accepts a strategy field; extraction always uses its own endpoint.
| Strategy | How to call | Returns |
|---|---|---|
tampering_detectionDefault | POST /documents/ | authentic / tampered, risk score, findings |
deepfake_detection | POST /documents/ + strategy=deepfake_detection | authentic / ai_generated / face_swap / uncertain, plus artifact_breakdown |
document_extraction | POST /extract-documents/ | Page-scoped pages[].images[] crops (no verdict) |
Analyze
Multipart upload. File field document (PDF, JPG, JFIF, PNG, WEBP, BMP, TIFF; max 40 MB).
| Field | Required | Description |
|---|---|---|
document | Yes | File to analyze |
strategy | No | tampering_detection (default) or deepfake_detection |
mode | No | async (default) or instant |
document_identifier | No | Your correlation id (max 512) |
webhook_id | No | Target a specific webhook UUID |
suppress_categories | No | JSON array of finding keys to exclude |
pdf_password | No | Password for encrypted PDFs. Returns pdf_password_required (400) if needed but missing, pdf_password_incorrect (400) if wrong. |
curl -sS -X POST "https://api.tampercheck.ai/api/v1/documents/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "document=@./statement.pdf" \ -F "strategy=tampering_detection" \ -F "mode=async" \ -F "document_identifier=loan-app-12345"
Deepfake example
curl -sS -X POST "https://api.tampercheck.ai/api/v1/documents/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "document=@./portrait.jpg" \ -F "strategy=deepfake_detection" \ -F "mode=async"
Async & instant
| Mode | HTTP | Next step |
|---|---|---|
async | 202 | Poll status, then fetch detail (or use webhooks) |
instant | 200 | Full result in the same response |
202 Accepted body
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"original_filename": "statement.pdf",
"document_identifier": "loan-app-12345",
"page_count": 3,
"documents_billed": 3
}Poll with exponential backoff (start ~1s, cap ~5–10s). Stop on completed or failed.
Completed responses
Tampering detection
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"run_mode": "instant",
"strategy": "tampering_detection",
"original_filename": "statement.pdf",
"document_identifier": "loan-app-12345",
"document_type": "bank_statement",
"document_subtype": "Indian Savings Account Statement",
"verdict": "tampered",
"risk_score": 42,
"confidence": 0.78,
"page_count": 1,
"documents_billed": 1,
"findings": [
{
"category": "font_inconsistency",
"severity": "medium",
"description": "Mixed font metrics in the totals row.",
"confidence": 0.71
}
],
"human_summary": "Plain-language summary of the main issues…",
"created_at": "2026-04-02T12:00:00Z",
"completed_at": "2026-04-02T12:00:03Z"
}Deepfake detection
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"strategy": "deepfake_detection",
"verdict": "ai_generated",
"risk_score": 88,
"confidence": 0.91,
"findings": [
{
"category": "provenance",
"severity": "high",
"description": "Missing camera metadata typical of generator output."
}
],
"artifact_breakdown": {
"provenance": { "score": 92, "issues": ["missing EXIF"] }
},
"human_summary": "Strong signals of AI image generation."
}Extract documents
Split a multi-document scan into PNG crops. Same auth and mode / webhook_id as analyze. Sets strategy=document_extraction server-side. Billing: ceil(pages / 6) extraction units.
curl -sS -X POST "https://api.tampercheck.ai/api/v1/extract-documents/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "document=@./scan.pdf" \ -F "mode=async"
Completed shape
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"run_mode": "instant",
"strategy": "document_extraction",
"original_filename": "scan.pdf",
"page_count": 2,
"documents_billed": 1,
"pages": [
{
"page": 1,
"images": [
{
"index": 1,
"content_type": "image/png",
"data": "<base64>",
"bbox": {"x": 12, "y": 40, "width": 800, "height": 1200}
}
]
}
]
}Suppress categories
On analyze only: exclude finding categories from verdict and risk score after QC. Unknown keys are ignored.
curl -sS -X POST "https://api.tampercheck.ai/api/v1/documents/" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "document=@./bank_statement.pdf" \ -F "mode=async" \ -F 'suppress_categories=["signature_forgery", "jpeg_ghost_splicing"]'
Common keys: signature_forgery, jpeg_ghost_splicing, ela_anomaly, font_size_inconsistency, metadata_image_editor, double_jpeg_compression.
List, status & detail
Jobs for this API key (includes strategy and run_mode).
Lightweight poll: status, verdict/score when ready, page_count, documents_billed, timestamps.
Full result for completed jobs (analysis or extraction shape depending on strategy).
PDF reports
Mint a single-use, 30-minute HTTPS URL for the forensic PDF. Completed jobs only. Response includes download_url, expires_at, expires_in_seconds (1800).
curl -sS -X POST "https://api.tampercheck.ai/api/v1/documents/<job-uuid>/report-link/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# Then (no Authorization header; single-use):
curl -sS -L "PASTE_download_url_HERE" -o report.pdfReplay after first download → 410. Expired token → error. Dashboard downloads use session auth instead of this token flow.
Webhooks
Register URLs under Dashboard → Developers → Webhooks. On completed / failed, TamperCheck POSTs the same body as job detail.
- With
webhook_id: only that webhook is notified. - Without: all active webhooks on the account (broadcast).
- 400
invalid_webhook_idif unknown, inactive, or not yours.
POST https://your-app.example/webhooks/tampercheck
Content-Type: application/json
X-Webhook-ID: 7c9e6679-7425-40de-944b-e07fc1f90ae7
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"strategy": "tampering_detection",
"verdict": "tampered",
"risk_score": 42,
"confidence": 0.78,
"findings": [],
"created_at": "2026-04-02T12:00:00Z",
"completed_at": "2026-04-02T12:00:03Z"
}Headers: X-Webhook-ID, X-Webhook-Signature (sha256=<hex> HMAC of raw body).
import hmac, hashlib
def verify_webhook(body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
provided = signature_header.removeprefix("sha256=")
return hmac.compare_digest(expected, provided)Usage summary
Aggregates completed jobs for this API key: document counts, tokens, estimated cost. Dates are inclusive calendar days in UTC.
curl -sS "https://api.tampercheck.ai/api/v1/usage/?since=2026-08-01&until=2026-08-07" \ -H "Authorization: Bearer YOUR_API_KEY"
Wallet usage
Paginated wallet credits and debits for the account (API key owner). Free — does not charge the wallet. Works even when services are suspended. Optional page / page_size (default 25, max 100).from / to accepted as aliases for since / until.
curl -sS "https://api.tampercheck.ai/api/v1/wallet/usage/?since=2026-08-01&until=2026-08-07" \ -H "Authorization: Bearer YOUR_API_KEY"
Example response
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"entry_type": "document_fee",
"amount": "-0.50",
"balance_after": "46.06",
"description": "Document analysis - statement.pdf (1 pages, 1 check)",
"metadata": {},
"job": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2026-08-07T03:41:00Z"
}
]
}entry_type values include document_fee, document_extraction_fee, platform_ai_markup, top_up, signup_credit. Amounts are positive for credits, negative for debits.
Errors
JSON body with error and detail. Some include job id / status.
| Status | Meaning | Action |
|---|---|---|
400 | Validation / invalid webhook | Fix file type, size, or webhook UUID |
401 | Missing or invalid API key | Check Bearer token |
402 | No payment method, or suspended wallet | Top up at Dashboard → Billing |
404 | Unknown job for this key | Verify UUID and API key |
410 | Report link already used | Mint a new report-link |
422 | Unprocessable file (no charge) | Re-export / re-scan the file |
503 | AI service unavailable (no charge) | Retry with backoff |
Claude Code and agent skills
Download the TamperCheck API skill (Markdown + YAML frontmatter) for Cursor, Claude Code, or any workflow that loads project skills.
Download skill.md