> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/buenas-practicas.md).

# Best practices

### Polling strategy

Check the status by phased polling, as the resolution time can vary significantly between transactions:

* **Phase 1 (fast polling, first \~10 seconds)**: poll every 1 second. Covers the usual case, where the transaction resolves quickly.
* **Phase 2 (exponential backoff, from \~10 seconds if there is still no terminal state)**: progressively increase the interval (e.g. 2s → 4s → 8s → 15s), with a cap of between 15 and 20 seconds between polls. Covers cases that require additional analysis and may take substantially longer.
* Define a maximum wait time on the consumer side (e.g. several minutes). If exceeded, treat the case as indeterminate and retry later or contact support.
* Do not assume a fixed response time: the duration can vary substantially between transactions, as some require additional internal analysis before being resolved.

### Status handling

* `COMPLETED`: read `diagnostic` and, if it is `DECLINED` or `DOUBTFUL`, `rejectionReason`/`diagnostics[]` to inform the end user. A `DOUBTFUL` is not a rejection: the analysis was not conclusive and the decision is yours (see [Service modes](/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation.md#modalidades-del-servicio)).
* `ERROR` / `FAILED`: treat as an integration or service error. Review the data sent and retry if appropriate.
* `FAILED` with `failureReason = Validation could not be completed`: transient processing failure (includes internal analysis timeouts). It is safe to retry by starting a new transaction with the same assets (see [Check status](/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/consultar-estado.md)). For the rest of the values of `failureReason`, consult its table in [Check status](/docs.facephi-en/rest-api/midapi-v2/document-services/document-validation/consultar-estado.md#failurereason).

### Security

* Do not store the OAuth2 Token on the client. Renew it according to its expiration (see [Authentication](/docs.facephi-en/rest-api/midapi-v2/autenticacion.md)).
* Use the same `operationId` Token in the asset upload and in the header `operation-id` of validation start: all the `fileKeys` of a request must belong to that same operation.
* Create the operation **when capture starts**, not before: it expires after 15 minutes by default, and an expired operation requires creating another one and uploading the assets again.
* Resend each `fileKey` as returned by `POST /storage`, without composing or interpreting it. If you need to recover them, use [Get File Keys](/docs.facephi-en/rest-api/midapi-v2/operations/get-file-keys.md).
* Treat `transactionId` as an opaque identifier. Do not infer information from its format.

### Traceability for support

To investigate a specific case with support, keep and provide the following identifiers:

* **`transactionId`**: main transaction identifier (returned by `POST /document/validate` and in each status check). It is the key data to locate a case.
* **Response header `X-Trace-Id`**: request identifier returned by the API in each response; it allows support to correlate the exact call. Recommended to store it together with the `transactionId`.
* **`timestamp`** of the transaction (ISO-8601 format) and the identifiers you provide in the headers: `operation-id` and `consumer-id`.

When opening a ticket, always include the `transactionId` (and the `X-Trace-Id` if you have it recorded). Check with Facephi the retention periods applicable to your Integration.
