Response Format
POST /verify returns a rich forensic object — integrate from the layers below, not from fraud_score alone.
analyst_summary.verdict_tier and policy_actions, not from raw engine verdict alone. Recommendation must match tier (no presentation drift).
Top-level fields
| Field | Description |
|---|---|
analysis_id | Stable analysis identifier (e.g. ANL-…) |
verdict | Engine verdict: real, manipulated, suspicious, ai_generated, … |
fraud_score | 0–100 risk score |
confidence | 0.0–1.0 model confidence |
verdict_reason | Human-readable summary |
recommendation | Presentation-layer decision hint (synced with analyst tier) |
requires_manual_review | Boolean HITL flag |
details | Deep forensic payload, intake_hash, PDF forensics, xmp_lineage |
analyst_summary
Rule-based summary for analysts and agents:
{
"verdict_tier": "SUSPICIOUS",
"generation_rule": "xmp_lineage_review",
"presentation": {
"business_label": "Review recommended",
"summary_lines": [ "..." ]
},
"policy_actions": [
{
"action": "manual_review",
"reason": "shared_generation_fingerprint",
"priority": "high"
}
]
}
Common generation_rule values (non-exhaustive):
generation_rule | When | HITL posture |
|---|---|---|
document_localized_edit | Sterile document scan + Layer 1 region(s) ≥ threshold; global tamper may stay low | Review flagged regions — inspect critical fields |
document_scan_mixed | Sterile scan + supporting GAN/intrinsic noise, low AI intrinsic | Manual review; verify fields |
intrinsic_borderline | Elevated pixel/GAN cluster below auto-deny | HITL before enforcement |
scan_pipeline_conflict | PDF scan pipeline vs pixel conflict | Route to HITL |
metadata_decoupling | Metadata vs content mismatch | Review |
xmp_lineage_review | Repeat / cross-client XMP fingerprint | Review — not auto-deny |
ai_plain_image | High-confidence synthetic image | Per tier |
generic_suspicious | Mixed signals fallback | Review |
business_view.top_indicators, recommendation, and key_indicators are kept in sync for presentation rules such as document_localized_edit and intrinsic_borderline.
Document scan — Layer 1 (details)
When document_fraud_hint is active (preserve_exif=true on flat JPEG/PNG), responses may include localized edit candidates even if global tamper_score is below auto-deny:
{
"document_fraud_hint": true,
"tamper_score": 30,
"tamper_regions": [
{
"id": "R1",
"bbox": [320, 448, 448, 192],
"score": 81,
"rank_score": 100,
"methods": ["cfa_lam"],
"area_pct": 8.24
}
],
"local_inconsistency_maps": {
"version": "layer1-v1",
"layers_run": ["ela_mq", "dct_block", "prnu_splice", "cfa_lam"],
"candidate_count": 20,
"fused_count": 6
},
"tamper_locale": {
"image_size": { "width": 1280, "height": 816 },
"regions": [ { "bbox_px": [...], "label": "CFA composite 1" } ]
}
}
bbox—[x, y, width, height]in pixels; coordinates for analyst review, not legal proof of edit location.rank_score— internal priority (0–100, capped); field-sized multi-method regions rank above whole-frame PRNU noise.forensic_view.risk_modules— EXIF on document scans showspasswith sterile messaging whenMETADATA_STERILEapplies.
Presentation: analyst_summary.generation_rule → document_localized_edit, verdict_tier → SUSPICIOUS, policy_actions → hitl_queue (inspect flagged regions).
PDF — embedded raster fields (details)
{
"input_format": "pdf",
"embedded_image_analyzed": true,
"embedded_image_verdict": "suspicious",
"embedded_image_fraud_score": 49,
"pdf_pages_total": 3,
"pdf_pages_analyzed": [0, 2],
"embedded_image_count": 2,
"embedded_images_verified": 1
}
Composite embedded score feeds forensic_view.risk_modules (embedded_image, pixel_risk). Decomposition step binds parent_hash (PDF) + child_hashes[] (extracted rasters). See Evidence lifecycle.
forensic_view
Structured module output for technical reviewers:
risk_modules[]— per-detector status, score, summaryrisk_tags[]— flat tags e.g.TOOL_PHOTOSHOP,XMP_ID_CROSS_CLIENTrisk_findings[]— human-readable list:id,category,label,plain,severitymodule_tally— check census:checks_run,cleared,review,failed,skipped,flaggedpdf_container— PDF envelope block (see below)xmp_lineage_signals[]— structured lineage hits with confidenceevidence_lifecycle— duplicate of top-level lifecycle manifest
PDF — forensic_view.pdf_container
{
"pdf_mode": "structural",
"model": "plica_pdf/structural/v1",
"container_hit": true,
"container_label": "Tampering Detected",
"container_signals_flagged": 2,
"tool_attribution": {
"tool": "ChatGPT",
"confidence": null,
"matched_field": "creator"
},
"structure": {
"prediction": "Tampering Detected",
"signals": {
"overlay": { "flagged": false, "severity": null, "findings": [] },
"hidden": { "flagged": false, "severity": null, "findings": [] },
"font": { "flagged": false, "severity": null, "findings": [] },
"revision": {
"flagged": true,
"severity": "high",
"findings": [{
"detail": "Page content overwritten after creation.",
"changes": ["p1: '$1,250.00' -> '$5,750.00'"]
}]
},
"ocr_mismatch": { "flagged": true, "severity": "high", "findings": [] },
"metadata_edit": { "flagged": false, "severity": null, "findings": [] },
"math_logic": { "flagged": false, "severity": null, "findings": [] }
}
},
"narrative_status": "skipped",
"narrative_explanation": null
}
tool_attribution is present only when AI PDF metadata fingerprints match (ChatGPT, Grok, Claude, …). Revision changes[] lines use the format p{N}: 'before' -> 'after'.
Agent fields — details.warnings & details.pipeline_stage
Machine-readable signals for automation (PLICA namespace — not copied from third-party APIs):
warnings[]— typed items:type,severity,message, optionaldetailpipeline_stage.step— highest completed forensic stage index (1–3)pipeline_stage.completed[]/skipped[]— stage ids e.g.pdf_container_phase1,embedded_raster_pixel
business_view
Simplified label/score/confidence for non-forensic UI — aligned with analyst tier overrides.
Lineage → HITL on clean scores
When generation_rule is xmp_lineage_review, expect:
verdictmay remainreal(engine band)analyst_summary.verdict_tier→SUSPICIOUSrequires_manual_review→truepolicy_actionsincludesmanual_review— not auto-rejectdetails.xmp_lineageandforensic_view.xmp_lineage_signalscarry structured reasons
Lineage signals (review only)
{
"tag": "XMP_ID_CROSS_CLIENT",
"reason": "same_instance_id_seen_across_3_clients",
"confidence": "medium",
"distinct_clients": 3,
"doc_class": "utility_bill"
}
Lineage hit → review escalation · Not evidence of fraud · Not auto-deny
policy_actions integration
Consume typed actions for Slack, n8n, or internal agents. Do not invent parallel reject logic that contradicts verdict_tier.