Skip to main content

POST /api/v1/fraud-verify

Checks one document — a PDF or an image — for signs that it was edited after it was issued, fabricated, or submitted before, and returns a verdict: trusted, review or suspect.

A verdict never rejects a document by itself. It tells you whether a person should look before you rely on it. What each check and signal means is described in Fraud Detection.

Detect an edited payslip with the Cogneris fraud verification API Watch on YouTube

Endpoint​

POST https://api-eu.cogneris.ai/api/v1/fraud-verify
POST https://api-eu.cogneris.ai/api/v1/fraud-verify

Before You Call It​

  • Your tenant must allow fraud detection. A tenant administrator turns it on in Tenant agent settings › Guards (see Turn it on). Until then the call answers 403 fraud.not_enabled and nothing is charged.
  • The key needs the fraud-verify.write scope. A key with full access (*) holds it.
  • Production keys only. A sandbox key (xtkt_test_) is refused with environment.sandbox_route_unavailable.

Authentication​

Authorization: Bearer xtkt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Request​

Content-Type: multipart/form-data

FieldTypeRequiredDescription
filefile✅The document, as you received it. PDF or image, up to 10 MB.
sensitivitystringlow, medium or high: how readily signals become review and suspect. Default: the sensitivity saved on templateId, otherwise medium.
templateIdUUIDA template whose saved fraud settings supply the default sensitivity.
reusebooleanDefault true: if the same file was analysed at the same sensitivity in the last 24 hours, that analysis is returned with reused: true, free of charge. Send false to always run a new one.
fieldsstringA JSON object with values you already extracted from this document, e.g. {"cpf":"123.456.789-09","issueDate":"2026-02-30"}. Adds the field-consistency checks (tax ids, dates, amounts). Without it, only the file is checked.
Send the original file

The checks read the file exactly as you send it. Re-saving a PDF, or printing it to a new PDF, erases the edit history several checks look for — send the file as it reached you.

Constraints

  • Max size: 10 MB.
  • Rate limit: 50 requests per API key per fixed 1-minute window.
  • Synchronous: the analysis comes back in the response.

Example​

curl --fail-with-body \
--request POST \
--header "Authorization: Bearer $COGNERIS_API_KEY" \
--form "file=@./payslip.pdf" \
--form "sensitivity=medium" \
--form 'fields={"cnpj":"11.222.333/0001-81","netPay":"3450.00"}' \
"https://api-eu.cogneris.ai/api/v1/fraud-verify"

Response​

200 OK — the standard service envelope.

{
"data": {
"requestId": "3f0c2a54-6b1e-4c39-9d0e-2a7b6c1d9e10",
"verdict": "review",
"riskScore": 0.42,
"aiGeneratedLikelihood": 0.08,
"policyAction": "allow",
"pipelineVersion": "fraud-c-1",
"reused": false,
"signals": [
{
"code": "pdf_incremental_updates",
"label": "PDF edited after it was created",
"severity": "medium",
"score": 0.5,
"evidence": "document contains more than one %%EOF marker (incremental update / re-save)"
}
],
"checks": [
{ "name": "semantic", "status": "clear", "signals": [] },
{
"name": "pdf_structure",
"status": "flagged",
"signals": [
{
"code": "pdf_incremental_updates",
"label": "PDF edited after it was created",
"severity": "medium",
"score": 0.5,
"evidence": "document contains more than one %%EOF marker (incremental update / re-save)"
}
]
},
{ "name": "image_ela", "status": "clear", "signals": [] },
{ "name": "c2pa_provenance", "status": "clear", "signals": [] },
{ "name": "pdf_signature", "status": "clear", "signals": [] }
],
"failedCoverage": []
},
"meta": { "httpStatusCode": 200, "messages": [], "creditsConsumed": 8 },
"hasErrors": false
}
FieldTypeDescription
requestIdUUIDId of the analysis. Read it back with GET /api/v1/fraud-verify/{requestId}.
verdictstringtrusted, review or suspect.
riskScorenumber 0–1The combined score the verdict was taken from.
aiGeneratedLikelihoodnumber 0–1A model's estimate that the text reads as machine-generated. One input of the score, never a verdict.
policyActionstringallow, flag or block: your tenant's enforcement setting applied to the verdict. block means "do not proceed without a person"; it is not a rejection. Always allow in advisory mode.
pipelineVersionstringVersion of the checks that produced the analysis.
reusedbooleantrue when an earlier analysis of the same file was returned. Nothing was charged.
signals[]arrayEvery signal raised: code, label (plain English), severity (low | medium | high), score (0–1) and evidence. Score-0 signals are informational.
checks[]arrayEvery check that ran, in order, with status clear, flagged or failed and the signals it raised.
failedCoverage[]array of stringChecks that could not run on this document. A check that did not run never counts as clear.

meta.creditsConsumed is 8 for a new analysis and 0 when reused is true.

Deciding what to do​

verdictSuggested handling
trustedContinue.
reviewSend the document to a person before relying on it.
suspectHold the decision; a person must look.

Also route to a person when failedCoverage is not empty and the document matters: the checks listed there did not run.

GET /api/v1/fraud-verify/{requestId}​

Reads an analysis back. It also reads the analysis of a document checked during an extraction or a workflow — use the extraction's fraudRequestId. Requires the fraud-verify.read scope.

curl --fail-with-body \
--header "Authorization: Bearer $COGNERIS_API_KEY" \
"https://api-eu.cogneris.ai/api/v1/fraud-verify/3f0c2a54-6b1e-4c39-9d0e-2a7b6c1d9e10"

The response has the same shape as above; reused is always false. 404 fraud.not_found when there is no analysis with this id in your tenant.

Errors​

StatuscodeMeaning
400request.validation_failedNo file, a file over 10 MB or of an unsupported type, an unknown sensitivity, or fields that is not a JSON object.
403fraud.not_enabledYour tenant has not enabled fraud detection. Nothing ran; nothing was charged.
403fraud.scope_requiredThe key lacks fraud-verify.write (or fraud-verify.read for the read).
403environment.sandbox_route_unavailableA sandbox key.
404fraud.not_foundThe read found no analysis with this id.
503fraud.unavailableThe analysis could not complete. Retryable; nothing was charged. Not a trusted result.

See API errors for 401, 413, 415 and 429.