Skip to content

Fileverity API docs

Analyses

Create image and document analyses, wait for the result with Prefer: wait or poll, cancel, download the PDF report and read the report object and verification page.

View as MarkdownUpdated 2026-11-04

An analysis is one image or document check. It checks one uploaded file with fvimg-2 (images) or fvdoc-3 (documents). Upload the file first (see Files), then create the analysis.

For a product overview with a request and a response, see the AI image detection API and Document fraud detection API.

Create an analysis

POST /analyses returns the analysis object. The price is reserved when the analysis is created and released if it fails or is canceled.

FieldTypeRequiredDescription
modelstringYesfvimg-2 or fvdoc-3, or a snapshot ID such as fvimg-2-2026-10-30.
filestringYesID of an uploaded file.
metadataobjectNoUp to 16 string pairs. Keys up to 40 characters, values up to 500. Returned on the analysis and in webhooks.
options.passwordstringNoPassword of an encrypted document, up to 256 characters.
options.localestringNoLanguage of document findings: en, fr, de, es, zh, vi or ar. Default en.
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"}}'

Wait, poll or use webhooks

Create returns 202 with status: processing. You have three ways to get the result:

  • Wait. Send Prefer: wait=N, where N is up to 60 seconds. The request is held until the analysis finishes or N seconds pass. A finished analysis returns 200; otherwise you still get 202. The response header preference-applied: wait=N confirms the wait.
  • Poll. Call GET /analyses/{id} every few seconds until status is no longer processing.
  • Webhook. Subscribe to analysis.completed and analysis.failed and fetch the analysis when the event arrives. See Webhooks.
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();}
{  "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}

While an analysis is processing, progress.stage is one of queued, reading, analyzing or reporting, and position is the queue position while the stage is queued. Documents can be queued. Waiting is optional for documents and can end before the result is ready, so always handle 202.

When the service is busy

When capacity is busy, POST /analyses returns 503 with the code service_unavailable and a retry-after header. You are not charged. Wait the number of seconds in retry-after, then retry with the same Idempotency-Key so the retry can never run a check twice. For the best throughput, run image analyses one after another instead of in parallel.

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");}

Statuses

StatusMeaning
processingThe analysis is running. result is null.
succeededThe result is ready. report_id, report_url, summary and result are set.
failedThe analysis could not be completed. error holds the code and message. You were not charged.
canceledYou canceled it. error.code is canceled. You were not charged.
{  "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}

The report object

A succeeded analysis carries the same report that the website, the PDF and the verification page show.

FieldDescription
report_idReport ID, FV-XXXX-XXXX-XXXX.
report_urlPublic verification page for the report. Anyone with the link can check the report ID, the file fingerprint and the timestamp against the record, without an account.
summaryThe short verdict. See below.
result.reportThe full report. result.report.schema is fileverity.report/1 for images and fileverity.docpro/1 for documents.
result.stamped_atUnix timestamp of the RFC 3161 timestamp issued for the report, or null.
usageamount charged in cents (0 for free-start checks and failures), currency and funding (trial or balance).
metadataThe metadata you sent, or null.
expires_atUnix timestamp after which result is removed. Results are kept for 7 days.
{  "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}

The report object is shortened above; the real one holds the complete findings.

The summary is the stable, machine-readable verdict. result.report is the full report that the website and the PDF render. Its structure follows the schema named in result.report.schema. Within the same schema version, listed fields keep their name and meaning, and new fields can be added, so ignore fields you do not recognize.

Image summary

FieldValues
levelL0 Undetermined, L1 Source verified, L2 No anomalies found, L3 Needs manual review, L4 Highly suspicious, L5 Strong evidence against authenticity.
actionaccept, review, reject, resubmit
assessmentauthentic_untouched, authentic_locally_edited, ai_generated, undetermined
ailabelled, very_likely, suspected, undecided, low, very_low, not_evaluated
editdetected, suspected, suspected_record, review, generative, minor, none, not_applicable, not_evaluated

Document summary

FieldDescription
kindAlways docpro.
levelL0 Undetermined, L1 Source verified, L2 No signs of tampering, L3 Needs manual review, L4 High risk, L5 Problems established.
actionaccept, note (check the AI content marked in the report against your policy), review, reject or resubmit.
reasonThe finding or condition behind the level, for example clean, incomplete or a finding ID, or null.
findingsIDs of the findings that matter.
pages, imagesPages in the document and embedded photos examined.
textThe verdict on the document's text (ai_generated, mixed, human, inconclusive), or null when text was not evaluated.
strongtrue when a listed finding is strong. Absent otherwise.
{  "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}

Image report fields

result.report of an image analysis. Nested objects are listed in the API reference.

FieldTypeRequiredDescription
schema"fileverity.report/1"Yes
idstringYesReport ID, FV-XXXX-XXXX-XXXX.
sampletrueNoPresent on the fixed sample reports that test keys return.
issuedAtstringNoWhen the report was issued, ISO 8601 in UTC. Format date-time.
issuerobjectNoWho issued the report.
fileobjectNoThe checked image.
proobjectNoThe verdict. The same values as summary, with reason.
scoreinteger or nullNoAuthenticity 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.
confidenceone of "high", "medium", "low"NoHow much this file allows the analysis to establish. Low confidence usually reflects the file itself, such as low resolution or heavy compression.
questionsobjectNoThe three questions the report answers.
generatorobject or nullNoThe AI generator named for the image, or null.
regionsarray of objectNoFlagged regions, in pixels of the displayed image.
provenanceobjectNoWhat the file's own records say about its origin.
digeststringNoFingerprint of the report content, used by the verification page.

Document report fields

result.report of a document analysis.

FieldTypeRequiredDescription
schema"fileverity.docpro/1"Yes
idstringYesReport ID, FV-XXXX-XXXX-XXXX.
sampletrueNoPresent on the fixed sample reports that test keys return.
issuedAtstringNoWhen the report was issued, ISO 8601 in UTC. Format date-time.
receivedAtstringNoWhen the file was received, ISO 8601 in UTC. Format date-time.
issuerobjectNoWho issued the report.
fileobjectNoThe checked document.
levelone of "L0", "L1", "L2", "L3", "L4", "L5"NoRisk level, L0 to L5.
actionone of "accept", "note", "review", "reject", "resubmit"No
reasonstring or nullNoThe finding or condition behind the level.
findingsarray of objectNoThe findings behind the level, each with the pages and embedded photos it refers to.
textobjectNoThe result for the document's text.
imagesarray of objectNoThe embedded photos and graphics, numbered in document order.
structureobject or nullNoThe edit history of the file, or null when it was not examined.
provenanceobjectNoWhat the file's own records say about its origin.
digeststringNoFingerprint of the report content, used by the verification page.

Retrieve, list and cancel

  • GET /analyses/{id} returns the analysis, with its result while it is kept.
  • GET /analyses lists analyses of the workspace, newest first. limit is 1 to 100 (default 20), type filters by image or document, and starting_after takes the previous page's next_cursor. List items never include result.
  • POST /analyses/{id}/cancel cancels a document analysis that is still processing and releases its charge. Image analyses cannot be canceled; a late or finished cancel returns not_cancelable.
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 report

GET /analyses/{id}/report.pdf downloads the sealed PDF report of a succeeded analysis while its result is kept. Add ?locale= with en, fr, de, es, zh, vi or ar (default en). Send the Authorization header; the response is application/pdf.

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

For documents, page images and text excerpts are kept for 3 hours after the check. After that the PDF omits them, and the response header x-evidence-included is false. Download the PDF when the analysis finishes if you need it to include the evidence.

Errors

CodeStatusCause
file_not_found400The file ID is unknown, expired or already used, or the upload to upload.url has not finished yet.
model_not_found404Unknown model.
invalid_parameter400A field is missing, mistyped or unknown. Text models belong to POST /text/detections.
unsupported_file, invalid_file415, 422The file format is not supported for the model, or the file is damaged.
file_too_large, too_many_pixels, too_many_pages, document_too_long413A size limit was exceeded.
password_required, wrong_password422The document is encrypted. Send options.password.
not_examinable422The document has nothing that can be examined. Not charged.
insufficient_balance, spend_limit_reached402The balance or the key's monthly limit cannot cover the price.
service_unavailable, analysis_failed503, 502A temporary failure or busy capacity. Not charged; retry. service_unavailable carries a retry-after header. See When the service is busy.
unsupported_media_type415The body is not sent as application/json.
idempotency_mismatch, idempotency_in_progress409The Idempotency-Key was used with a different body, or its first request is still running. See Idempotency.
not_cancelable409Only documents that are still processing can be canceled.

Some failures happen after the analysis is created, for example when a model cannot finish. They set status: failed and error on the analysis instead of failing the create call, and the analysis.failed webhook fires. See Errors.