Retention of receipts and data
A validation by image or PDF leaves three different things behind, and each has its own retention rule:
| what | where it lives | how long it is kept |
|---|---|---|
| The receipt file | File storage | Five years from upload, unless something else is requested with retain_image or with the permanent deletion |
| The CEP | The XML in the database and the PDF in files | As long as the validation exists |
| The extracted data and the Banxico result | Database | As long as the validation exists |
Withdrawing a validation with DELETE /v1/validations/{id} changes none of this: it only removes it from the history. Two operations do change what is kept, and each answers a different need.
Not keeping the file: retain_image
retain_image is an optional parameter of POST /v1/validate-ocr, true by default. With false, the file is deleted as soon as the validation reaches a terminal status in which it is no longer needed. It applies the same with ?async=1.
Everything else is kept: the verdict, the CEP, and the extracted data. What changes:
- The validation publishes
image_retained=falseand stops publishingimage_path. GET /v1/validations/{id}/imageresponds410 image_not_retained, a code of its own instead of a generic404.
The file exists while the validation is processed, because the background job reads it. The deletion waits in only one case: a CEP in PDF with an open retry cycle, because each retry compares the PDF's seal against the official CEP again. When that cycle closes, as resolved, exhausted, or cancelled, the file is deleted. An image waits for nothing. A follow-up check of a valid does not read the file.
If you activate retries after the file was already deleted, the retry keeps querying Banxico with the stored data and skips the seal comparison (banxico_result._cep_upload).
Permanently deleting a validation
The permanent deletion is what DELETE /v1/validations/{id} does not do: it deletes the content, not just the history entry. It takes two steps, with the same prepare-and-execute pattern with a confirmation token that the destructive administration operations use:
POST /v1/validations/{id}/purge/preparesays what would be deleted and what would be kept, warns that it is irreversible, and issues a single-use token, bound to the account and to that validation, valid for 120 seconds. It changes nothing.POST /v1/validations/{id}/purge/executeverifies the token and deletes.
Your own validations in a terminal status are accepted, including those you already withdrew from the history. A validation in progress responds 409 purge_validation_in_progress; one already purged, 410 validation_purged; one that is not yours, 404 not_found. An open retry cycle does not prevent it: the deletion cancels it.
What is deleted:
- The receipt file and the CEP, as XML and as PDF.
request_data,ocr_result,banxico_result, and the normalization warnings. Ofnormalized_data, only the amount is kept.- The derived records with personal data: retry attempts, account probes, stored
Idempotency-Keyresponses, inbox notifications, and the content of the notifications sent. - The sent body and the receiver response in the webhook deliveries of that validation. The record of each delivery is kept.
- The bodies of the audit rows that name the validation and the free-form context of its security events, which is reduced to ids and codes.
client_ref, because it is free text that can carry personal data.
What is left: the tombstone
The validation does not disappear: it is left as a tombstone with the strict minimum for quota, statistics, finance, and history to keep adding up.
| kept | deleted |
|---|---|
id, validation_type, status, banxico_status | The file, the CEP, and banxico_result |
created_at, completed_at, deleted_at, purged_at | request_data and ocr_result |
processing_time_ms and error_code | client_ref and normalization_warnings |
The amount, in normalized_data.monto | The rest of normalized_data |
GET /v1/validations/{id} responds with the tombstone with 200 and purged_at. The image, the CEP, the retries, and the follow-up check respond 410 validation_purged, and webhooks, retries, and sweeps ignore it.
The deletion does not refund quota or change what was charged, and the finance totals and the list statistics do not change. What does disappear from a report is the breakdown that depends on the deleted data: the validation no longer counts by beneficiary, by bank, or by counterparty, and the statement shows it without a tracking key or accounts.
What the deletion does not reach
The deletion is irreversible and covers what the platform stores about that validation, but some things are outside its reach:
- Infrastructure backups are not altered. They keep a copy until their backup cycle retires it.
- The global account catalog keeps no link to the validation: an account that a CEP confirmed entered it on its own, by account number, not by the validation, and the deletion does not touch it. What your account contributed to the catalog is removed when your account is deleted.
- The server log files are rotated separately and are not redacted.
- What already went out cannot be recovered: the webhooks your endpoint received, the Telegram messages, and what was sent to a third party to read the receipt.
- Other validations with the same receipt are not touched. Each keeps its own copy of what was extracted and is deleted separately.
purge/preparelists their identifiers insame_image_validation_ids. - Audit rows from before version 1.61.0 do not mention the validation they created and cannot be linked to it.
- Files that could not be deleted at the moment: the deletion responds
file_removal: pending, the tombstone keeps their path without serving it, and the daily receipts sweep finishes them.
How to do it, step by step: Permanently delete a validation.