— Developers
One POST away from a forensic verdict
Bearer-key auth, JSON in and out, and a report schema designed to be filed as an exhibit — not parsed out of a PDF. First analysis free with an account.
— API
The analysis API
All endpoints live under a versioned base URL and authenticate with a bearer key from your dashboard. Keys are scoped per project and revocable instantly.
https://api.vestigeforensics.com/v1| Method | Path | |
|---|---|---|
| POST | /v1/analyze | Analyze one image; returns a forensic report. |
| POST | /v1/analyze/batch | Up to 50 images per request (Starter and up). |
| GET | /v1/reports/{report_id} | Retrieve a stored report by id. |
| DELETE | /v1/reports/{report_id} | Acknowledges deletion. Nothing is stored server-side — the report exists only where you saved it. |
| GET | /v1/usage | Image balance, plan, and rolling usage. |
POST /v1/analyze
image · file · required
JPEG, PNG, or WebP up to 15 MB, multipart over TLS. Scored in memory — the image is never stored.
fpr_cap · 0.05 | 0.01 · default 0.05
False-positive budget the verdict threshold is calibrated to. Use 0.01 for evidentiary work.
condition_hint · string · optional
Override the estimated degradation condition (e.g. social_chain) when you know the image's history.
webhook_url · url · optional
POSTed the finished report instead of long-polling.
DeletionDELETE /v1/reports/{id} acknowledges deletion for workflow symmetry — but images are scored in memory and never stored, so there is nothing server-side for it to remove. See the privacy commitments.
curl -X POST https://api.vestigeforensics.com/v1/analyze \
-H "Authorization: Bearer dl_live_9x2…" \
-F "image=@exhibit_2216-042.jpg" \
-F "fpr_cap=0.01"— Pricing
Pay per image, or put it on a plan
Every account starts with one free diagnostic. After that: credits for occasional checks, monthly plans for caseloads and pipelines. Web uploads and API calls share one balance.
Credits
$910 images
Pay per image. No subscription, credits never expire.
- Full forensic report per image
- Standard (≤5% FPR) and strict (≤1% FPR) verdicts
- JSON + web report, delete anytime
- Email support
Starter
Most popular$49per month
For steady caseloads. 200 images included, then $0.25 per image.
- Everything in Credits
- API access with bearer keys
- Batch upload (up to 50 per request)
- Webhook callbacks
- 90-day report retention controls
Pro
$249per month
For teams and pipelines. 2,000 images included, then $0.12 per image.
- Everything in Starter
- Priority analysis queue
- Team seats and shared case folders
- Usage analytics endpoint
- 99.5% uptime SLA
Forensic
Customannual
For labs and legal teams with evidentiary requirements.
- Everything in Pro
- Methodology pack + calibration disclosures
- Expert-report support & witness prep material
- Pinned pipeline versions per case
- EU-region processing, DPA, on-prem option
- · Every account starts with one free image diagnostic — no card required.
- · API and web uploads draw from the same image balance.
- · Deleted images are never billed twice: re-analyzing the same SHA-256 within 30 days is free.
— Report format
The forensic report, field by field
One JSON document, versioned and hashed. The response example above is rendered from the same object as this schema — the docs cannot drift from the type.
Root
report_idstring“VF-” + first 8 hex chars of the image hash. Stable across re-analysis of identical bytes.created_atISO 8601Report creation time, UTC.report_sha256hex(64)SHA-256 of the canonical report JSON (this field excluded). Tamper-evidence for the document itself.service.pipeline_versionstringPinned pipeline release that produced this report. Cite it; reproduce with it.service.calibration_refstringNamed benchmark run the thresholds and power figures come from (currently full_v4).image
image.sha256hex(64)SHA-256 of the exact bytes received — the chain-of-custody anchor. Any edit or re-export changes it.image.filename / mime_type / byte_sizestring · string · intAs received. Dimensions are null when the container can't be parsed.primary & supporting[]
primary.idenumcf_finetuned — the calibrated fine-tuned detector whose score the verdict is based on. Pinned by checkpoint hash.supporting[].idenumcommunity_forensics (stock) · sdxl_detector. Independent corroboration; they never drive the verdict.primary.venue / supporting[].venuestringPublication venue or provenance (CVPR 2025 lineage, community). Cite-ready.primary.score / supporting[].scorefloat [0,1]1.0 = confident AI-generated, 0.0 = confident real photograph. A low supporting score does not weaken the verdict — stock models lag on 2024+ generators.decision
decision.fpr_cap0.05 | 0.01The false-positive budget you chose.decision.thresholdfloatOperating threshold calibrated for this cap UNDER THE ESTIMATED CONDITION so every real source in the benchmark stays within the cap — never the naive 0.5, and different per condition.decision.verdictenumai_flagged_strict (≥ strict threshold) · ai_flagged (≥ standard threshold at the 5% cap) · not_flagged.decision.tpr_at_capfloatDetection rate measured at exactly this threshold on the calibration run — what a flag's absence is worth.robustness & limits
robustness.estimated_conditionenumDegradation condition estimated from the encoding fingerprint: clean · jpeg_q70 · jpeg_q50 · resize_50 · whatsapp · screenshot · social_chain.robustness.honesty_gapfloatHeadline AUC minus tpr_at_cap: the share of benchmark performance that does not survive your evidentiary standard. Printed, not hidden.robustness.per_degradation[]arrayDetection rate at ≤5% FPR for every condition, so you can see how power moves if the image history differs from the estimate.limits[]string[]Plain-language caveats — always present. These are the questions opposing counsel will ask; we answer them first.sampleobject?Present only on simulated demo output: { simulated: true, note }. Real analyses never carry it.