The job

A policyholder submits a motor claim with nine files. Before you pay, you want to know whether any of them was edited, generated by AI, or lifted from the web, and you want the claim form and repair estimate extracted at the same time. If anything looks wrong, the claim goes to an investigator with a list of what was found and where.

Sample input

Steps

The examples use your API key from the environment:
See Regions for regional hosts.
1

Choose products for each file

Pick enabledProducts per file on POST /v1/files/upload. Both choices run fileForensics with all 19 checks, started once the file is stored:enabledProducts works only on the single upload route and in workspaces enabled for these products; otherwise the request returns 422. See Choose products.
2

Upload every file in the pack

Request an upload URL for each file and PUT the bytes to it within 300 seconds. Then poll GET /v1/uploads/{uploadId} until the file’s document is processed or action_required, and keep its fileId.
3

Wait for each file's run

Read each file’s run with GET /v1/forensics/files/{file_id}. It returns 404 until the run exists, then the run itself; poll until its status is complete or error. All the checks in a run execute at the same time, so a run takes about as long as its slowest check: web_presence can take up to about 180 seconds.
A run still queued or running after about 6 minutes is stuck; see Retry if stuck.
4

Combine the results into one decision

Fan out over the pack, then decide. Any issue on any file sends the claim to an investigator, with the file and check named. A failed run or check holds the claim for a retry, because “no finding” from a check that didn’t run is not evidence.
For the PDFs, read the extracted values with GET /v1/files/{fileId}/values as in the financial report example.

Which checks matter for which file

Every file gets all 19 checks. A check that has nothing to look at in a file usually reports skip; a few report none with a note in value instead (for example, producer_divergence on a photo). Both mean “nothing found here”, so treat them the same. See Detectors for what each key returns.

Result

Illustrative: shape from the API reference. Values vary by check.
Here is what the pack might return, with every check not listed reporting none or skip: Combined decision: investigate. Three files carry an issue, so the claim goes to an investigator with the list above. The run for photo_4.jpg, shortened to four of its 19 checks:
GET /v1/forensics/files/{file_id}
An upload-time run lists all 19 keys in spec_filter, with one result for each under forensics.

How the findings combine

The API has no overall fraud score. Each check on each file reports none, issue, skip or error, and your code decides what that means for the claim:
  • Per file: route on each check’s status, not the run’s. A complete run can still contain an issue.
  • Per pack: one issue anywhere is enough to stop straight-through payment here. You could instead weight checks differently, for example send a single web_presence hit to a quick manual look and a copy_move hit to a full investigation.
  • Missing results: a run in error, a check in error, or a run that never appears is not a clean result. Hold the claim and retry rather than pay.
  • web_presence: a missing web_presence boolean means the check reached no conclusion, not “not found on the web”.

What it shows

  • One upload per file both stores it and starts all 19 checks; photos skip extraction with storageOnly: true.
  • GET /v1/forensics/files/{file_id} finds each file’s run without tracking a run_id.
  • Checks that don’t fit a file type report skip (or none with a note), so you can run everything on everything and still read the results the same way.
  • The pack-level decision is yours: the API reports per file and per check, and your code combines them.

Next steps

Detectors and results

All 19 checks, statuses and errors.

Document integrity checks

Pick checks per file with POST /v1/forensics and route on the result.

fileForensics

Two ways to run it, and how usage is counted.

Uploads

enabledProducts and storageOnly rules.