--- title: "Requesting NIGO Results" slug: "requesting-nigo-results" description: "Validate document uploads with OneSpan Sign's NIGO Attachment Validation, ensuring compliance and integrity checks for a seamless signing experience." updated: 2026-11-05T19:41:27Z published: 2026-11-05T19:41:27Z canonical: "docs.onespan.com/requesting-nigo-results" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.onespan.com/llms.txt > Use this file to discover all available pages before exploring further. # Requesting NIGO Results Which checks run, and against which fields, depends entirely on the document type: | Document type | Data completeness requires | Date check | | --- | --- | --- | | Passport | fullName, dateOfBirth, expiryDate | Expiry on expiryDate | | Driver's License | fullName, dateOfBirth, expiryDate, address | Expiry on expiryDate | | Bank Statement | accountHolderName, financialInstitutionName, statementDate | Recency on statementDate, 6 months | | Utility Bill | fullName, address, providerName, billDate | Recency on billDate, 6 months | | Tax Return | fullName, taxYear, totalIncome | — | | Pay Stub | fullName, employerName, payDate, netPay | Recency on payDate, 6 months | | Invoice | invoiceDate, vendorName, totalAmount | Recency on invoiceDate, 12 months | | Contract | contractTitle, partyName1, effectiveDate | — | | T4 Slip (CA) | employeeName, employerName, taxYear, employmentIncome | Tax year recency on taxYear, 2 years | | State ID Card (US) | fullName, dateOfBirth, expiryDate, idNumber | Expiry on expiryDate | | Void Cheque (CA) | accountHolderName, bankName, accountNumber, transitNumber, institutionNumber | — | | Void Cheque (US) | accountHolderName, bankName, accountNumber, routingNumber | — | | Auto Insurance Certificate | policyHolder, insurer, policyNumber, coverageStart, coverageEnd | Coverage period | | Property Insurance | policyHolder, propertyAddress, insurer, policyNumber, coverageStart, coverageEnd | Coverage period | | Life Insurance Policy | policyOwnerName, insuredName, insurer, policyNumber, issueDate | Recency on issueDate, 10 years | | Vehicle Registration | ownerName, vin, licensePlate, registrationExpiry | Expiry on registrationExpiry | | Employment Letter | employeeName, employerName, jobTitle, letterDate | Recency on letterDate, 3 months | ## Requesting validation Both settings live on an attachment requirement, which is nested inside a role. Set them when you create or update the role, or when you create the package. | Field | Type | Default | Effect | | --- | --- | --- | --- | | attachmentType | string enum | null | The expected document type. **Setting it is what enables classification for this requirement.** | | extractionEnabled | boolean | null (off) | Enables field extraction and the content verification checks for this requirement. Has no effect unless attachmentType is also set. | ```json {  "id": "role1",  "type": "SIGNER",  "signers": [    { "email": "jane@example.com", "firstName": "Jane", "lastName": "Doe" }  ],  "attachmentRequirements": [    {      "id": "attachment-1",      "name": "Proof of address",      "description": "Upload a recent bank statement",      "required": true,      "attachmentType": "BANK_STATEMENT",      "extractionEnabled": true    }  ] } ``` `POST` or `PUT` this to `/aws/rest/services/packages/{packageId}/roles[/{roleId}]`, or include it in the package creation payload. `extractionEnabled` is a nullable boolean: `null` and `false` are equivalent, and both mean off. It is nullable so that an omitted field can never accidentally enable extraction — only an explicit `true` does. ### Validation errors The request is rejected if you ask for something the account is not entitled to: | Condition | Error | | --- | --- | | attachmentType is set and the DocInsight release flag is off for the account | error.validation.role.releaseFlagDocInsightIsDisabled — *"Release flag DocInsight is disabled."* | | attachmentType is set and the account feature Attachment Classification is off | error.validation.role.attachmentClassificationIsDisabled — *"Attachment classification feature is disabled."* | | extractionEnabled is true and the account feature Attachment Data Extraction is off | error.validation.role.attachmentDataExtractionIsDisabled — *"Attachment data extraction feature is disabled."* | Tamper detection has no per-requirement field. It is controlled solely by the account-level Document Authenticity setting, and applies to every eligible attachment on the account. ## Retrieving results ```http GET /aws/rest/services/packages/{packageId}/attachment/verifications ``` Note that the path segment is `attachment`, singular. | Response | Meaning | | --- | --- | | 200 OK | A bare JSON array of validation results, one element per uploaded attachment file | | 204 No Content | No results exist for this transaction | The response is a **bare array**, not an object with a named field. There is no pagination. **This endpoint requires transaction edit privileges** — sender, owner or delegate. Signers receive `403`. Validation results are not exposed anywhere in the signer-facing API. **Classification is synchronous; extraction is asynchronous.** Classification completes during the upload, so `classificationResult` is available as soon as the upload returns. Extraction runs afterwards, and its result appears at this endpoint once it completes — until then the file's element reports `extractionStatus: "NOT_PERFORMED"` with a `null` `reasonCode` and no `extractionResult`. Results are assembled on each request: the extraction result is fetched from the validation service and the content checks are evaluated at that moment, so read this endpoint when you need current results rather than caching it. ### Detecting completion Extraction is asynchronous, no event announces its completion (see [Callbacks and events](/docs/requesting-nigo-results#callbacks-and-events)), and `PACKAGE_ATTACHMENT` fires before it finishes — so a client that needs extraction results has to re-read this endpoint until each file reaches a final state. **This endpoint is not rate limited, so limit yourself.** Every call fetches the current extraction result for every validated file on the transaction from the validation service and re-evaluates the content checks. Do not loop tightly. Recommended: start on the `PACKAGE_ATTACHMENT` callback (per upload) or on `SIGNER_COMPLETE` (once the signer is done), re-read **no more than once every 10 seconds per transaction** — one call covers all of the transaction's files — and **stop after 5 minutes**, treating any file still without a final state as unavailable. These are recommendations, not measured limits: there is no published bound on extraction time. Decide per file, on each read: | Element state | Action | | --- | --- | | The file is absent from the array | Stop. It was never validated and will not appear later — see ["No results" states](/docs/requesting-nigo-results#no-results-states) | | extractionStatus is COMPLETED | Done | | extractionStatus is FAILED | Stop. Terminal — see reasonCode | | extractionStatus is NOT_PERFORMED and reasonCode is not null | Stop. Terminal, and the reason code says why | | extractionStatus is NOT_PERFORMED and reasonCode is null | Apply the decision tree under [reasonCode](/docs/requesting-nigo-results#reasoncode). Keep reading only if it lands on its last branch, until your time limit | If you only need the classification, there is nothing to wait for. ### Response shape Each array element: | Field | Type | Notes | | --- | --- | --- | | attachmentUuid | string | The id of the attachment requirement the file was uploaded against | | fileName | string | **Base name only — the extension is stripped.** To reconstruct the original filename, join fileName and extension with a dot (no dot when extension is empty). To match an element to an uploaded file, prefer fileId | | fileId | string | The file's id, as a string. It equals files[].id on the attachment requirement (an integer there) — the reliable key for matching an element to an uploaded file, whose files[].name carries the original filename | | extension | string | The file extension, without a leading dot | | classificationResult | object or null | What the document was detected as. null if the stored result could not be read | | extractionResult | object or null | Extracted fields, checks and integrity findings. null whenever extraction did not produce a result | | extractionStatus | string enum | COMPLETED, NOT_PERFORMED or FAILED. Never null | | reasonCode | string enum or null | Why extraction did not complete. **Can be null even when extractionStatus is NOT_PERFORMED** | | typeMatch | boolean | Whether the detected type matched what you asked for at high confidence — which is also the condition for extraction to be performed. **It does not tell you whether extraction has completed** — see below | `classificationResult`: | Field | Type | Notes | | --- | --- | --- | | documentUuid | string | The internal validation id for this file | | documentType | string or null | The detected type. null when classification failed | | confidenceScore | number | 0.0 when classification failed | | confidenceLevel | string or null | HIGH, MEDIUM or LOW. null when classification failed | | providerName | string or null | | | failed | boolean | Always present, always a boolean. **Check this before reading any other field on this object** | | errorCode | string or null | A translation key describing the problem. Populated only when failed is true | | failureMessage | string or null | | `extractionResult`: | Field | Type | Notes | | --- | --- | --- | | documentUuid | string | | | extractedFields | object | String-to-string map. **Sparse** — see below. Empty unless extraction completed | | providerName | string or null | | | verificationCheckResults | array | The content check results. Empty unless extraction completed | | extractionStatus | string enum | Same as the element-level value | | reasonCode | string enum or null | Same as the element-level value | | failureMessage | string or null | | | preflight | object or null | Document integrity findings. Integrity analysis runs at the start of extraction, before fields are extracted, so this is present on an extraction that was submitted and then failed as well as on a completed one. It is never produced when extraction was not submitted — in those cases extractionResult itself is null, and there are no findings to read | | failed | boolean | Derived: true whenever extractionStatus is not COMPLETED | **Which** `extractionStatus` **and** `reasonCode` **to read.** Both appear twice — on the array element and inside `extractionResult`. Read the element-level ones: they are always present. When `extractionResult` is non-null, its `extractionStatus` and `reasonCode` are identical to the element's (the element copies them from it), and its `failed` is simply `extractionStatus` not being `COMPLETED`. When `extractionResult` is `null`, the element-level fields are the only ones, and say why there is no result. One edge case: if the validation service ever reports a status this release does not know, the nested value is `null` and the element reports `NOT_PERFORMED`. **Null fields are present in the JSON, not omitted.** Do not treat the presence of a key as evidence that it has a value. Conversely, new fields may be added in later releases — ignore keys you do not recognise. `typeMatch` **says whether extraction was eligible, not whether it has completed.** It is `true` only when `classificationResult.documentType` equals your requested `attachmentType` **and** `confidenceLevel` is `HIGH` — and extraction is only performed under exactly those conditions. So `typeMatch: false` means no extraction result will ever exist for this file, for one of two reasons that `reasonCode` tells apart: a different `documentType` was detected (the wrong document — extraction was never submitted, and `reasonCode` stays `null`), or the right `documentType` was detected at `MEDIUM` or `LOW` confidence (extraction was submitted and declined, and `reasonCode` is `CLASSIFICATION_QUALITY_WARNING` with `classificationResult.failed: false`). Conversely `typeMatch: true` only means extraction was submitted — read `extractionStatus` to know whether it has completed. ### Example — a successful result ```json [  {    "attachmentUuid": "attachment-1",    "fileName": "statement-june",    "fileId": "8842",    "extension": "pdf",    "classificationResult": {      "documentUuid": "9f2c1d84-3b7e-4a15-9c2d-6e8f1a4b7c30",      "documentType": "BANK_STATEMENT",      "confidenceScore": 0.95,      "confidenceLevel": "HIGH",      "providerName": "bedrock",      "failed": false,      "errorCode": null,      "failureMessage": null    },    "extractionResult": {      "documentUuid": "9f2c1d84-3b7e-4a15-9c2d-6e8f1a4b7c30",      "extractedFields": {        "accountHolderName": "JANE DOE",        "financialInstitutionName": "Bank of Example",        "statementDate": "2026-06-30",        "statementPeriodStart": "2026-06-01",        "statementPeriodEnd": "2026-06-30"      },      "providerName": "bedrock",      "verificationCheckResults": [        {          "ruleName": "data_completeness",          "fields": [],          "status": "PASS",          "message": "esl.error.attachment_verification_check.data_completeness_pass"        },        {          "ruleName": "date_validation",          "fields": ["statementDate"],          "status": "PASS",          "message": "esl.error.attachment_verification_check.date_recent"        }      ],      "extractionStatus": "COMPLETED",      "reasonCode": null,      "failureMessage": null,      "preflight": {        "checks": [          {            "check": "SOURCE",            "status": "PASS",            "messageKey": "esl.error.preflight_check.source_verified",            "params": {}          },          {            "check": "EDITS_AFTER_CREATION",            "status": "PASS",            "messageKey": "esl.error.preflight_check.no_edits_after_creation",            "params": {}          },          {            "check": "FILE_DATES",            "status": "PASS",            "messageKey": "esl.error.preflight_check.file_dates_consistent",            "params": {}          },          {            "check": "PERIOD_DATE",            "status": "PASS",            "messageKey": "esl.error.preflight_check.period_date_within",            "params": {}          }        ],        "verifiability": { "inputType": "VERIFIABLE_PDF" },        "tier": "CLEAR"      },      "failed": false    },    "extractionStatus": "COMPLETED",    "reasonCode": null,    "typeMatch": true  } ] ``` ### Example — the file could not be classified ```json [  {    "attachmentUuid": "attachment-1",    "fileName": "photo",    "fileId": "8843",    "extension": "jpg",    "classificationResult": {      "documentUuid": "1a4b7c30-9f2c-4a15-8e6d-3b7e5c2d9f10",      "documentType": null,      "confidenceScore": 0.0,      "confidenceLevel": null,      "providerName": null,      "failed": true,      "errorCode": "esl.error.attachment_verification.image_too_blurry",      "failureMessage": "Document is difficult to read"    },    "extractionResult": null,    "extractionStatus": "NOT_PERFORMED",    "reasonCode": "CLASSIFICATION_QUALITY_WARNING",    "typeMatch": false  } ] ``` ## Document types and extraction fields The following document types are supported. The **Extraction fields** column lists every key that can appear in `extractedFields` for that type. Keys marked **(date)** are returned in ISO `YYYY-MM-DD` form; every other value is returned as printed on the document. | attachmentType | Label | Extraction fields | | --- | --- | --- | | PASSPORT | Passport | fullName, dateOfBirth (date), expiryDate (date), issuingCountry, documentNumber | | DRIVERS_LICENSE | Driver's License | fullName, dateOfBirth (date), expiryDate (date), address, issuingCountry, licenseNumber, issuingState | | BANK_STATEMENT | Bank Statement | accountHolderName, financialInstitutionName, statementDate (date), address, statementPeriodStart (date), statementPeriodEnd (date) | | UTILITY_BILL | Utility Bill | fullName, address, providerName, billDate (date), utilityType | | TAX_RETURN | Tax Return | fullName, taxYear, netIncome, totalIncome, address, formType | | PAY_STUB | Pay Stub | fullName, employerName, payPeriodEndDate (date), payDate (date), netPay, grossPay, employeeAddress, payFrequency, ytdGrossPay, ytdNetPay | | INVOICE | Invoice | invoiceNumber, vendorName, invoiceDate (date), totalAmount | | CONTRACT | Contract | contractTitle, partyName1, partyName2, effectiveDate (date), endDate (date) | | T4_SLIP_CA | T4 Slip (CA) | employerName, employerAddress, employeeName, employeeAddress, taxYear, employmentIncome, incomeTaxDeducted, provinceOfEmployment | | STATE_ID_CARD_US | State ID Card (US) | fullName, dateOfBirth (date), expiryDate (date), address, idNumber, issuingState | | VOID_CHEQUE_CA | Void Cheque (CA) | accountHolderName, bankName, accountNumber, transitNumber, institutionNumber | | VOID_CHEQUE_US | Void Cheque (US) | accountHolderName, bankName, accountNumber, routingNumber | | AUTO_INSURANCE_CERTIFICATE | Auto Insurance Certificate | policyHolder, insurer, policyNumber, coverageStart (date), coverageEnd (date), vin, vehicleMake, vehicleModel, vehicleYear, licensePlate | | PROPERTY_INSURANCE | Property Insurance | policyHolder, propertyAddress, insurer, policyNumber, coverageStart (date), coverageEnd (date) | | LIFE_INSURANCE_POLICY | Life Insurance Policy | policyOwnerName, insuredName, insurer, policyNumber, issueDate (date) | | VEHICLE_REGISTRATION | Vehicle Registration | ownerName, ownerAddress, vehicleMake, vehicleModel, vehicleYear, vin, licensePlate, registrationExpiry (date), stateOrProvince | | EMPLOYMENT_LETTER | Employment Letter | employeeName, employerName, employerAddress, jobTitle, startDate (date), compensation, letterDate (date) | | INDIGENOUS_IDENTITY_DOCUMENT | Indigenous Identity Document (CA) | fullName, dateOfBirth (date), expiryDate (date), issuingCountry | Two fields are constrained to a fixed set of values: - `utilityType` — one of `electric`, `gas`, `water`, `internet`, `mobile`, `other` - `payFrequency` — one of `weekly`, `bi-weekly`, `monthly`, `undefined` `taxYear` is a **plain string**, not a date. It is returned as printed on the document. Note that classification can report a document as an unrecognised type, in which case `documentType` is `"UNKNOWN"`. `UNKNOWN` is not a valid `attachmentType` and cannot be requested. ## Handling extracted fields `extractedFields` **is sparse.** It contains only the keys that were actually found and legible. A field that was absent from the document, unreadable, or that the extractor declined to guess at is **omitted from the map entirely** — it is not returned as `null` or as an empty string. This applies to every key, including the ones the checks require. Your code must handle **any** key being missing, and must not assume that every key listed for a document type will be present in every response. All values are strings. - **Dates** are normalized to ISO `YYYY-MM-DD`. This normalization is performed by the extractor and constrained by its output schema, but it is not re-validated afterwards. Treat a well-formed ISO date as the expected case, and handle a value that does not parse rather than assuming it will. - **Monetary amounts** are returned exactly as printed — for example `"65000.00"`, `"$75,000 per year"`, or `"120,000 00"`. They are not normalized to numbers. Parse them yourself, defensively. - **Everything else** is returned as printed on the document. Extracted data is produced by the validation service and surfaced through this endpoint. **It is not editable through the API**, and there is no endpoint to correct or override an extracted value. ## Verification check results `extractionResult.verificationCheckResults` is an array of check results, present only when extraction completed. Each element: | Field | Type | Notes | | --- | --- | --- | | ruleName | string | Which check this is | | fields | array of strings | The extracted field names this check looked at. For a data_completeness failure this is the list of **missing** fields | | status | string enum | PASS, WARNING or FAIL | | message | string | A translation key describing the specific outcome | There are four checks. Which of them run, and against which fields, is determined entirely by the document type. | ruleName | Purpose | Outcomes and message keys | | --- | --- | --- | | data_completeness | The fields that matter for this type were found and are non-blank | PASS → …_check.data_completeness_pass, with fields: []. FAIL → …_check.data_completeness_missing, with fields listing what is missing | | date_validation | A date is not expired (EXPIRY) or is recent enough (RECENCY) | PASS → …_check.date_valid or …_check.date_recent. FAIL → …_check.date_expired or …_check.date_too_old. WARNING → …_check.date_not_available (field absent or blank) or …_check.date_parse_error (value not a parseable ISO date) | | coverage_period | Today falls inside an insurance coverage window | PASS → …_check.date_valid. FAIL → …_check.date_expired (coverage ended). WARNING → …_check.coverage_not_started, …_check.date_not_available, or …_check.date_parse_error | | tax_year_recency | A tax year is recent enough | PASS → …_check.date_recent. FAIL → …_check.date_too_old. WARNING → …_check.date_not_available (absent, non-numeric, before 2000, or later than the current year) | All message keys are prefixed `esl.error.attachment_verification_check.` A missing or unparseable date always produces `WARNING`, never `FAIL`. Only a date that was read successfully and found to be out of range produces `FAIL`. Do not treat `WARNING` as a soft failure of the document — in most cases it means the check could not be performed. Per-type configuration: | attachmentType | data_completeness requires | Date check | | --- | --- | --- | | PASSPORT | fullName, dateOfBirth, expiryDate | date_validation EXPIRY on expiryDate | | DRIVERS_LICENSE | fullName, dateOfBirth, expiryDate, address | date_validation EXPIRY on expiryDate | | BANK_STATEMENT | accountHolderName, financialInstitutionName, statementDate | date_validation RECENCY on statementDate, 6 months | | UTILITY_BILL | fullName, address, providerName, billDate | date_validation RECENCY on billDate, 6 months | | TAX_RETURN | fullName, taxYear, totalIncome | — | | PAY_STUB | fullName, employerName, payDate, netPay | date_validation RECENCY on payDate, 6 months | | INVOICE | invoiceDate, vendorName, totalAmount | date_validation RECENCY on invoiceDate, 12 months | | CONTRACT | contractTitle, partyName1, effectiveDate | — | | T4_SLIP_CA | employeeName, employerName, taxYear, employmentIncome | tax_year_recency on taxYear, 2 years | | STATE_ID_CARD_US | fullName, dateOfBirth, expiryDate, idNumber | date_validation EXPIRY on expiryDate | | VOID_CHEQUE_CA | accountHolderName, bankName, accountNumber, transitNumber, institutionNumber | — | | VOID_CHEQUE_US | accountHolderName, bankName, accountNumber, routingNumber | — | | AUTO_INSURANCE_CERTIFICATE | policyHolder, insurer, policyNumber, coverageStart, coverageEnd | coverage_period on coverageStart / coverageEnd | | PROPERTY_INSURANCE | policyHolder, propertyAddress, insurer, policyNumber, coverageStart, coverageEnd | coverage_period on coverageStart / coverageEnd | | LIFE_INSURANCE_POLICY | policyOwnerName, insuredName, insurer, policyNumber, issueDate | date_validation RECENCY on issueDate, 10 years | | VEHICLE_REGISTRATION | ownerName, vin, licensePlate, registrationExpiry | date_validation EXPIRY on registrationExpiry | | EMPLOYMENT_LETTER | employeeName, employerName, jobTitle, letterDate | date_validation RECENCY on letterDate, 3 months | Note that `data_completeness` requires some fields the extractor treats as optional — `payDate` on a pay stub and `totalIncome` on a tax return are examples. A `data_completeness` failure naming those fields means they were not found on the document, not that something went wrong. ### "No results" states | Situation | What you see | | --- | --- | | No attachment requirement on the transaction has an attachmentType | 204 No Content | | The DocInsight release flag is off for the account | 204 No Content | | The account feature Attachment Classification is off | 204 No Content | | The validation service was unreachable when the file was uploaded | The file is **absent from the array, permanently**. Classification runs once, at upload; if it could not run, no result is ever recorded for that file and it will not appear later. Other files may still appear | | The stored classification could not be read | The element is present with classificationResult: null | An empty result is never an error. `204` means nothing has been validated on this transaction, which is the normal state for a transaction that does not use the feature. **Reconcile this array against the files you know were uploaded.** Every uploaded file is listed in `attachmentRequirements[].files[]` on the role. A file in that list but absent from this array was never validated — the service was unreachable when it was uploaded, or validation was not configured for its requirement at the time. Treat that as an explicit *not validated* state and surface it as such: re-reading this endpoint will not change it, and the only way to validate the file is for the signer to replace it. Do not confuse it with a file that is present with `extractionStatus: NOT_PERFORMED` and a `null` `reasonCode` — resolve that one with the decision tree under `reasonCode`. ## Mark as Reviewed through the API ```http PUT    /aws/rest/services/packages/{packageId}/attachment/{attachmentId}/file/{fileId}/reviewed DELETE /aws/rest/services/packages/{packageId}/attachment/{attachmentId}/file/{fileId}/reviewed ``` `PUT` marks the file as reviewed; `DELETE` undoes it. Neither takes a request body. Both return `200` with the updated `AttachmentFile`, and both require transaction edit privileges. A `fileId` that does not belong to the given `attachmentId` returns `404 error.validation.AttachmentFileNotFound`. The API field name is `reviewed`, and the feature is **Mark as Reviewed**; the audit trail records it as *Mark as Verified*. For what the action means and does not do — always available, never re-runs or clears results, never notifies the signer — see [Mark as Reviewed](/v1/docs/nigo#mark-as-reviewed) in the Sender UI topic. Five fields on `AttachmentFile` carry the state. They are also returned on `AttachmentRequirement.files[]` wherever a role or package is read, so you can see review state without calling the verifications endpoint: | Field | Type | Notes | | --- | --- | --- | | reviewed | boolean | | | reviewedBy | string | The id of the user who marked it reviewed | | reviewedAt | timestamp | | | unreviewedBy | string | The id of the user who undid it | | unreviewedAt | timestamp | | - Marking sets `reviewed`, `reviewedBy` and `reviewedAt`, and **clears** `unreviewedBy` and `unreviewedAt`. - Undoing sets `reviewed` to `false` and records `unreviewedBy` and `unreviewedAt`, while **preserving** the original `reviewedBy` and `reviewedAt` as history. - Undoing a file that was never marked, or is already unmarked, is a no-op that returns the current state. - Replacing or deleting a file discards its review state. ## Audit trail Marking a file as reviewed and undoing it produce the audit entries `Mark as Verified` and `Undo Verification` — the audit-trail names for those actions — alongside the existing `Upload File Attachment` and `Download File Attachment`, all retrievable from `GET /aws/rest/services/packages/{packageId}/audit`. **No classification outcome, extracted value, verification check result or integrity finding produces an audit entry** — if you need a durable record of what validation reported at a point in time, capture it from the verifications endpoint yourself. ##