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.

Get API keyskill.md

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.

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

StrategyHow to callReturns
tampering_detection
Default
POST /documents/authentic / tampered, risk score, findings
deepfake_detectionPOST /documents/ + strategy=deepfake_detectionauthentic / ai_generated / face_swap / uncertain, plus artifact_breakdown
document_extractionPOST /extract-documents/Page-scoped pages[].images[] crops (no verdict)

Analyze

POST https://api.tampercheck.ai/api/v1/documents/

Multipart upload. File field document (PDF, JPG, JFIF, PNG, WEBP, BMP, TIFF; max 40 MB).

FieldRequiredDescription
documentYesFile to analyze
strategyNotampering_detection (default) or deepfake_detection
modeNoasync (default) or instant
document_identifierNoYour correlation id (max 512)
webhook_idNoTarget a specific webhook UUID
suppress_categoriesNoJSON array of finding keys to exclude
pdf_passwordNoPassword 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

ModeHTTPNext step
async202Poll status, then fetch detail (or use webhooks)
instant200Full 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

POST https://api.tampercheck.ai/api/v1/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

GET https://api.tampercheck.ai/api/v1/documents/list/

Jobs for this API key (includes strategy and run_mode).

GET https://api.tampercheck.ai/api/v1/documents/<uuid>/status/

Lightweight poll: status, verdict/score when ready, page_count, documents_billed, timestamps.

GET https://api.tampercheck.ai/api/v1/documents/<uuid>/

Full result for completed jobs (analysis or extraction shape depending on strategy).

PDF reports

POST https://api.tampercheck.ai/api/v1/documents/<uuid>/report-link/

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

Replay 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_id if 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

GET https://api.tampercheck.ai/api/v1/usage/?since=YYYY-MM-DD&until=YYYY-MM-DD

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

GET https://api.tampercheck.ai/api/v1/wallet/usage/?since=YYYY-MM-DD&until=YYYY-MM-DD

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.

StatusMeaningAction
400Validation / invalid webhookFix file type, size, or webhook UUID
401Missing or invalid API keyCheck Bearer token
402No payment method, or suspended walletTop up at Dashboard → Billing
404Unknown job for this keyVerify UUID and API key
410Report link already usedMint a new report-link
422Unprocessable file (no charge)Re-export / re-scan the file
503AI 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