# 分析

> 创建图片和文档分析，通过 Prefer: wait 或轮询等待结果，取消分析，下载 PDF 报告，并了解报告对象和核验页。

来源： https://fileverity.com/zh/docs/analyses

每个分析对应一次图片或文档检测。它使用 `fvimg-2`（图片）或 `fvdoc-3`（文档）检测一个已上传的文件。请先上传文件（见[文件](https://fileverity.com/zh/docs/files.md)），再创建分析。

包含请求和响应的产品概述，请参阅 [AI 生成图片检测 API](https://fileverity.com/zh/api/ai-image-detection) 和[文档伪造检测 API](https://fileverity.com/zh/api/document-fraud-detection)。

## 创建分析

`POST /analyses` 返回分析对象。创建分析时会预留费用；若分析失败或被取消，预留的费用会被释放。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `model` | string | 是 | `fvimg-2` 或 `fvdoc-3`，或快照 ID，例如 `fvimg-2-2026-10-30`。 |
| `file` | string | 是 | 已上传文件的 ID。 |
| `metadata` | object | 否 | 最多 16 个字符串键值对。键最长 40 个字符，值最长 500 个字符。会随分析对象和 Webhook 一并返回。 |
| `options.password` | string | 否 | 加密文档的密码，最长 256 个字符。 |
| `options.locale` | string | 否 | 文档检测发现所用的语言：`en`、`fr`、`de`、`es`、`zh`、`vi` 或 `ar`。默认为 `en`。 |

**创建分析: cURL**

```bash
curl https://api.fileverity.com/v1/analyses \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0e5f6a64-52c2-4b36-9d0d-6f3d2f4c9a10" \
  -d '{"model": "fvdoc-3", "file": "file_Pw3mY6zB8Hk2pQ4vN9sL1xR7", "metadata": {"order_id": "A-10492"}}'
```

**创建分析: JavaScript**

```javascript
const response = await fetch("https://api.fileverity.com/v1/analyses", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.FILEVERITY_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({ model: "fvdoc-3", file: file.id, metadata: { order_id: "A-10492" } }),
});
const analysis = await response.json();
```

**创建分析: Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.fileverity.com/v1/analyses",
    headers={
        "Authorization": "Bearer " + os.environ["FILEVERITY_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"model": "fvdoc-3", "file": file["id"], "metadata": {"order_id": "A-10492"}},
)
analysis = response.json()
```

## 等待、轮询或使用 Webhook

创建请求返回 `202` 和 `status: processing`。有三种方式获取结果：

- **等待**：发送 `Prefer: wait=N`，其中 N 最大为 60 秒。请求会保持等待，直到分析完成或经过 N 秒。分析完成时返回 `200`；否则仍返回 `202`。响应头 `preference-applied: wait=N` 会确认该等待设置已生效。
- **轮询**：每隔几秒调用一次 `GET /analyses/{id}`，直到 `status` 不再是 `processing`。
- **Webhook**：订阅 `analysis.completed` 和 `analysis.failed`，在事件到达时获取该分析。参见 [Webhooks](https://fileverity.com/zh/docs/webhooks.md)。

**轮询直到完成: JavaScript**

```javascript
let analysis = created;
while (analysis.status === "processing") {
  await new Promise((resolve) => setTimeout(resolve, 3000));
  const response = await fetch("https://api.fileverity.com/v1/analyses/" + analysis.id, {
    headers: { Authorization: "Bearer " + process.env.FILEVERITY_API_KEY },
  });
  analysis = await response.json();
}
```

**轮询直到完成: Python**

```python
import time

analysis = created
while analysis["status"] == "processing":
    time.sleep(3)
    analysis = requests.get("https://api.fileverity.com/v1/analyses/" + analysis["id"], headers=headers).json()
```

**202 Accepted（文档）**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvdoc-3-2026-11-03",
  "livemode": true,
  "status": "processing",
  "file": {
    "name": "contract.pdf",
    "bytes": 18874368,
    "format": "pdf"
  },
  "report_id": null,
  "report_url": null,
  "summary": null,
  "result": null,
  "error": null,
  "progress": {
    "stage": "queued",
    "done": 0,
    "total": 0,
    "position": 1
  },
  "usage": {
    "amount": 599,
    "currency": "usd",
    "funding": "balance"
  },
  "metadata": {
    "order_id": "A-10492"
  },
  "completed_at": null,
  "expires_at": null
}
```

分析处理期间，`progress.stage` 为 `queued`、`reading`、`analyzing` 或 `reporting` 之一；当阶段为 `queued` 时，`position` 表示排队位置。文档可能需要排队。对文档来说，等待是可选的，并且可能在结果就绪前结束，因此务必处理 `202`。

## 服务繁忙时

资源繁忙时，`POST /analyses` 返回 `503`，错误码为 `service_unavailable`，并带有 `retry-after` 响应头。不会扣费。请等待 `retry-after` 指定的秒数，然后使用相同的 `Idempotency-Key` 重试，这样重试绝不会让同一次检测运行两次。若要获得最佳吞吐量，请依次运行图片分析，而不是并行运行。

**繁忙时重试: JavaScript**

```javascript
async function create(body, key) {
  for (let attempt = 0; attempt < 5; attempt++) {
    const response = await fetch("https://api.fileverity.com/v1/analyses", {
      method: "POST",
      headers: { Authorization: "Bearer " + process.env.FILEVERITY_API_KEY, "Content-Type": "application/json", "Idempotency-Key": key },
      body: JSON.stringify(body),
    });
    if (response.status !== 503) return response;
    const wait = Number(response.headers.get("retry-after")) || 15;
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
  }
  throw new Error("Service busy");
}
```

**繁忙时重试: Python**

```python
import time

def create(body, key):
    for attempt in range(5):
        response = requests.post("https://api.fileverity.com/v1/analyses", headers={**headers, "Idempotency-Key": key}, json=body)
        if response.status_code != 503:
            return response
        time.sleep(int(response.headers.get("retry-after", 15)))
    raise RuntimeError("Service busy")
```

## 状态

| 状态 | 含义 |
| --- | --- |
| `processing` | 分析正在运行。`result` 为 `null`。 |
| `succeeded` | 结果已就绪。`report_id`、`report_url`、`summary` 和 `result` 均已设置。 |
| `failed` | 分析未能完成。`error` 中包含 `code` 和 `message`。未扣费。 |
| `canceled` | 您已取消该分析。`error.code` 为 `canceled`。未扣费。 |

**失败的分析**

```json
{
  "id": "an_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "analysis",
  "created": 1793700120,
  "model": "fvimg-2-2026-10-30",
  "livemode": true,
  "status": "failed",
  "file": {
    "name": "claim-photo.jpg",
    "bytes": 2481920,
    "format": "jpeg"
  },
  "report_id": null,
  "report_url": null,
  "summary": null,
  "result": null,
  "error": {
    "code": "analysis_failed",
    "message": "The analysis could not be completed. You were not charged; retry it, and contact support with the request ID if it fails again."
  },
  "progress": null,
  "usage": {
    "amount": 0,
    "currency": "usd",
    "funding": null
  },
  "metadata": null,
  "completed_at": 1793700135,
  "expires_at": null
}
```

## 报告对象

成功的分析会带有一份报告，其内容与网站、PDF 和核验页上显示的报告相同。

| 字段 | 说明 |
| --- | --- |
| `report_id` | 报告编号，`FV-XXXX-XXXX-XXXX`。 |
| `report_url` | 该报告的公开核验页。任何拿到链接的人无需账号，即可对照记录核验报告编号、文件指纹和时间戳。 |
| `summary` | 简短的判定结果。见下文。 |
| `result.report` | 完整报告。图片的 `result.report.schema` 为 `fileverity.report/1`，文档的为 `fileverity.docpro/1`。 |
| `result.stamped_at` | 为该报告签发的 RFC 3161 时间戳所对应的 Unix 时间戳，或 `null`。 |
| `usage` | 已扣费金额 `amount`（单位为美分，免费额度内的检测和失败的检测为 0）、`currency` 以及 `funding`（`trial` 或 `balance`）。 |
| `metadata` | 您传入的元数据，或 `null`。 |
| `expires_at` | `result` 将在此 Unix 时间戳之后被移除。结果保留 7 天。 |

**200 OK（图片）**

```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
}
```

上面的 `report` 对象已缩短；实际返回的对象包含完整的检测发现。

`summary` 是稳定的、机器可读的判定结果。`result.report` 是网站和 PDF 所呈现的完整报告，其结构遵循 `result.report.schema` 中指明的 schema。在同一 schema 版本内，已列出的字段保持名称和含义不变，也可能新增字段，因此请忽略无法识别的字段。

### 图片摘要

| 字段 | 取值 |
| --- | --- |
| `level` | `L0` 无法判定，`L1` 来源已验证，`L2` 未发现异常，`L3` 需人工复核，`L4` 高度可疑，`L5` 有力证据否定真实性。 |
| `action` | `accept`, `review`, `reject`, `resubmit` |
| `assessment` | `authentic_untouched`, `authentic_locally_edited`, `ai_generated`, `undetermined` |
| `ai` | `labelled`, `very_likely`, `suspected`, `undecided`, `low`, `very_low`, `not_evaluated` |
| `edit` | `detected`, `suspected`, `suspected_record`, `review`, `generative`, `minor`, `none`, `not_applicable`, `not_evaluated` |

### 文档摘要

| 字段 | 说明 |
| --- | --- |
| `kind` | 始终为 `docpro`。 |
| `level` | `L0` 无法判定，`L1` 来源已验证，`L2` 未发现篡改迹象，`L3` 需人工复核，`L4` 高风险，`L5` 问题已证实。 |
| `action` | `accept`、`note`（对照您的政策，核查报告中标出的 AI 内容）、`review`、`reject` 或 `resubmit`。 |
| `reason` | 该风险等级背后的发现或条件，例如 `clean`、`incomplete` 或某个发现 ID，或 `null`。 |
| `findings` | 重要发现的 ID。 |
| `pages`, `images` | 文档中的页数，以及已检查的内嵌照片数。 |
| `text` | 对文档文本的判定（`ai_generated`、`mixed`、`human`、`inconclusive`）；未评估文本时为 `null`。 |
| `strong` | 当所列发现中包含强证据时为 `true`，否则不出现。 |

**200 OK（文档）**

```json
{
  "id": "an_Zc4vB7nP1sK8tL3wR6yQm2Xa",
  "object": "analysis",
  "created": 1793700300,
  "model": "fvdoc-3-2026-11-03",
  "livemode": true,
  "status": "succeeded",
  "file": {
    "name": "contract.pdf",
    "bytes": 18874368,
    "format": "pdf"
  },
  "report_id": "FV-3PXH-6WQ2-8NDC",
  "report_url": "https://fileverity.com/verify/FV-3PXH-6WQ2-8NDC",
  "summary": {
    "kind": "docpro",
    "level": "L3",
    "action": "review",
    "reason": null,
    "findings": [],
    "pages": 12,
    "images": 3,
    "text": "human"
  },
  "result": {
    "report": {
      "schema": "fileverity.docpro/1",
      "id": "FV-3PXH-6WQ2-8NDC"
    },
    "stamped_at": 1793700340
  },
  "error": null,
  "progress": null,
  "usage": {
    "amount": 599,
    "currency": "usd",
    "funding": "balance"
  },
  "metadata": null,
  "completed_at": 1793700341,
  "expires_at": 1794305141
}
```

### 图片报告字段

图片分析的 `result.report`。嵌套对象列于 [API 参考](https://fileverity.com/zh/docs/api-reference.md#create-analysis)。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `schema` | `"fileverity.report/1"` | 是 |  |
| `id` | string | 是 | 报告编号，FV-XXXX-XXXX-XXXX。 |
| `sample` | `true` | 否 | 出现在测试密钥返回的固定示例报告中。 |
| `issuedAt` | string | 否 | 报告签发时间，UTC 的 ISO 8601 格式。格式为 date-time。 |
| `issuer` | object | 否 | 报告的签发方。 |
| `file` | object | 否 | 被检测的图片。 |
| `pro` | object | 否 | 判定结果。取值与 summary 相同，并附带 reason。 |
| `score` | integer 或 null | 否 | 真实性评分，取值 0 到 100，步长为 5：表示证据在多大程度上支持该图片为未经编辑的真实拍摄。未评估时为 null。 |
| `confidence` | 以下值之一：`"high"`、`"medium"`、`"low"` | 否 | 该文件可供分析确定结论的程度。置信度低通常源于文件本身，例如分辨率低或压缩严重。 |
| `questions` | object | 否 | 报告回答的三个问题。 |
| `generator` | object 或 null | 否 | 为该图片指出的 AI 生成器，或 null。 |
| `regions` | object 数组 | 否 | 被标记的区域，以所显示图片的像素为单位。 |
| `provenance` | object | 否 | 文件自身记录所反映的来源信息。 |
| `digest` | string | 否 | 报告内容的指纹，供核验页使用。 |

### 文档报告字段

文档分析的 `result.report`。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `schema` | `"fileverity.docpro/1"` | 是 |  |
| `id` | string | 是 | 报告编号，FV-XXXX-XXXX-XXXX。 |
| `sample` | `true` | 否 | 出现在测试密钥返回的固定示例报告中。 |
| `issuedAt` | string | 否 | 报告签发时间，UTC 的 ISO 8601 格式。格式为 date-time。 |
| `receivedAt` | string | 否 | 文件接收时间，UTC 的 ISO 8601 格式。格式为 date-time。 |
| `issuer` | object | 否 | 报告的签发方。 |
| `file` | object | 否 | 被检测的文档。 |
| `level` | 以下值之一：`"L0"`、`"L1"`、`"L2"`、`"L3"`、`"L4"`、`"L5"` | 否 | 风险等级，L0 至 L5。 |
| `action` | 以下值之一：`"accept"`、`"note"`、`"review"`、`"reject"`、`"resubmit"` | 否 |  |
| `reason` | string 或 null | 否 | 该风险等级背后的发现或条件。 |
| `findings` | object 数组 | 否 | 该风险等级背后的各项发现，每项发现都附有其涉及的页面和内嵌照片。 |
| `text` | object | 否 | 文档文本的检测结果。 |
| `images` | object 数组 | 否 | 内嵌的照片和图形，按在文档中的顺序编号。 |
| `structure` | object 或 null | 否 | 文件的编辑历史，未检查时为 null。 |
| `provenance` | object | 否 | 文件自身记录所反映的来源信息。 |
| `digest` | string | 否 | 报告内容的指纹，供核验页使用。 |

## 获取、列出与取消

- `GET /analyses/{id}` 返回该分析；结果在保留期内一并返回。
- `GET /analyses` 按从新到旧的顺序列出工作区的分析。`limit` 取值 1 到 100（默认 20），`type` 可按 `image` 或 `document` 过滤，`starting_after` 接收上一页返回的 `next_cursor`。列表项不会包含 `result`。
- `POST /analyses/{id}/cancel` 取消仍在处理中的文档分析，并释放已预留的费用。图片分析无法取消；过晚或已完成后的取消请求会返回 `not_cancelable`。

**列出与取消: cURL**

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

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

## PDF 报告

`GET /analyses/{id}/report.pdf` 可在结果保留期内下载成功分析的数字签名 PDF 报告。添加 `?locale=` 并取值为 `en`、`fr`、`de`、`es`、`zh`、`vi` 或 `ar`（默认为 `en`）。请发送 `Authorization` 请求头；响应类型为 `application/pdf`。

**下载 PDF: 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
```

对于文档，页面图片和文本摘录在检测后保留 3 小时。此后 PDF 将不再包含这些内容，响应头 `x-evidence-included` 为 `false`。如需 PDF 包含这些证据，请在分析完成后立即下载。

## 错误

| 错误码 | 状态 | 原因 |
| --- | --- | --- |
| `file_not_found` | 400 | 文件 ID 未知、已过期或已被使用，或者向 `upload.url` 的上传尚未完成。 |
| `model_not_found` | 404 | 未知模型。 |
| `invalid_parameter` | 400 | 字段缺失、类型错误或未知。文本模型应使用 `POST /text/detections`。 |
| `unsupported_file`, `invalid_file` | 415, 422 | 该模型不支持此文件格式，或文件已损坏。 |
| `file_too_large`, `too_many_pixels`, `too_many_pages`, `document_too_long` | 413 | 超出大小限制。 |
| `password_required`, `wrong_password` | 422 | 文档已加密。请发送 `options.password`。 |
| `not_examinable` | 422 | 文档中没有可检测的内容。未扣费。 |
| `insufficient_balance`, `spend_limit_reached` | 402 | 余额或该密钥的每月支出上限不足以支付此次费用。 |
| `service_unavailable`, `analysis_failed` | 503, 502 | 临时故障或资源繁忙。未扣费；请重试。`service_unavailable` 会带有 `retry-after` 响应头。参见[服务繁忙时](https://fileverity.com/zh/docs/analyses.md#busy)。 |
| `unsupported_media_type` | 415 | 请求体不是以 `application/json` 发送的。 |
| `idempotency_mismatch`, `idempotency_in_progress` | 409 | 该 `Idempotency-Key` 曾用于不同的请求体，或其首次请求仍在运行。参见[幂等性](https://fileverity.com/zh/docs/idempotency.md)。 |
| `not_cancelable` | 409 | 只有仍在处理中的文档才能取消。 |

> **注意。** 有些失败发生在分析创建之后，例如模型无法完成检测。此时创建请求本身不会失败，而是在分析上设置 `status: failed` 和 `error`，并触发 `analysis.failed` Webhook。参见[错误](https://fileverity.com/zh/docs/errors.md)。

