https://api.veriko.mx/v1/validate Validar una transferencia SPEI (directa)
Guía de uso →Valida una transferencia SPEI contra el CEP de Banxico usando los campos proporcionados: fecha, monto, clave de rastreo, referencia numérica, banco emisor, banco receptor y cuenta beneficiaria. Devuelve un veredicto con estado valid, not_found, cep_unavailable o error. Usa ?async=1 para encolar la operación y recibir 202 inmediato; sondea GET /v1/validations/{id} hasta el estado terminal. Diferencia clave con POST /v1/validate-ocr: este endpoint recibe campos explícitos; el OCR acepta imagen de comprobante e infiere los campos automáticamente. Acepta Idempotency-Key opcional para evitar duplicados en reintentos de red. Si se reutiliza la clave con un body distinto el server responde 422 idempotency_key_reused; si la operación previa sigue en curso responde 409 idempotency_key_in_progress. Las respuestas con status 5xx no se cachean. Tras un not_found / cep_unavailable / error puedes activar reintentos automáticos con PUT /v1/validations/{id}/retry-policy o pasar retry_policy directamente en el body. El historial completo se consulta vía GET /v1/validations.
| Parámetro | Ubicación | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
async | query | string | opcional | Cuando es `1`/`true`/`yes`, encola la validación y responde 202 inmediato con `validation_id`; el cliente sondea `GET /v1/validations/{id}` hasta el estado terminal. Sin el flag o con `0`, la respuesta es síncrona y devuelve el resultado final en el mismo POST. Predeterminado: |
Idempotency-Key | header | string | opcional | Llave opcional generada por el cliente (estilo Stripe) que garantiza que la petición se procese **exactamente una vez** dentro de un TTL de 24 horas. El alcance es `(user_id, endpoint, llave)`. Los reintentos con la misma llave y el mismo cuerpo devuelven la respuesta cacheada byte a byte con la cabecera `Idempotent-Replayed: true`, sin consumir cuota de rate-limit, sin re-disparar webhooks y sin crear una nueva fila en `validations`. Misma llave con cuerpo distinto → 422 `idempotency_key_reused`. Misma llave con una petición en vuelo → 409 `idempotency_key_in_progress`. Las respuestas 5xx no se cachean (los reintentos con la misma llave procesan de verdad). Formato: 1–255 caracteres, alfanuméricos + `_` + `-`. |
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
fecha | string (date) (patrón, 10–10) | obligatorio | Fecha de la transferencia en formato ISO 8601 (YYYY-MM-DD). Debe coincidir con la fecha registrada en el CEP; diferencias de ±1 día pueden producir un resultado `not_found`. p. ej.2025-03-15 |
monto | number (double) (> 0) | obligatorio | Importe de la transferencia en pesos mexicanos (MXN), mayor que cero y con hasta dos decimales. Debe coincidir exactamente con el monto registrado en el CEP; cualquier diferencia puede producir `not_found`. p. ej.15000.5 |
clave_rastreo | string (1–30) | Obligatorio si no se envía referencia_numerica | Clave de rastreo SPEI generada por el banco emisor: cadena alfanumérica de 18 a 30 caracteres. Requerida si `referencia_numerica` está ausente; pueden enviarse ambas simultáneamente para mayor precisión de búsqueda. p. ej.MXBA20250315001234 |
referencia_numerica | string (patrón, 1–7) | Obligatorio si no se envía clave_rastreo | Referencia numérica de la transferencia: entre 1 y 7 dígitos. Requerida si `clave_rastreo` está ausente; ambas pueden enviarse simultáneamente. p. ej.1234567 |
emisor | string (?–255) | opcional | Nombre del banco emisor. Texto libre; el sistema lo normaliza contra el catálogo Banxico. Ignorado para CLABE y tarjeta, ya que el banco emisor se deriva del prefijo. Para celular/DiMo (10 dígitos), su presencia mejora la resolución del banco receptor. p. ej.BANCO NACIONAL DE MEXICO |
receptor | string (?–255) | opcional | Nombre del banco receptor. Para CLABE (18 dígitos) y tarjeta (13-19 dígitos) el banco se deriva automáticamente del prefijo/BIN y este campo se ignora. Solo es relevante cuando `cuenta_beneficiaria` es de 10 dígitos (celular/DiMo) y no puede resolverse por otros medios. p. ej.BBVA MEXICO |
cuenta_beneficiaria | string (patrón) | opcional | Cuenta destino del SPEI: CLABE de 18 dígitos, número de tarjeta de 13 a 19 dígitos, o número de celular DiMo de 10 dígitos. El tipo se autodetecta por longitud y se valida el checksum correspondiente (CLABE: dígito verificador estándar; tarjeta: Luhn). Para celular, el banco receptor se resuelve en orden: whitelist del usuario → catálogo global; si no se encuentra, el resultado es `error` con código `bank_code_unresolvable_for_phone`. p. ej.012180004412345678 |
retry_policy | object | opcional | Política de reintentos automáticos para esta validación. Si se omite, se aplica la política configurada en `PUT /v1/users/me/retry-policy`. Los reintentos no consumen cuota de validaciones. |
curl -X POST 'https://api.veriko.mx/v1/validate' \
-H 'Authorization: Bearer mxcep_••••' \
-H 'Content-Type: application/json' \
-d '{
"fecha": "2025-03-15",
"monto": 15000.5,
"clave_rastreo": "MXBA20250315001234",
"referencia_numerica": "1234567",
"emisor": "BANCO NACIONAL DE MEXICO",
"receptor": "BBVA MEXICO",
"cuenta_beneficiaria": "012180004412345678"
}'
Ejemplo en Python — próximamente.
Ejemplo en JavaScript — próximamente.
Ejemplo en PHP — próximamente.
| Campo | Tipo | Descripción |
|---|---|---|
id * | string (uuid) | Identificador único de la validación (UUID v4). |
type * | string | Tipo de recurso JSON:API. Siempre `validation`. |
attributes * | object | Datos canónicos de la validación. |
validation_type | string | `direct` para peticiones con parámetros textuales; `ocr` para peticiones con imagen de comprobante. |
is_playground | boolean | Indica si la validación fue ejecutada en modo playground. Las ejecuciones playground sí consultan Banxico pero no consumen cuota, no emiten webhooks ni notificaciones. |
status | string | Estado del ciclo de vida: `queued` — encolado para worker; `processing` — worker procesando; `valid` — CEP encontrado y datos coinciden; `not_found` — Banxico consultado, transferencia no encontrada; `cep_unavailable` — servicio Banxico no disponible; `invalid` — payload rechazado post-encolado; `failed` — fallo terminal; `error` — error retriable (Banxico HTTP 5xx). |
banxico_status | string | null anulable | Estado reportado por Banxico tras la consulta. `null` antes de consultar. |
processing_time_ms | integer | null anulable | Milisegundos transcurridos entre encolado y resolución terminal. |
request_data | object | Snapshot literal de los campos del request original. |
created_at | string (date-time) | Marca temporal UTC del encolado. |
completed_at | string | null anulable | Marca temporal UTC de resolución terminal. `null` mientras `status` esté en `queued`/`processing`. |
enqueued_at | string | null anulable | Marca temporal del encolado en el bus de mensajería. |
processing_started_at | string | null anulable | Marca temporal del primer XCLAIM del worker. |
expires_at | string | null anulable | Marca temporal de expiración para validaciones encoladas. Tras esta marca, el job pasa a `failed`. |
etag_version | integer | null anulable | Versión incremental para `If-None-Match` en consultas polling. |
image_path | string | null anulable | Ruta relativa de la imagen del comprobante. Solo OCR. |
ocr_result | object | null anulable | Resultado bruto del OCR. Solo OCR. |
ocr_confidence | number | null anulable | Puntaje OCR 0–1. Solo OCR; `null` para `direct`. |
normalized_data | object | null anulable | Campos normalizados post-OCR para consulta a Banxico. |
normalization_warnings | array | null anulable | Advertencias de la pipeline de normalización. |
is_masked | boolean | null anulable | Indica si el PAN viene enmascarado en el comprobante OCR. |
banxico_result | object | null anulable | Payload literal devuelto por Banxico CEP. |
error_message | string | null anulable | Mensaje legible del error terminal cuando aplique. |
error_code | string | null anulable | Código machine-readable del error terminal. |
batch_id | integer | null anulable | Identificador del lote de import masivo si aplica. |
batch_position | integer | null anulable | Posición dentro del batch (1-indexed). |
retry_state | object | Estado completo del ciclo de reintentos. Siempre presente; si la validación no tiene reintentos activos, `enabled=false` y los campos de política son `null`. Las validaciones de import masivo siempre tienen `enabled=false`. |
enabled | boolean | Indica si el ciclo de reintentos está activo para esta validación. |
max_retries | integer | null anulable | Número máximo de reintentos configurado. El tope superior depende del plan (`retry_max_retries`) o del default global `max_retries_cap` (típicamente 5–10). `null` si `enabled=false`. |
interval_seconds | integer | null anulable | Intervalo entre reintentos en segundos (300–86400). `null` si `enabled=false`. |
outcomes | array | null anulable | Resultados de validación que habilitan un reintento (`not_found`, `cep_unavailable`, `error`). `null` si `enabled=false`. |
attempts_completed | integer | Número de reintentos completados hasta el momento. |
next_attempt_at | union | Timestamp del próximo reintento programado. `null` si el ciclo está en estado terminal o si no hay reintentos activos. |
resolved_at | union | Timestamp cuando un reintento resolvió la validación a `valid`. `null` si el ciclo no ha terminado por resolución. |
exhausted_at | union | Timestamp cuando se agotaron los reintentos sin resolución. `null` si el ciclo no ha terminado por agotamiento. |
cancelled_at | union | Timestamp cuando el ciclo fue cancelado explícitamente. `null` si no fue cancelado. |
terminal_state | string | null anulable | Estado terminal del ciclo: `pending` — activo, sin resultado final aún; `resolved` — un reintento obtuvo `valid`; `exhausted` — se agotaron los intentos; `cancelled` — cancelado por el usuario. |
links | object | Enlaces relacionados (JSON:API `links`). |
self | string | URL de la validación. |
cep_xml | string | null anulable | URL del CEP en formato XML. `null` si `status` no es `valid`. |
cep_pdf | string | null anulable | URL del CEP en formato PDF. `null` si `status` no es `valid`. |
| Código | Clase | Descripción | Cuerpo |
|---|---|---|---|
| 200 | 2xx | Veredicto síncrono de la validación. El campo `status` toma uno de: `valid` (transferencia confirmada en el CEP), `not_found` (no existe en el CEP para los datos proporcionados), `cep_unavailable` (Banxico no respondió a tiempo) o `error` (fallo inesperado en el pipeline). Cuando `has_cep: true` el certificado CEP está disponible vía `GET /v1/validations/{id}/cep`. | Sin cuerpo |
| 202 | 2xx | Validación encolada. El cliente debe sondear `GET /v1/validations/{id}` hasta uno de los estados terminales (`valid`, `not_found`, `cep_unavailable`, `invalid`, `failed`, `error`). `meta.next_poll_after_seconds` indica el intervalo recomendado para el primer poll. | ValidationQueued |
| 400 | 4xx | El valor de la cabecera `Idempotency-Key` no cumple el formato permitido (alfanumérico + `_` + `-`, 1–255 caracteres). | ErrorResponse |
| 401 | 4xx | Se requiere autenticación o las credenciales son inválidas | ErrorResponse |
| 409 | 4xx | Una petición con la misma `Idempotency-Key` aún se está procesando. El cliente debe reintentar después de los segundos que indica la cabecera `Retry-After`. Las filas en vuelo más antiguas que `idempotency.in_flight_timeout_seconds` (300 por defecto) se tratan automáticamente como zombies y se limpian en el siguiente intento. | ErrorResponse |
| 422 | 4xx | Falló la validación de la petición. Códigos típicos: `clave_or_ref_required`, `required` (fecha/monto), `invalid_date`, `invalid_amount`, `invalid_account_format`, `invalid_account_length`, `invalid_clabe_checksum`, `invalid_card_luhn`, `retry_policy_invalid`, `retry_pending_cap_exceeded`. También se emite cuando se reutiliza `Idempotency-Key` con un cuerpo distinto (`idempotency_key_reused`). | ErrorResponse |
| 429 | 4xx | Límite de tasa excedido | ErrorResponse |
| 503 | 5xx | Falla del upstream Banxico O fallo de despacho async (Redis caído → `dispatch_failed`). Se devuelve `banxico_rate_limit_exhausted` cuando Banxico aplica throttling y la plataforma agotó sus reintentos automáticos. Espera unos minutos y reintenta. | ErrorResponse |
| Cabecera | Tipo | Descripción |
|---|---|---|
Idempotent-Replayed | string | Presente solo cuando el cliente envió la cabecera `Idempotency-Key`. `false` para respuestas frescas; `true` cuando la respuesta es replay del caché de idempotencia (TTL 24h por usuario+endpoint+key). |
| Código | Clave | Detalle |
|---|---|---|
| 400 | invalid_idempotency_key | Invalid Idempotency-Key format. Allowed: A-Z a-z 0-9 _ - (1-255 chars). Envelope
|
| 401 | unauthorized | Invalid or missing authentication credentials. Envelope
|
| 409 | idempotency_key_in_progress | A request with this Idempotency-Key is still being processed. Envelope
Cabeceras de respuesta
|
| 429 | rate_limit_exceeded | Rate limit exceeded. Try again in 45 seconds. Envelope
Cabeceras de respuesta
|
Política de reintentos
POST /v1/validate
Política de reintentos automáticos. Configura cuándo y cuántas veces el sistema reintenta una validación cuyo resultado es elegible (`not_found`, `cep_unavailable` o `error` por defecto).
- Intentos
- —
- Intervalo
- 5 min – 1 h × 24
- Resultados elegibles
-
not_found,cep_unavailable,error
Esta operación admite una política de reintentos opcional.