# API reference

> Every Fileverity API endpoint with parameters, request and response schemas, error codes and examples, generated from the OpenAPI 3.1 specification.

Source: https://fileverity.com/en/docs/api-reference

This reference is generated from the API's OpenAPI 3.1 document, available at [https://api.fileverity.com/v1/openapi.json](https://api.fileverity.com/v1/openapi.json), so it always matches the API. For concepts and guides, start with the [Overview](https://fileverity.com/en/docs.md).

## Conventions

Base URL: `https://api.fileverity.com/v1`. Authenticate every request with `Authorization: Bearer <key>`. Errors share one format, described in [Errors](https://fileverity.com/en/docs/errors.md). Every response carries an `x-request-id` header, and authenticated responses carry the rate-limit headers described in [Rate limits and headers](https://fileverity.com/en/docs/rate-limits.md). Nested objects open in collapsible sections under the table.

## Text detections

### Detect AI-written text

`POST` `https://api.fileverity.com/v1/text/detections`

Classifies plain text as AI-written, partly AI-written or human-written and returns the AI-written passages. The text is evaluated and discarded; it is not stored. Billing counts Unicode code points in units of 1,000 characters, rounded up per request. Requests rejected before evaluation are not charged. Test keys return a fixed human result without charge.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | No | Unique key of up to 255 characters. Repeating the request with the same key and body within 24 hours returns the first response with the header idempotent-replayed: true; the same key with a different body returns 409. |

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | No | Model ID or snapshot ID. Default `"fvdoc-3-text"`. |
| `text` | string | Yes | Plain text, at least 100 words and at most 100,000 characters. |
| `language` | one of `"en"`, `"fr"`, `"de"`, `"es"`, `"zh"`, `null` | No | ISO 639-1 code. Detected automatically when omitted. Default `null`. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The detection result. | `TextDetection` |
| 400 | Invalid request. Error codes: invalid_json, missing_parameter, text_too_short, unsupported_language, invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 402 | The balance or the key's monthly spend limit cannot cover the request. Error codes: insufficient_balance, spend_limit_reached. | `Error` |
| 404 | Resource not found. Error codes: model_not_found. | `Error` |
| 409 | Conflict with the current state. Error codes: idempotency_mismatch, idempotency_in_progress. | `Error` |
| 413 | A size limit was exceeded. Error codes: text_too_long. | `Error` |
| 415 | Unsupported media type or file format. Error codes: unsupported_media_type. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |
| 502 | Analysis could not be completed; not charged. Error codes: analysis_failed. | `Error` |
| 503 | Temporarily unavailable or busy; not charged. Retry after the number of seconds in the retry-after header. Error codes: service_unavailable. | `Error` |

#### Response 200: TextDetection

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"text.detection"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `model` | string | Yes | Snapshot that produced the result. |
| `livemode` | boolean | Yes | False for test keys. |
| `language` | one of `"en"`, `"fr"`, `"de"`, `"es"`, `"zh"` | Yes |  |
| `verdict` | one of `"ai"`, `"mixed"`, `"human"` | Yes | ai: the text reads as AI-written throughout; mixed: AI-written passages within human text; human: no AI-written passage found. |
| `score` | number | Yes | Model score for the most AI-like passage. Minimum 0. Maximum 1. |
| `ai_fraction` | number | Yes | Share of the evaluated text inside AI-written segments. Minimum 0. Maximum 1. |
| `segments` | array of object | Yes | AI-written passages, as offsets into the submitted text in Unicode code points. Boundaries are approximate and can include adjacent sentences. |
| `usage` | object | Yes |  |

**segments: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `start` | integer | Yes |  |
| `end` | integer | Yes | Exclusive. |
| `score` | number | Yes | Minimum 0. Maximum 1. |

**usage: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `characters` | integer | Yes | Unicode code points evaluated. |
| `free_characters` | integer | Yes | Characters covered by your free-start allowance, not billed. |
| `billed_units` | integer | Yes | Units of 1,000 characters actually charged, after free characters; billed_units × unit price is the cost. |

#### Error codes

| Code | Status |
| --- | --- |
| `invalid_json` | 400 |
| `missing_parameter` | 400 |
| `unsupported_media_type` | 415 |
| `text_too_short` | 400 |
| `text_too_long` | 413 |
| `unsupported_language` | 400 |
| `model_not_found` | 404 |
| `insufficient_balance` | 402 |
| `spend_limit_reached` | 402 |
| `service_unavailable` | 503 |
| `analysis_failed` | 502 |
| `invalid_parameter` | 400 |
| `idempotency_mismatch` | 409 |
| `idempotency_in_progress` | 409 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/text/detections \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -Rs '{text: .}' essay.txt)"
```

**Response**

```json
{
  "id": "tdet_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "text.detection",
  "created": 1793664000,
  "model": "fvdoc-3-text-2026-11-03",
  "livemode": true,
  "language": "en",
  "verdict": "mixed",
  "score": 0.97,
  "ai_fraction": 0.41,
  "segments": [
    {
      "start": 212,
      "end": 433,
      "score": 0.97
    },
    {
      "start": 579,
      "end": 790,
      "score": 0.93
    }
  ],
  "usage": {
    "characters": 1412,
    "free_characters": 0,
    "billed_units": 2
  }
}
```

## Files

### Upload a file

`POST` `https://api.fileverity.com/v1/files`

Uploads a file for analysis. Send files up to 4 MB as multipart/form-data in the field file; the response has status uploaded. Files larger than 4 MB must be uploaded with a pre-signed URL. Send JSON with filename, content_type and bytes (documents up to 50 MB); the response has status pending and an upload object with a pre-signed URL: send the file bytes to it with PUT and the given headers before it expires. A file is deleted when an analysis starts and at the latest after 24 hours. A workspace can hold up to 50 unexpired files and 200 MB per mode at once.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | No | Unique key of up to 255 characters. Repeating the request with the same key and body within 24 hours returns the first response with the header idempotent-replayed: true; the same key with a different body returns 409. |

#### Request body: multipart/form-data, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `file` | string | Yes | Format binary. |

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filename` | string | No |  |
| `content_type` | string | Yes | MIME type of the file, for example image/jpeg or application/pdf. |
| `bytes` | integer | Yes | Exact size in bytes. Minimum 1. Maximum 52,428,800. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 201 | The file. | `File` |
| 400 | Invalid request. Error codes: invalid_json, missing_parameter, invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 409 | Conflict with the current state. Error codes: idempotency_mismatch, idempotency_in_progress. | `Error` |
| 413 | A size limit was exceeded. Error codes: file_too_large. | `Error` |
| 415 | Unsupported media type or file format. Error codes: unsupported_media_type, unsupported_file. | `Error` |
| 422 | The file cannot be processed. Error codes: invalid_file. | `Error` |
| 429 | Too many requests. Error codes: pending_files_limit, rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 201: File

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"file"` | Yes |  |
| `filename` | string or null | Yes |  |
| `bytes` | integer or null | Yes |  |
| `content_type` | string | Yes |  |
| `status` | one of `"pending"`, `"uploaded"` | Yes | pending until the bytes sent to the pre-signed URL have arrived. |
| `livemode` | boolean | Yes | Files are only visible to keys of the same mode. |
| `created` | integer | Yes | Unix timestamp. |
| `expires_at` | integer | Yes | Unix timestamp after which the file is deleted. |
| `upload` | object | No | Present on the response to a JSON upload request. |

**upload: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | Yes | Test keys get a placeholder URL (test: true); nothing is uploaded or stored. |
| `method` | `"PUT"` | Yes |  |
| `headers` | object of string | Yes |  |
| `expires_at` | integer | Yes | Unix timestamp. |
| `test` | `true` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `invalid_json` | 400 |
| `missing_parameter` | 400 |
| `unsupported_media_type` | 415 |
| `unsupported_file` | 415 |
| `invalid_file` | 422 |
| `file_too_large` | 413 |
| `pending_files_limit` | 429 |
| `invalid_parameter` | 400 |
| `idempotency_mismatch` | 409 |
| `idempotency_in_progress` | 409 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/files \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -F file=@claim-photo.jpg
```

**Response**

```json
{
  "id": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "file",
  "filename": "claim-photo.jpg",
  "bytes": 2481920,
  "content_type": "image/jpeg",
  "status": "uploaded",
  "livemode": true,
  "created": 1793700000,
  "expires_at": 1793786400
}
```

### Retrieve a file

`GET` `https://api.fileverity.com/v1/files/{id}`

Returns the file and whether its bytes have arrived.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | File ID. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The file. | `File` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: not_found. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: File

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"file"` | Yes |  |
| `filename` | string or null | Yes |  |
| `bytes` | integer or null | Yes |  |
| `content_type` | string | Yes |  |
| `status` | one of `"pending"`, `"uploaded"` | Yes | pending until the bytes sent to the pre-signed URL have arrived. |
| `livemode` | boolean | Yes | Files are only visible to keys of the same mode. |
| `created` | integer | Yes | Unix timestamp. |
| `expires_at` | integer | Yes | Unix timestamp after which the file is deleted. |
| `upload` | object | No | Present on the response to a JSON upload request. |

**upload: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | Yes | Test keys get a placeholder URL (test: true); nothing is uploaded or stored. |
| `method` | `"PUT"` | Yes |  |
| `headers` | object of string | Yes |  |
| `expires_at` | integer | Yes | Unix timestamp. |
| `test` | `true` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `not_found` | 404 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/files/file_8Hk2pQ4vN9sL1xR7cW3mY6zB \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "id": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "file",
  "filename": "claim-photo.jpg",
  "bytes": 2481920,
  "content_type": "image/jpeg",
  "status": "uploaded",
  "livemode": true,
  "created": 1793700000,
  "expires_at": 1793786400
}
```

### Delete a file

`DELETE` `https://api.fileverity.com/v1/files/{id}`

Deletes an uploaded file and its stored bytes.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | File ID. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The file was deleted. | `FileDeleted` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: not_found. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: FileDeleted

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"file"` | Yes |  |
| `deleted` | `true` | Yes |  |

#### Error codes

| Code | Status |
| --- | --- |
| `not_found` | 404 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl -X DELETE https://api.fileverity.com/v1/files/file_8Hk2pQ4vN9sL1xR7cW3mY6zB \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "id": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "file",
  "deleted": true
}
```

## Analyses

### Create an analysis

`POST` `https://api.fileverity.com/v1/analyses`

Analyzes an uploaded file with fvimg-2 (images) or fvdoc-3 (documents). An analysis is one image or document check. The response is 202 with status processing; the result arrives by webhook or by polling GET /analyses/{id}. Send Prefer: wait=N (up to 60 seconds) to hold the request until the result is ready; a finished analysis returns 200. The price is reserved when the analysis is created and released if it fails or is canceled. Results are kept for 7 days. When capacity is busy the API returns 503 service_unavailable with a retry-after header and charges nothing: retry with the same Idempotency-Key, and run image analyses one after another for the best throughput. Test keys return a sample result and are never charged; the sample report contains only a few fields.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | No | Unique key of up to 255 characters. Repeating the request with the same key and body within 24 hours returns the first response with the header idempotent-replayed: true; the same key with a different body returns 409. |
| `Prefer` | header | string | No | wait=N holds the request for up to N seconds (maximum 60) until the analysis finishes. |

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | one of `"fvimg-2"`, `"fvimg-2-2026-10-30"`, `"fvdoc-3"`, `"fvdoc-3-2026-11-03"` | Yes | Model ID or snapshot ID. fvimg-2 analyzes images, fvdoc-3 documents. |
| `file` | string | Yes | ID of an uploaded file. |
| `metadata` | object of string | No | Up to 16 string pairs (keys up to 40 characters, values up to 500) returned on the analysis and in webhooks. |
| `options` | object | No |  |

**options: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `password` | string | No | Password of an encrypted document. Maximum length 256. |
| `locale` | one of `"en"`, `"fr"`, `"de"`, `"es"`, `"zh"`, `"vi"`, `"ar"` | No | Language of document findings. Default `"en"`. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The finished analysis. | `Analysis` |
| 202 | The analysis is processing. | `Analysis` |
| 400 | Invalid request. Error codes: invalid_json, missing_parameter, file_not_found, invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 402 | The balance or the key's monthly spend limit cannot cover the request. Error codes: insufficient_balance, spend_limit_reached. | `Error` |
| 404 | Resource not found. Error codes: model_not_found. | `Error` |
| 409 | Conflict with the current state. Error codes: idempotency_mismatch, idempotency_in_progress. | `Error` |
| 413 | A size limit was exceeded. Error codes: file_too_large, too_many_pixels, too_many_pages, document_too_long. | `Error` |
| 415 | Unsupported media type or file format. Error codes: unsupported_media_type, unsupported_file. | `Error` |
| 422 | The file cannot be processed. Error codes: invalid_file, password_required, wrong_password, not_examinable. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |
| 502 | Analysis could not be completed; not charged. Error codes: analysis_failed. | `Error` |
| 503 | Temporarily unavailable or busy; not charged. Retry after the number of seconds in the retry-after header. Error codes: service_unavailable. | `Error` |

#### Response 200: Analysis

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"analysis"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `model` | string | Yes | Snapshot that produced the result. |
| `livemode` | boolean | Yes |  |
| `status` | one of `"processing"`, `"succeeded"`, `"failed"`, `"canceled"` | Yes |  |
| `file` | object | Yes |  |
| `report_id` | string or null | Yes | Verifiable report ID, FV-XXXX-XXXX-XXXX. |
| `report_url` | string or null | Yes | Public verification page of the report. |
| `summary` | `ImageSummary` or `DocumentSummary` or null | Yes | The short, stable verdict: an ImageSummary for images, a DocumentSummary for documents, null until the analysis succeeds. |
| `result` | object or null | Yes | Present once status is succeeded and until the result expires. |
| `error` | object or null | Yes |  |
| `progress` | object or null | Yes |  |
| `usage` | object | Yes |  |
| `metadata` | object or null | Yes |  |
| `completed_at` | integer or null | Yes |  |
| `expires_at` | integer or null | Yes | Unix timestamp after which the result is deleted. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `bytes` | integer or null | No |  |
| `format` | string or null | No |  |

**summary (ImageSummary): fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `level` | one of `"L0"`, `"L1"`, `"L2"`, `"L3"`, `"L4"`, `"L5"` | Yes | Risk level, L0 to L5. |
| `assessment` | one of `"authentic_untouched"`, `"authentic_locally_edited"`, `"ai_generated"`, `"undetermined"` | Yes |  |
| `action` | one of `"accept"`, `"review"`, `"reject"`, `"resubmit"` | Yes |  |
| `ai` | one of `"labelled"`, `"very_likely"`, `"suspected"`, `"undecided"`, `"low"`, `"very_low"`, `"not_evaluated"` | Yes | The finding on AI generation. |
| `edit` | one of `"detected"`, `"suspected"`, `"suspected_record"`, `"review"`, `"generative"`, `"minor"`, `"none"`, `"not_applicable"`, `"not_evaluated"` | Yes | The finding on local editing. |

**summary (DocumentSummary): fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | `"docpro"` | Yes |  |
| `level` | one of `"L0"`, `"L1"`, `"L2"`, `"L3"`, `"L4"`, `"L5"` | Yes | Risk level, L0 to L5. |
| `action` | one of `"accept"`, `"note"`, `"review"`, `"reject"`, `"resubmit"` | Yes | note: check the AI content marked in the report against your policy. |
| `reason` | string or null | Yes | The finding or condition behind the level, for example clean or incomplete, or a finding ID. |
| `findings` | array of string | Yes | IDs of the findings that matter. |
| `pages` | integer | Yes | Pages in the document. |
| `images` | integer | Yes | Embedded photos examined. |
| `text` | one of `"ai_generated"`, `"mixed"`, `"human"`, `"inconclusive"`, `null` | Yes | The verdict on the document's text, or null when text was not evaluated. |
| `strong` | `true` | No | Present when a listed finding is strong. |

**result: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `report` | `ImageReport` or `DocumentReport` | No | The full report. report.schema is fileverity.report/1 for images and fileverity.docpro/1 for documents. |
| `stamped_at` | integer or null | No | Unix timestamp of the RFC 3161 timestamp issued for the report, or null. |

**report (ImageReport): fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schema` | `"fileverity.report/1"` | Yes |  |
| `id` | string | Yes | Report ID, FV-XXXX-XXXX-XXXX. |
| `sample` | `true` | No | Present on the fixed sample reports that test keys return. |
| `issuedAt` | string | No | When the report was issued, ISO 8601 in UTC. Format date-time. |
| `issuer` | object | No | Who issued the report. |
| `file` | object | No | The checked image. |
| `pro` | object | No | The verdict. The same values as summary, with reason. |
| `score` | integer or null | No | Authenticity score from 0 to 100 in steps of 5: how strongly the evidence supports the image as an authentic, unedited capture. null when not evaluated. |
| `confidence` | one of `"high"`, `"medium"`, `"low"` | No | How much this file allows the analysis to establish. Low confidence usually reflects the file itself, such as low resolution or heavy compression. |
| `questions` | object | No | The three questions the report answers. |
| `generator` | object or null | No | The AI generator named for the image, or null. |
| `regions` | array of object | No | Flagged regions, in pixels of the displayed image. |
| `provenance` | object | No | What the file's own records say about its origin. |
| `digest` | string | No | Fingerprint of the report content, used by the verification page. |

**issuer: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `operator` | string | No |  |
| `verify` | string | No | Public verification page of the report. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `sha256` | string | No | SHA-256 of the checked file, in hex. |
| `bytes` | integer | No |  |
| `width` | integer | No | Width in pixels as displayed. |
| `height` | integer | No | Height in pixels as displayed. |
| `format` | string | No |  |

**pro: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `level` | one of `"L0"`, `"L1"`, `"L2"`, `"L3"`, `"L4"`, `"L5"` | No | Risk level, L0 to L5. |
| `action` | one of `"accept"`, `"review"`, `"reject"`, `"resubmit"` | No |  |
| `assessment` | one of `"authentic_untouched"`, `"authentic_locally_edited"`, `"ai_generated"`, `"undetermined"` | No |  |
| `reason` | string or null | No |  |

**questions: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ai` | object | No |  |
| `edit` | object | No |  |
| `source` | object | No |  |

**ai: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | one of `"labelled"`, `"very_likely"`, `"suspected"`, `"undecided"`, `"low"`, `"very_low"`, `"not_evaluated"` | No |  |
| `basis` | one of `"verified"`, `"detected"`, `"declared"`, `null` | No | What the answer rests on. |
| `strength` | one of `"strong"`, `"moderate"`, `"limited"`, `null` | No | How strongly the evidence supports the answer. |
| `likelihood` | integer or null | No | Likelihood of AI generation from 0 to 100 in steps of 5, or null. |

**edit: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | one of `"detected"`, `"suspected"`, `"suspected_record"`, `"review"`, `"generative"`, `"minor"`, `"none"`, `"not_applicable"`, `"not_evaluated"` | No |  |
| `basis` | one of `"verified"`, `"detected"`, `"declared"`, `null` | No | What the answer rests on. |
| `strength` | one of `"strong"`, `"moderate"`, `"limited"`, `null` | No | How strongly the evidence supports the answer. |
| `regions` | integer | No | Number of flagged regions. |

**source: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | No |  |
| `basis` | one of `"verified"`, `"detected"`, `"declared"`, `null` | No | What the answer rests on. |
| `strength` | one of `"strong"`, `"moderate"`, `"limited"`, `null` | No | How strongly the evidence supports the answer. |
| `signer` | string or null | No |  |
| `aiClaim` | boolean | No | Whether the file's own records claim AI generation. |

**generator: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `basis` | string | No | How the generator was identified. |

**regions: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | No |  |
| `x` | integer | No |  |
| `y` | integer | No |  |
| `w` | integer | No |  |
| `h` | integer | No |  |
| `strength` | one of `"high"`, `"medium"` | No |  |

**provenance: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `credentials` | one of `"valid"`, `"unverified"`, `"issues"`, `"invalid"`, `"removed"`, `"none"` | No | State of the Content Credentials. |
| `signer` | string or null | No |  |
| `software` | array of string | No | Software named in the file's records. |
| `camera` | string or null | No |  |
| `captured` | string or null | No | Capture time recorded in the file, if any. |

**report (DocumentReport): fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schema` | `"fileverity.docpro/1"` | Yes |  |
| `id` | string | Yes | Report ID, FV-XXXX-XXXX-XXXX. |
| `sample` | `true` | No | Present on the fixed sample reports that test keys return. |
| `issuedAt` | string | No | When the report was issued, ISO 8601 in UTC. Format date-time. |
| `receivedAt` | string | No | When the file was received, ISO 8601 in UTC. Format date-time. |
| `issuer` | object | No | Who issued the report. |
| `file` | object | No | The checked document. |
| `level` | one of `"L0"`, `"L1"`, `"L2"`, `"L3"`, `"L4"`, `"L5"` | No | Risk level, L0 to L5. |
| `action` | one of `"accept"`, `"note"`, `"review"`, `"reject"`, `"resubmit"` | No |  |
| `reason` | string or null | No | The finding or condition behind the level. |
| `findings` | array of object | No | The findings behind the level, each with the pages and embedded photos it refers to. |
| `text` | object | No | The result for the document's text. |
| `images` | array of object | No | The embedded photos and graphics, numbered in document order. |
| `structure` | object or null | No | The edit history of the file, or null when it was not examined. |
| `provenance` | object | No | What the file's own records say about its origin. |
| `digest` | string | No | Fingerprint of the report content, used by the verification page. |

**issuer: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No |  |
| `operator` | string | No |  |
| `verify` | string | No | Public verification page of the report. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `sha256` | string | No | SHA-256 of the checked file, in hex. |
| `bytes` | integer | No |  |
| `format` | string | No |  |
| `pages` | integer | No |  |
| `textLayer` | one of `"present"`, `"partial"`, `"absent"` | No | Whether the document carries a text layer. |

**findings: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | No |  |
| `basis` | one of `"verified"`, `"detected"`, `"declared"` | No |  |
| `strength` | one of `"strong"`, `"moderate"`, `"limited"` | No |  |
| `material` | boolean | No | Whether the finding counts toward the level. |
| `pages` | array of integer | No |  |
| `images` | array of integer | No |  |

**text: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | one of `"evaluated"`, `"insufficient_text"`, `"unsupported_language"`, `"no_text"` | No |  |
| `verdict` | one of `"ai_generated"`, `"mixed"`, `"human"`, `"inconclusive"` | No | Present when status is evaluated. |
| `words` | integer | No |  |
| `languages` | array of string | No |  |
| `passages` | integer | No | Number of marked passages. |

**images: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `n` | integer | No |  |
| `pages` | array of integer | No |  |
| `kind` | one of `"photo"`, `"graphic"` | No |  |
| `width` | integer | No |  |
| `height` | integer | No |  |
| `level` | one of `"L0"`, `"L1"`, `"L2"`, `"L3"`, `"L4"`, `"L5"`, `null` | No |  |
| `assessment` | one of `"authentic_untouched"`, `"authentic_locally_edited"`, `"ai_generated"`, `"undetermined"`, `null` | No |  |
| `ai` | one of `"labelled"`, `"very_likely"`, `"suspected"`, `"undecided"`, `"low"`, `"very_low"`, `"not_evaluated"`, `null` | No |  |
| `edit` | one of `"detected"`, `"suspected"`, `"suspected_record"`, `"review"`, `"generative"`, `"minor"`, `"none"`, `"not_applicable"`, `"not_evaluated"`, `null` | No |  |

**structure: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revisions` | integer or null | No |  |
| `changedPages` | array of integer | No |  |
| `addedPages` | integer | No |  |
| `signatures` | integer | No |  |

**provenance: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `credentials` | string | No | State of the Content Credentials. |
| `signer` | string or null | No |  |
| `aiClaim` | boolean | No | Whether the file's own records claim AI generation. |
| `software` | array of string | No |  |
| `created` | string or null | No |  |
| `modified` | string or null | No |  |
| `revisions` | integer or null | No |  |
| `signed` | boolean or null | No |  |

**error: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | one of `"invalid_json"`, `"missing_parameter"`, `"invalid_parameter"`, `"text_too_short"`, `"text_too_long"`, `"unsupported_media_type"`, `"unsupported_language"`, `"file_not_found"`, `"unsupported_file"`, `"file_too_large"`, `"too_many_pixels"`, `"too_many_pages"`, `"document_too_long"`, `"invalid_file"`, `"password_required"`, `"wrong_password"`, `"not_examinable"`, `"missing_api_key"`, `"invalid_api_key"`, `"insufficient_balance"`, `"spend_limit_reached"`, `"not_found"`, `"model_not_found"`, `"not_cancelable"`, `"canceled"`, `"idempotency_mismatch"`, `"idempotency_in_progress"`, `"pending_files_limit"`, `"rate_limited"`, `"internal_error"`, `"analysis_failed"`, `"service_unavailable"` | No |  |
| `message` | string | No |  |

**progress: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stage` | one of `"queued"`, `"reading"`, `"analyzing"`, `"reporting"` | No |  |
| `done` | integer | No | Units finished in the current stage, when known; otherwise 0. |
| `total` | integer | No | Units in the current stage, when known; otherwise 0. |
| `position` | integer | No | Queue position while the stage is queued. |

**usage: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | integer | No | Charge in cents; 0 for free-start checks and failures. |
| `currency` | `"usd"` | No |  |
| `funding` | one of `"trial"`, `"balance"`, `null` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `invalid_json` | 400 |
| `missing_parameter` | 400 |
| `unsupported_media_type` | 415 |
| `model_not_found` | 404 |
| `file_not_found` | 400 |
| `unsupported_file` | 415 |
| `invalid_file` | 422 |
| `file_too_large` | 413 |
| `too_many_pixels` | 413 |
| `too_many_pages` | 413 |
| `document_too_long` | 413 |
| `password_required` | 422 |
| `wrong_password` | 422 |
| `not_examinable` | 422 |
| `insufficient_balance` | 402 |
| `spend_limit_reached` | 402 |
| `service_unavailable` | 503 |
| `analysis_failed` | 502 |
| `invalid_parameter` | 400 |
| `idempotency_mismatch` | 409 |
| `idempotency_in_progress` | 409 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/analyses \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{"model": "fvimg-2", "file": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB"}'
```

**Response**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvimg-2-2026-10-30",
  "livemode": true,
  "status": "succeeded",
  "file": {
    "name": "claim-photo.jpg",
    "bytes": 2481920,
    "format": "jpeg"
  },
  "report_id": "FV-7K2M-9QXD-4T8R",
  "report_url": "https://fileverity.com/verify/FV-7K2M-9QXD-4T8R",
  "summary": {
    "level": "L2",
    "assessment": "authentic_untouched",
    "action": "accept",
    "ai": "very_low",
    "edit": "none"
  },
  "result": {
    "report": {
      "schema": "fileverity.report/1",
      "id": "FV-7K2M-9QXD-4T8R"
    },
    "stamped_at": 1793700130
  },
  "error": null,
  "progress": null,
  "usage": {
    "amount": 199,
    "currency": "usd",
    "funding": "balance"
  },
  "metadata": {
    "order_id": "A-10492"
  },
  "completed_at": 1793700131,
  "expires_at": 1794304931
}
```

### List analyses

`GET` `https://api.fileverity.com/v1/analyses`

Lists the image and document analyses of your workspace, newest first. Test keys always get an empty list.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `limit` | query | integer | No | Default `20`. Minimum 1. Maximum 100. |
| `starting_after` | query | string | No | Cursor: the next_cursor of the previous page. |
| `type` | query | one of `"image"`, `"document"` | No |  |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | A page of analyses. | `AnalysisList` |
| 400 | Invalid request. Error codes: invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: AnalysisList

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"list"` | Yes |  |
| `data` | array of `Analysis` | Yes |  |
| `has_more` | boolean | Yes |  |
| `next_cursor` | string or null | Yes | Pass as starting_after to get the next page. |

**data: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"analysis"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `model` | string | Yes | Snapshot that produced the result. |
| `livemode` | boolean | Yes |  |
| `status` | one of `"processing"`, `"succeeded"`, `"failed"`, `"canceled"` | Yes |  |
| `file` | object | Yes |  |
| `report_id` | string or null | Yes | Verifiable report ID, FV-XXXX-XXXX-XXXX. |
| `report_url` | string or null | Yes | Public verification page of the report. |
| `summary` | `ImageSummary` or `DocumentSummary` or null | Yes | The short, stable verdict: an ImageSummary for images, a DocumentSummary for documents, null until the analysis succeeds. |
| `result` | object or null | Yes | Present once status is succeeded and until the result expires. |
| `error` | object or null | Yes |  |
| `progress` | object or null | Yes |  |
| `usage` | object | Yes |  |
| `metadata` | object or null | Yes |  |
| `completed_at` | integer or null | Yes |  |
| `expires_at` | integer or null | Yes | Unix timestamp after which the result is deleted. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `bytes` | integer or null | No |  |
| `format` | string or null | No |  |

**result: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `report` | `ImageReport` or `DocumentReport` | No | The full report. report.schema is fileverity.report/1 for images and fileverity.docpro/1 for documents. |
| `stamped_at` | integer or null | No | Unix timestamp of the RFC 3161 timestamp issued for the report, or null. |

**error: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | one of `"invalid_json"`, `"missing_parameter"`, `"invalid_parameter"`, `"text_too_short"`, `"text_too_long"`, `"unsupported_media_type"`, `"unsupported_language"`, `"file_not_found"`, `"unsupported_file"`, `"file_too_large"`, `"too_many_pixels"`, `"too_many_pages"`, `"document_too_long"`, `"invalid_file"`, `"password_required"`, `"wrong_password"`, `"not_examinable"`, `"missing_api_key"`, `"invalid_api_key"`, `"insufficient_balance"`, `"spend_limit_reached"`, `"not_found"`, `"model_not_found"`, `"not_cancelable"`, `"canceled"`, `"idempotency_mismatch"`, `"idempotency_in_progress"`, `"pending_files_limit"`, `"rate_limited"`, `"internal_error"`, `"analysis_failed"`, `"service_unavailable"` | No |  |
| `message` | string | No |  |

**progress: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stage` | one of `"queued"`, `"reading"`, `"analyzing"`, `"reporting"` | No |  |
| `done` | integer | No | Units finished in the current stage, when known; otherwise 0. |
| `total` | integer | No | Units in the current stage, when known; otherwise 0. |
| `position` | integer | No | Queue position while the stage is queued. |

**usage: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | integer | No | Charge in cents; 0 for free-start checks and failures. |
| `currency` | `"usd"` | No |  |
| `funding` | one of `"trial"`, `"balance"`, `null` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `invalid_parameter` | 400 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl "https://api.fileverity.com/v1/analyses?limit=20&type=image" \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "object": "list",
  "data": [
    {
      "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
      "object": "analysis",
      "created": 1793700120,
      "model": "fvimg-2-2026-10-30",
      "livemode": true,
      "status": "succeeded",
      "file": {
        "name": "claim-photo.jpg",
        "bytes": 2481920,
        "format": "jpeg"
      },
      "report_id": "FV-7K2M-9QXD-4T8R",
      "report_url": "https://fileverity.com/verify/FV-7K2M-9QXD-4T8R",
      "summary": {
        "level": "L2",
        "assessment": "authentic_untouched",
        "action": "accept",
        "ai": "very_low",
        "edit": "none"
      },
      "result": {
        "report": {
          "schema": "fileverity.report/1",
          "id": "FV-7K2M-9QXD-4T8R"
        },
        "stamped_at": 1793700130
      },
      "error": null,
      "progress": null,
      "usage": {
        "amount": 199,
        "currency": "usd",
        "funding": "balance"
      },
      "metadata": {
        "order_id": "A-10492"
      },
      "completed_at": 1793700131,
      "expires_at": 1794304931
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

### Retrieve an analysis

`GET` `https://api.fileverity.com/v1/analyses/{id}`

Returns the analysis, with its result once it has succeeded and until it expires.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Analysis ID. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The analysis. | `Analysis` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: not_found. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: Analysis

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"analysis"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `model` | string | Yes | Snapshot that produced the result. |
| `livemode` | boolean | Yes |  |
| `status` | one of `"processing"`, `"succeeded"`, `"failed"`, `"canceled"` | Yes |  |
| `file` | object | Yes |  |
| `report_id` | string or null | Yes | Verifiable report ID, FV-XXXX-XXXX-XXXX. |
| `report_url` | string or null | Yes | Public verification page of the report. |
| `summary` | `ImageSummary` or `DocumentSummary` or null | Yes | The short, stable verdict: an ImageSummary for images, a DocumentSummary for documents, null until the analysis succeeds. |
| `result` | object or null | Yes | Present once status is succeeded and until the result expires. |
| `error` | object or null | Yes |  |
| `progress` | object or null | Yes |  |
| `usage` | object | Yes |  |
| `metadata` | object or null | Yes |  |
| `completed_at` | integer or null | Yes |  |
| `expires_at` | integer or null | Yes | Unix timestamp after which the result is deleted. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `bytes` | integer or null | No |  |
| `format` | string or null | No |  |

**result: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `report` | `ImageReport` or `DocumentReport` | No | The full report. report.schema is fileverity.report/1 for images and fileverity.docpro/1 for documents. |
| `stamped_at` | integer or null | No | Unix timestamp of the RFC 3161 timestamp issued for the report, or null. |

**error: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | one of `"invalid_json"`, `"missing_parameter"`, `"invalid_parameter"`, `"text_too_short"`, `"text_too_long"`, `"unsupported_media_type"`, `"unsupported_language"`, `"file_not_found"`, `"unsupported_file"`, `"file_too_large"`, `"too_many_pixels"`, `"too_many_pages"`, `"document_too_long"`, `"invalid_file"`, `"password_required"`, `"wrong_password"`, `"not_examinable"`, `"missing_api_key"`, `"invalid_api_key"`, `"insufficient_balance"`, `"spend_limit_reached"`, `"not_found"`, `"model_not_found"`, `"not_cancelable"`, `"canceled"`, `"idempotency_mismatch"`, `"idempotency_in_progress"`, `"pending_files_limit"`, `"rate_limited"`, `"internal_error"`, `"analysis_failed"`, `"service_unavailable"` | No |  |
| `message` | string | No |  |

**progress: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stage` | one of `"queued"`, `"reading"`, `"analyzing"`, `"reporting"` | No |  |
| `done` | integer | No | Units finished in the current stage, when known; otherwise 0. |
| `total` | integer | No | Units in the current stage, when known; otherwise 0. |
| `position` | integer | No | Queue position while the stage is queued. |

**usage: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | integer | No | Charge in cents; 0 for free-start checks and failures. |
| `currency` | `"usd"` | No |  |
| `funding` | one of `"trial"`, `"balance"`, `null` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `not_found` | 404 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/analyses/an_8Hk2pQ4vN9sL1xR7cW3mY6zB \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvimg-2-2026-10-30",
  "livemode": true,
  "status": "succeeded",
  "file": {
    "name": "claim-photo.jpg",
    "bytes": 2481920,
    "format": "jpeg"
  },
  "report_id": "FV-7K2M-9QXD-4T8R",
  "report_url": "https://fileverity.com/verify/FV-7K2M-9QXD-4T8R",
  "summary": {
    "level": "L2",
    "assessment": "authentic_untouched",
    "action": "accept",
    "ai": "very_low",
    "edit": "none"
  },
  "result": {
    "report": {
      "schema": "fileverity.report/1",
      "id": "FV-7K2M-9QXD-4T8R"
    },
    "stamped_at": 1793700130
  },
  "error": null,
  "progress": null,
  "usage": {
    "amount": 199,
    "currency": "usd",
    "funding": "balance"
  },
  "metadata": {
    "order_id": "A-10492"
  },
  "completed_at": 1793700131,
  "expires_at": 1794304931
}
```

### Cancel an analysis

`POST` `https://api.fileverity.com/v1/analyses/{id}/cancel`

Cancels a document analysis that is still processing and releases its charge. Image analyses cannot be canceled once created.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Analysis ID. |
| `Idempotency-Key` | header | string | No | Unique key of up to 255 characters. Repeating the request with the same key and body within 24 hours returns the first response with the header idempotent-replayed: true; the same key with a different body returns 409. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The canceled analysis. | `Analysis` |
| 400 | Invalid request. Error codes: invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: not_found. | `Error` |
| 409 | Conflict with the current state. Error codes: not_cancelable, idempotency_mismatch, idempotency_in_progress. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: Analysis

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"analysis"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `model` | string | Yes | Snapshot that produced the result. |
| `livemode` | boolean | Yes |  |
| `status` | one of `"processing"`, `"succeeded"`, `"failed"`, `"canceled"` | Yes |  |
| `file` | object | Yes |  |
| `report_id` | string or null | Yes | Verifiable report ID, FV-XXXX-XXXX-XXXX. |
| `report_url` | string or null | Yes | Public verification page of the report. |
| `summary` | `ImageSummary` or `DocumentSummary` or null | Yes | The short, stable verdict: an ImageSummary for images, a DocumentSummary for documents, null until the analysis succeeds. |
| `result` | object or null | Yes | Present once status is succeeded and until the result expires. |
| `error` | object or null | Yes |  |
| `progress` | object or null | Yes |  |
| `usage` | object | Yes |  |
| `metadata` | object or null | Yes |  |
| `completed_at` | integer or null | Yes |  |
| `expires_at` | integer or null | Yes | Unix timestamp after which the result is deleted. |

**file: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | No |  |
| `bytes` | integer or null | No |  |
| `format` | string or null | No |  |

**result: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `report` | `ImageReport` or `DocumentReport` | No | The full report. report.schema is fileverity.report/1 for images and fileverity.docpro/1 for documents. |
| `stamped_at` | integer or null | No | Unix timestamp of the RFC 3161 timestamp issued for the report, or null. |

**error: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | one of `"invalid_json"`, `"missing_parameter"`, `"invalid_parameter"`, `"text_too_short"`, `"text_too_long"`, `"unsupported_media_type"`, `"unsupported_language"`, `"file_not_found"`, `"unsupported_file"`, `"file_too_large"`, `"too_many_pixels"`, `"too_many_pages"`, `"document_too_long"`, `"invalid_file"`, `"password_required"`, `"wrong_password"`, `"not_examinable"`, `"missing_api_key"`, `"invalid_api_key"`, `"insufficient_balance"`, `"spend_limit_reached"`, `"not_found"`, `"model_not_found"`, `"not_cancelable"`, `"canceled"`, `"idempotency_mismatch"`, `"idempotency_in_progress"`, `"pending_files_limit"`, `"rate_limited"`, `"internal_error"`, `"analysis_failed"`, `"service_unavailable"` | No |  |
| `message` | string | No |  |

**progress: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stage` | one of `"queued"`, `"reading"`, `"analyzing"`, `"reporting"` | No |  |
| `done` | integer | No | Units finished in the current stage, when known; otherwise 0. |
| `total` | integer | No | Units in the current stage, when known; otherwise 0. |
| `position` | integer | No | Queue position while the stage is queued. |

**usage: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | integer | No | Charge in cents; 0 for free-start checks and failures. |
| `currency` | `"usd"` | No |  |
| `funding` | one of `"trial"`, `"balance"`, `null` | No |  |

#### Error codes

| Code | Status |
| --- | --- |
| `not_found` | 404 |
| `not_cancelable` | 409 |
| `invalid_parameter` | 400 |
| `idempotency_mismatch` | 409 |
| `idempotency_in_progress` | 409 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl -X POST https://api.fileverity.com/v1/analyses/an_8Hk2pQ4vN9sL1xR7cW3mY6zB/cancel \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvimg-2-2026-10-30",
  "livemode": true,
  "status": "canceled",
  "file": {
    "name": "claim-photo.jpg",
    "bytes": 2481920,
    "format": "jpeg"
  },
  "report_id": null,
  "report_url": null,
  "summary": null,
  "result": null,
  "error": {
    "code": "canceled",
    "message": "The analysis was canceled. You were not charged."
  },
  "progress": null,
  "usage": {
    "amount": 0,
    "currency": "usd",
    "funding": null
  },
  "metadata": null,
  "completed_at": 1793700135,
  "expires_at": null
}
```

### Download the PDF report

`GET` `https://api.fileverity.com/v1/analyses/{id}/report.pdf`

Returns the sealed PDF report of a succeeded analysis while its result is kept. Test keys get 404. Document evidence such as page images is available for 3 hours after the analysis; after that the PDF omits it, signaled by x-evidence-included: false.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | Yes | Analysis ID. |
| `locale` | query | one of `"en"`, `"fr"`, `"de"`, `"es"`, `"zh"`, `"vi"`, `"ar"` | No | Default `"en"`. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The PDF report. | PDF file |
| 400 | Invalid request. Error codes: invalid_parameter. | `Error` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: not_found. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Error codes

| Code | Status |
| --- | --- |
| `invalid_parameter` | 400 |
| `not_found` | 404 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl "https://api.fileverity.com/v1/analyses/an_8Hk2pQ4vN9sL1xR7cW3mY6zB/report.pdf?locale=en" \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -o Fileverity-FV-7K2M-9QXD-4T8R.pdf
```

## Models

### List models

`GET` `https://api.fileverity.com/v1/models`

Lists the models available to your API key.

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The available models. | `ModelList` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: ModelList

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"list"` | Yes |  |
| `data` | array of `Model` | Yes |  |

**data: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"model"` | Yes |  |
| `created` | integer | Yes | Unix timestamp of the current snapshot. |
| `owned_by` | string | Yes |  |
| `name` | string | Yes |  |
| `type` | one of `"image"`, `"document"`, `"text"` | Yes |  |
| `description` | string | Yes |  |
| `snapshot` | string | Yes | Dated snapshot the ID currently points to. |
| `status` | one of `"available"`, `"preview"`, `"deprecated"` | Yes |  |
| `input` | object | Yes | Accepted input. Files list formats and size limits; text lists languages and length limits. |
| `output` | object | Yes |  |
| `pricing` | object | Yes |  |

**input: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `formats` | array of string | No |  |
| `max_bytes` | integer | No |  |
| `max_megapixels` | integer | No |  |
| `max_pages` | integer | No |  |
| `languages` | array of string | No |  |
| `min_words` | integer | No |  |
| `max_characters` | integer | No |  |

**output: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schema` | string | Yes | Schema of the report in analysis results. |

**pricing: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `currency` | `"usd"` | Yes |  |
| `unit` | string | Yes |  |
| `unit_amount` | integer | Yes | Price per unit in cents. |

#### Error codes

| Code | Status |
| --- | --- |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/models \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "object": "list",
  "data": [
    {
      "id": "fvimg-2",
      "object": "model",
      "created": 1793318400,
      "owned_by": "fileverity",
      "name": "FVIMG V2",
      "type": "image",
      "description": "Image authenticity analysis. Detects AI generation and local edits, checks content credentials and metadata, and returns a verifiable report.",
      "snapshot": "fvimg-2-2026-10-30",
      "status": "available",
      "input": {
        "formats": [
          "jpeg",
          "png",
          "webp"
        ],
        "max_bytes": 10485760,
        "max_megapixels": 40
      },
      "output": {
        "schema": "fileverity.report/1"
      },
      "pricing": {
        "currency": "usd",
        "unit": "image",
        "unit_amount": 199
      }
    },
    {
      "id": "fvdoc-3",
      "object": "model",
      "created": 1793664000,
      "owned_by": "fileverity",
      "name": "FVDOC V3",
      "type": "document",
      "description": "Document fraud analysis. Evaluates AI-written text, embedded photos, edit history and signatures, and returns a verifiable report.",
      "snapshot": "fvdoc-3-2026-11-03",
      "status": "available",
      "input": {
        "formats": [
          "pdf",
          "docx",
          "doc",
          "rtf",
          "odt",
          "pptx",
          "txt"
        ],
        "max_bytes": 52428800,
        "max_pages": 100
      },
      "output": {
        "schema": "fileverity.docpro/1"
      },
      "pricing": {
        "currency": "usd",
        "unit": "document",
        "unit_amount": 599
      }
    },
    {
      "id": "fvdoc-3-text",
      "object": "model",
      "created": 1793664000,
      "owned_by": "fileverity",
      "name": "FVDOC V3 Text",
      "type": "text",
      "description": "AI-written text detection. Classifies plain text as AI-written, partly AI-written or human-written and marks the AI-written passages.",
      "snapshot": "fvdoc-3-text-2026-11-03",
      "status": "available",
      "input": {
        "languages": [
          "en",
          "fr",
          "de",
          "es",
          "zh"
        ],
        "min_words": 100,
        "max_characters": 100000
      },
      "output": {
        "schema": "fileverity.text-detection/1"
      },
      "pricing": {
        "currency": "usd",
        "unit": "1000_characters",
        "unit_amount": 14
      }
    }
  ]
}
```

### Retrieve a model

`GET` `https://api.fileverity.com/v1/models/{model}`

Retrieves a model by its ID or snapshot ID.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `model` | path | string | Yes | Model ID or snapshot ID. |

#### Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | The model. | `Model` |
| 401 | Missing or invalid API key. Error codes: missing_api_key, invalid_api_key. | `Error` |
| 404 | Resource not found. Error codes: model_not_found. | `Error` |
| 429 | Too many requests. Error codes: rate_limited. | `Error` |
| 500 | Internal error; not charged. Error codes: internal_error. | `Error` |

#### Response 200: Model

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `object` | `"model"` | Yes |  |
| `created` | integer | Yes | Unix timestamp of the current snapshot. |
| `owned_by` | string | Yes |  |
| `name` | string | Yes |  |
| `type` | one of `"image"`, `"document"`, `"text"` | Yes |  |
| `description` | string | Yes |  |
| `snapshot` | string | Yes | Dated snapshot the ID currently points to. |
| `status` | one of `"available"`, `"preview"`, `"deprecated"` | Yes |  |
| `input` | object | Yes | Accepted input. Files list formats and size limits; text lists languages and length limits. |
| `output` | object | Yes |  |
| `pricing` | object | Yes |  |

**input: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `formats` | array of string | No |  |
| `max_bytes` | integer | No |  |
| `max_megapixels` | integer | No |  |
| `max_pages` | integer | No |  |
| `languages` | array of string | No |  |
| `min_words` | integer | No |  |
| `max_characters` | integer | No |  |

**output: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schema` | string | Yes | Schema of the report in analysis results. |

**pricing: fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `currency` | `"usd"` | Yes |  |
| `unit` | string | Yes |  |
| `unit_amount` | integer | Yes | Price per unit in cents. |

#### Error codes

| Code | Status |
| --- | --- |
| `model_not_found` | 404 |
| `missing_api_key` | 401 |
| `invalid_api_key` | 401 |
| `rate_limited` | 429 |
| `internal_error` | 500 |

#### Example

**Request: cURL**

```bash
curl https://api.fileverity.com/v1/models/fvimg-2 \
  -H "Authorization: Bearer $FILEVERITY_API_KEY"
```

**Response**

```json
{
  "id": "fvimg-2",
  "object": "model",
  "created": 1793318400,
  "owned_by": "fileverity",
  "name": "FVIMG V2",
  "type": "image",
  "description": "Image authenticity analysis. Detects AI generation and local edits, checks content credentials and metadata, and returns a verifiable report.",
  "snapshot": "fvimg-2-2026-10-30",
  "status": "available",
  "input": {
    "formats": [
      "jpeg",
      "png",
      "webp"
    ],
    "max_bytes": 10485760,
    "max_megapixels": 40
  },
  "output": {
    "schema": "fileverity.report/1"
  },
  "pricing": {
    "currency": "usd",
    "unit": "image",
    "unit_amount": 199
  }
}
```

## Webhook events

Fileverity sends these events to your webhook endpoints. Verification and delivery rules are in [Webhooks](https://fileverity.com/en/docs/webhooks.md).

### Event analysis.completed

Delivered to your webhook endpoints following the Standard Webhooks specification: the headers webhook-id, webhook-timestamp and webhook-signature (v1,<base64 HMAC-SHA256 of id.timestamp.body>, keyed with the base64 part of your whsec_ secret). Respond with any 2xx within 10 seconds; failures are retried with exponential backoff for 3 days.

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Also sent as the webhook-id header; use it to deduplicate retries. |
| `object` | `"event"` | Yes |  |
| `type` | one of `"analysis.completed"`, `"analysis.failed"`, `"balance.low"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `data` | `Analysis` or `BalanceLow` | Yes | analysis.* events carry the same object as GET /analyses/{id}, with result always null; fetch the result with that endpoint. balance.low events carry the balance and threshold in cents. |

**data (BalanceLow): fields**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `balance` | integer | Yes | Balance in cents. |
| `threshold` | integer | Yes | Alert threshold in cents. |

### Event analysis.failed

Delivered to your webhook endpoints following the Standard Webhooks specification: the headers webhook-id, webhook-timestamp and webhook-signature (v1,<base64 HMAC-SHA256 of id.timestamp.body>, keyed with the base64 part of your whsec_ secret). Respond with any 2xx within 10 seconds; failures are retried with exponential backoff for 3 days.

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Also sent as the webhook-id header; use it to deduplicate retries. |
| `object` | `"event"` | Yes |  |
| `type` | one of `"analysis.completed"`, `"analysis.failed"`, `"balance.low"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `data` | `Analysis` or `BalanceLow` | Yes | analysis.* events carry the same object as GET /analyses/{id}, with result always null; fetch the result with that endpoint. balance.low events carry the balance and threshold in cents. |

### Event balance.low

Delivered to your webhook endpoints following the Standard Webhooks specification: the headers webhook-id, webhook-timestamp and webhook-signature (v1,<base64 HMAC-SHA256 of id.timestamp.body>, keyed with the base64 part of your whsec_ secret). Respond with any 2xx within 10 seconds; failures are retried with exponential backoff for 3 days.

#### Request body: application/json, required

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Also sent as the webhook-id header; use it to deduplicate retries. |
| `object` | `"event"` | Yes |  |
| `type` | one of `"analysis.completed"`, `"analysis.failed"`, `"balance.low"` | Yes |  |
| `created` | integer | Yes | Unix timestamp. |
| `data` | `Analysis` or `BalanceLow` | Yes | analysis.* events carry the same object as GET /analyses/{id}, with result always null; fetch the result with that endpoint. balance.low events carry the balance and threshold in cents. |

**OpenAPI**

```bash
curl https://api.fileverity.com/v1/openapi.json
```

