Asynchronous validations
A validation queries the CEP at Banxico, and that wait belongs to an external service. The ?async=1 parameter decouples the two: the request enqueues the work and responds immediately, instead of holding the connection until Banxico answers.
POST /v1/validate?async=1
POST /v1/validate-ocr?async=1The response is 202 with the validation identifier, and no verdict yet:
{
"data": {
"type": "validation",
"id": "9f3c2a1b-4d5e-6f70-8192-a3b4c5d6e7f8",
"attributes": { "status": "queued", "expires_at": "2026-08-21T15:12:44Z" }
}
}The verdict is obtained by polling GET /v1/validations/{id} until the state is terminal.
States
| state | terminal | meaning |
|---|---|---|
queued | No | Enqueued, not processed yet |
processing | No | Under way against Banxico |
valid | Yes | The CEP exists and matches the submitted data |
not_found | Yes | Banxico holds no CEP matching that data |
cep_unavailable | Yes | Banxico identified the operation but did not deliver the receipt |
returned | Yes | The payment settled and the beneficiary institution later sent it back |
invalid | Yes | Banxico answered in a way the service does not recognize |
failed | Yes | The validation stopped because the submitted data was rejected; the reason travels in error_code |
error | Yes | Failure during processing; the reason travels in error_code |
Polling cadence
The poll response states when to ask again, so the client does not have to pick an interval:
| signal | content |
|---|---|
Retry-After | Suggested seconds until the next poll |
meta.next_poll_after_seconds | The same value, in the body, for clients that do not read headers |
ETag | Signature of the current state, shaped W/"{version}-{state}" |
The suggestion is 2 seconds on every poll; the server does not widen it. A terminal state stops emitting Retry-After: that is the signal to stop polling.
Conditional polling
The ETag changes on every state transition. Sending it back as If-None-Match lets a poll with no news resolve as a 304 with no body:
GET /v1/validations/9f3c2a1b-…
If-None-Match: W/"3-processing"A 304 means the state has not changed since the previous query. It is the cheap way to poll: the response carries no resource.
Expiry
An enqueued validation carries an expires_at. Past that deadline without reaching a terminal state, the validation is closed as expired (status error, error_code ttl_expired) and stops being processed. The value comes in the 202 response and allows capping the client's polling cycle.
Choosing between synchronous and asynchronous
Without ?async=1 the request returns the verdict in the same response, at the cost of holding the connection while Banxico answers. The asynchronous path fits high volumes, clients that cannot keep long connections open, or results processed later through webhooks.