Validation flow
Validation flows — what are they?
In Veriko, we define a "validation flow" as the process that takes the data of a SPEI transfer (as text or image) and searches whether Banxico issued a CEP or a transaction record with that data.
A validation always ends in a "terminal state" (see below).
Manual validation vs image-based (OCR)
- Manual (
POST /v1/validate): You must send the following data in plain text:clave_rastreo— Optional ifreferencia_numericais sent.cuenta_beneficiariamontofechaemisorreceptor— Optional ifcuenta_beneficiariais CLABE/Card.receptor_participante— Optional.0for an account holder (default) or1when the beneficiary is the receiving institution itself («Pago a Banco»).
Full guide at: Validate a SPEI transfer (manual)
- Image-based (OCR) (
POST /v1/validate-ocr): You must send an image (Base64) or a URL (https):image— Optional ifimage_urlis sent.image_url— Optional ifimageis sent.cuenta_beneficiaria,banco_emisor,banco_receptor— Optional. Only if they are not present in the image.
Full guide at: Validate a SPEI transfer from an image (OCR)
Sync vs async
By default both endpoints are synchronous: that is, the system holds the request until Banxico responds (the median is 3-5s; the recommended timeout is 30s).
If you need to close the connection sooner or set a shorter timeout, simply add ?async=1 to the URL as a GET parameter. Then:
- The endpoint instantly returns
202with avalidation_id, plus anETagandmeta.next_poll_after_seconds. - The system enqueues and begins processing the validation.
- You can poll
GET /v1/validations/{id}periodically to retrieve the validation's status (preferably sendingIf-None-Matchwith the last ETag seen). As long as the row does not transition, the server responds304 Not Modified; when thestatuschanges the ETag changes and the poll's body carries the final result.
Full detail at: Async validations.
Terminal states
Each row can resolve to one of these 7 values:
valid— CEP found. It is the only verdict that obtains the CEP and counts as "verified" for your finance (see CEP and Finance).not_found— No CEP or transaction found with that data.cep_unavailable— The transaction was found but not the CEP (typically not yet settled or there are delays in the banking system).returned— The payment settled and the beneficiary institution later sent it back. The CEP, if one exists, is still delivered.invalid— Banxico answered in a way the service does not recognize; not a problem with the submitted data.failed— The validation stopped because the submitted data was rejected; the reason travels inerror_code.error— Failure of the service or of Banxico during processing; the reason travels inerror_code.
Follow-up check of a valid
A valid is the verdict of the moment of the query. Banxico can report the return of the payment hours or days later; the validation then moves from valid to returned, keeps its CEP, and emits the validation.returned webhook. There are two ways to detect it:
- On demand:
POST /v1/validations/{id}/recheckqueries only the payment status. It consumes no quota, accepts one query every 10 minutes per validation, and only responds during the first 72 hours. - Automatic: the service rechecks the
validvalidations of the last 72 hours at 1 hour, 6 hours, 1 day, and 3 days of age.
Full detail at: CEP.
Keeping or deleting the receipt
The receipt file is kept by default. retain_image=false on POST /v1/validate-ocr deletes it when the validation reaches a terminal status and leaves the verdict and the extracted data. To permanently delete a validation and everything it left behind, POST /v1/validations/{id}/purge/prepare and POST /v1/validations/{id}/purge/execute leave it as a tombstone: no file, no CEP, and no extracted data, with its verdict, its dates, and its amount.
Full detail at: Retention of receipts and data.
Retries
A terminal row may enter a retry cycle when its outcome (terminal state) is one of these:
not_foundcep_unavailableerror
The account's default policy is set with PUT /v1/users/me/retry-policy, and a single validation is adjusted with PUT /v1/validations/{id}/retry-policy. It defines enabled, max_retries, interval_seconds, and the specific outcomes from the list.
Full detail at: Retry policy.
Idempotency-Key
The Idempotency-Key header is optional. It is handled as follows:
- New key → The request is processed normally, and the response is persisted for replays.
- Same body with a repeated key → The endpoint replays the stored response, with its same status code and the
Idempotent-Replayed: trueheader. - Different body with a repeated key → The endpoint responds
422 idempotency_key_reused. - Same key still processing → The endpoint responds
409 idempotency_key_in_progress.
Full detail at: Idempotency.