# Document forensics
Source: https://docs.file.ai/verify/forensics

> Run checks on a stored file for signs of editing, AI generation, reuse and hidden content.

fileForensics

# Document forensics

Copy pageCopy page

Run checks on a stored file for signs of editing, AI generation, reuse and hidden content.

Copy pageCopy page

Reference for fileForensics runs: endpoints, request rules, statuses, every detector and the errors you can get. For what fileForensics is and how it’s metered, see the [overview](/forensics/overview). For a first run end to end, see the [quickstart](/quickstart/forensics).

## 

[​

](#how-it-works)

How it works

A run checks a file that is already stored in your workspace, identified by its `file_id`, so there is no upload in the request. Each result appears under `forensics.<key>` once that detector has reported.

1

Start a run

`POST /v1/forensics` returns `202` with a `run_id`, `status: "queued"` and a `poll_url`. Runs started at upload with `enabledProducts: ["FILE_FORENSICS"]` run all 19 detectors; read them with `GET /v1/forensics/files/{file_id}`.

2

Poll

`GET /v1/forensics/runs/{run_id}` until `status` is `complete` or `error`. Web presence can take up to about 180 seconds.

3

Retry if stuck

A run still `queued` or `running` after about 6 minutes is stuck. `POST /v1/forensics/runs/{run_id}/retry` re-runs the same file and `spec_filter` under a **new** `run_id`, which is the one to poll. The original run then reports `error`.

4

Clean up

`DELETE /v1/forensics/runs/{run_id}` once you have the result. The file itself is not affected.

Forensics runs are not jobs: they do not appear on `GET /v1/jobs/{job_id}` and have no callback. See [Async jobs](/api/async-jobs#forensics-runs) for how they compare with other async work.

## 

[​

](#endpoints)

Endpoints

Endpoint

What it does

`POST /v1/forensics`

Start a run. JSON body: `file_id`, `spec_filter`.

`GET /v1/forensics/runs/{run_id}`

Get a run’s status and results.

`GET /v1/forensics/files/{file_id}`

Get the newest run for a file, whether it was started at upload or with `POST /v1/forensics`. `404` if the file has no run.

`POST /v1/forensics/runs/{run_id}/retry`

Re-run with the same file and `spec_filter`. No body. Returns a new `run_id`.

`DELETE /v1/forensics/runs/{run_id}`

Delete the run. Afterwards, GET, retry and DELETE on it return `404`.

## 

[​

](#request)

Request

Field

Rules

`file_id`

Required. The public `fileId` of a stored file, up to 128 characters. Unknown files are a `404`.

`spec_filter`

Required. A non-empty array of unique detector keys from [Detectors](#detectors). An unknown or repeated key is a `422`.

`spec_filter` is required so that a detector added later cannot silently change what an existing integration runs.

## 

[​

](#response)

Response

Field

Meaning

`run_id`, `file_id`, `spec_filter`, `created_at`

The run and what it checks.

`status`

Run status. See [Run status](#run-status).

`poll_url`

The `GET /v1/forensics/runs/{run_id}` URL for this run. Returned when the run starts.

`forensics.<key>`

One result per detector in `spec_filter`, keyed by detector. Results appear as each detector reports.

`forensics.<key>.status`

See [Detector status](#detector-status).

`forensics.<key>.value`

A one-line summary, such as `"AI-generated: false"`. Other fields are detector-specific.

`forensics.web_presence.web_presence`

The combined web-presence boolean. Absent when the run reached no conclusion.

### 

[​

](#run-status)

Run status

`status`

Meaning

`queued`

Waiting to start.

`running`

In progress. Results appear as each detector reports.

`complete`

Final. Read the results under `forensics`.

`error`

Final. The run failed, or was replaced by a retry.

### 

[​

](#detector-status)

Detector status

Every detector result has a `status`, and usually a one-line `value`. Route on each detector’s status, not the run’s: a `complete` run can still contain an `issue`.

`status`

Meaning

`none`

Checked; nothing found.

`issue`

Checked; something found.

`skip`

Not applicable to this file type.

`error`

The detector failed.

For `web_presence`, the combined `web_presence` boolean is absent when the run reached no conclusion (still running, `skip` or `error`). Do not read a missing value as “not found on the web”.

## 

[​

](#detectors)

Detectors

Key

What it checks

`web_presence`

Whether the image appears on the web, from file metadata (`layer1`) and a reverse-image search (`layer2`).

`ai_gen_detection`

AI-generated image

`ai_text_detection`

AI-generated text

`ai_pdf_detection`

AI-generated PDF

`ai_office_detection`

AI-generated Office document

`copy_move`

Copied-and-moved (cloned) regions

`exact_duplicate`

Exact duplicate of a previously seen file

`provenance_credentials`

Content credentials (C2PA)

`generation_toolchain`

Creation tools inferred from metadata

`producer_divergence`

Different producers across pages

`encryption_permissions`

Encryption and permissions

`active_content`

Active content, such as scripts and launch actions

`digital_signature`

Digital signature

`attachments`

Embedded attachments

`revision_history`

Revision history

`magic_byte`

File signature vs declared type

`polyglot`

Polyglot file (valid as more than one format)

`trailing_data`

Data after the end of the file

`entropy`

Entropy anomalies

The MCP tool `run_file_forensics` offers 17 of these: all except `ai_pdf_detection` and `ai_office_detection`. See [MCP tools](/mcp/tools#forensics).

## 

[​

](#errors)

Errors

Status

When

`404`

Unknown file or run, a deleted run, or a run the forensics service no longer holds.

`422`

Invalid body, a file with no stored content to analyze, or (on retry) a file that is no longer available.

`502`

The forensics service returned an error or was unreachable.

`503`

fileForensics is not configured.

See [Errors](/api/errors) for the response format.

## 

[​

](#related)

Related

## Forensics quickstart

Run your first check end to end.

## Document integrity checks

Choose detectors per document and route on the result.

## Uploads

Store a file and get its `fileId`.

## MCP tools

Run fileForensics from an AI assistant.

[Previous](/quickstart/forensics)[

KYC example

Screen an identity document or statement for editing and AI generation during onboarding, and route it on the result.

Next

](/examples/document-integrity)

⌘I

## On this page

*   [How it works](#how-it-works)
*   [Endpoints](#endpoints)
*   [Request](#request)
*   [Response](#response)
    *   [Run status](#run-status)
    *   [Detector status](#detector-status)
*   [Detectors](#detectors)
*   [Errors](#errors)
*   [Related](#related)
