POSThttps://api.veriko.mx/v1/validate

Validar una transferencia SPEI (directa)

Audiencia
public
Autenticación
API key
Permiso
validations:create
Guía de uso →

Valida una transferencia SPEI contra el CEP de Banxico a partir de los campos que se envían:

  • fecha
  • monto
  • clave de rastreo
  • referencia numérica
  • banco emisor
  • banco receptor
  • cuenta beneficiaria

La respuesta es un veredicto: valid, not_found, cep_unavailable o error. Esta es la vía explícita. La alternativa, POST /v1/validate-ocr, recibe la imagen del comprobante y deduce de ella esos mismos campos; el veredicto y el resto del contrato son idénticos. Modo asíncrono. Con ?async=1 la operación se encola y la respuesta es un 202 inmediato con el identificador. El veredicto se recoge sondeando GET /v1/validations/{id} hasta un estado terminal; la cadencia y el uso de ETag para no descargar dos veces lo mismo están en las operaciones asíncronas. Cada llamada consume cuota del plan, tanto en modo síncrono como asíncrono, y se descuenta al aceptar la petición, no al resolverse. Agotar la cuota responde 429; el cómputo y los topes están en cuotas y planes. Idempotencia. La cabecera Idempotency-Key es opcional y evita duplicar una validación cuando un reintento de red repite la petición. Reutilizar la clave con un cuerpo distinto responde 422 idempotency_key_reused; hacerlo mientras la operación anterior sigue en curso, 409 idempotency_key_in_progress. Una respuesta 5xx no se guarda, de modo que un fallo del servidor no deja la clave inutilizada. Un veredicto not_found, cep_unavailable o error no es necesariamente definitivo: el CEP puede tardar en publicarse. Los reintentos automáticos se activan con PUT /v1/validations/{id}/retry-policy, o enviando retry_policy en este mismo cuerpo, y su funcionamiento está en la política de reintentos. El historial completo se consulta en GET /v1/validations.

Parámetros
ParámetroUbicaciónTipoObligatorioDescripción
asyncquerystringopcional

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: 0

Idempotency-Keyheaderstringopcional

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 + _ + -.

p. ej. 11111111-2222-3333-4444-555555555555
Parámetros
ParámetroTipoObligatorioDescripción
fechastring (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
montonumber (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_rastreostring (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_numericastring (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
emisorstring (?–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
receptorstring (?–255)opcional

Nombre del banco receptor. Para CLABE (18 dígitos) y tarjeta (16 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_beneficiariastring (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_policyobjectopcional

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.

Petición
curl -X POST 'https://api.veriko.mx/v1/validate' \
  -H 'Authorization: Bearer veriko_••••' \
  -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.

Respuesta 2xxValidation
CampoTipoDescripción
type*string

Tipo de recurso JSON:API. Siempre validation.

p. ej. validation
id*string (uuid)

Identificador único de la validación (UUID v4).

p. ej. 3fa85f64-5717-4562-b3fc-2c963f66afa6
attributes*object

Datos canónicos de la validación.

validation_typestring

direct para peticiones con parámetros textuales; ocr para peticiones con imagen de comprobante.

p. ej. direct
is_playgroundboolean

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.

p. ej. false
statusstring

Estado del ciclo de vida: queued — encolado para trabajador; processing — trabajador 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).

p. ej. valid
banxico_statusstring | nullanulable

Estado reportado por Banxico tras la consulta. null antes de consultar.

p. ej. valid
processing_time_msinteger | nullanulable

Milisegundos transcurridos entre encolado y resolución terminal.

p. ej. 1320
request_dataobject

Snapshot literal de los campos del request original.

created_atstring (date-time)

Marca temporal UTC del encolado.

p. ej. 2025-03-15T14:22:10Z
completed_atstring | nullanulable

Marca temporal UTC de resolución terminal. null mientras status esté en queued/processing.

p. ej. 2025-03-15T14:22:11Z
enqueued_atstring | nullanulable

Marca temporal del encolado en el bus de mensajería.

p. ej. 2026-04-30T10:15:00Z
processing_started_atstring | nullanulable

Marca temporal del primer XCLAIM del trabajador.

p. ej. 2026-04-30T10:15:00Z
expires_atstring | nullanulable

Marca temporal de expiración para validaciones encoladas. Tras esta marca, la importación pasa a failed.

p. ej. 2026-04-30T10:15:00Z
etag_versioninteger | nullanulable

Versión incremental para If-None-Match en consultas polling.

p. ej. 1
image_pathstring | nullanulable

Ruta relativa de la imagen del comprobante. Solo OCR.

p. ej. ocr/2026/04/a1b2c3d4.jpg
ocr_resultobject | nullanulable

Resultado bruto del OCR. Solo OCR.

ocr_confidencenumber | nullanulable

Puntaje OCR 0–1. Solo OCR; null para direct.

p. ej. 0.94
normalized_dataobject | nullanulable

Campos normalizados post-OCR para consulta a Banxico.

normalization_warningsarray | nullanulable

Advertencias de la pipeline de normalización.

is_maskedboolean | nullanulable

Indica si el PAN viene enmascarado en el comprobante OCR.

banxico_resultobject | nullanulable

Payload literal devuelto por Banxico CEP.

error_messagestring | nullanulable

Mensaje legible del error terminal cuando aplique.

p. ej. Banxico no respondió tras tres intentos.
error_codeValidationErrorCode | null

Código machine-readable del error terminal.

batch_idinteger | nullanulable

Identificador del lote de import masivo si aplica.

p. ej. 318
batch_positioninteger | nullanulable

Posición dentro del lote (1-indexed).

p. ej. 12
retry_stateobject

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.

enabledboolean

Indica si el ciclo de reintentos está activo para esta validación.

p. ej. true
max_retriesinteger | nullanulable

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.

p. ej. 3
interval_secondsinteger | nullanulable

Intervalo entre reintentos en segundos (300–86400). null si enabled=false.

p. ej. 600
outcomesarray | nullanulable

Resultados de validación que habilitan un reintento (not_found, cep_unavailable, error). null si enabled=false.

p. ej. ["not_found","cep_unavailable","error"]
attempts_completedinteger

Número de reintentos completados hasta el momento.

p. ej. 1
next_attempt_atTimestampUTC | null

Timestamp del próximo reintento programado. null si el ciclo está en estado terminal o si no hay reintentos activos.

resolved_atTimestampUTC | null

Timestamp cuando un reintento resolvió la validación a valid. null si el ciclo no ha terminado por resolución.

exhausted_atTimestampUTC | null

Timestamp cuando se agotaron los reintentos sin resolución. null si el ciclo no ha terminado por agotamiento.

cancelled_atTimestampUTC | null

Timestamp cuando el ciclo fue cancelado explícitamente. null si no fue cancelado.

terminal_statestring | nullanulable

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. null si la validación no tiene ciclo de reintentos.

p. ej. pending
linksobject

Enlaces relacionados (JSON:API links).

selfstring

URL de la validación.

p. ej. /v1/validations/3fa85f64-5717-4562-b3fc-2c963f66afa6
cep_xmlstring | nullanulable

URL del CEP en formato XML. null si status no es valid.

p. ej. /v1/validations/a1b2c3d4-e5f6-7890-abcd-ef0123456789/cep.xml
cep_pdfstring | nullanulable

URL del CEP en formato PDF. null si status no es valid.

p. ej. /v1/validations/a1b2c3d4-e5f6-7890-abcd-ef0123456789/cep.pdf
Códigos de respuestaPOST /v1/validate
CódigoClaseDescripciónCuerpo
2002xxVeredicto 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
2022xxValidació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
4004xxEl valor de la cabecera Idempotency-Key no cumple el formato permitido (alfanumérico + _ + -, 1–255 caracteres). ErrorResponse
4014xxSe requiere autenticación o las credenciales son inválidasErrorResponse
4094xxUna 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
4134xxEl cuerpo de la petición supera el tamaño máximo admitido (body_too_large).ErrorResponse
4224xxFalló 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
4294xxLímite de tasa excedidoErrorResponse
5035xxFalla 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
Cabeceras de respuesta200
CabeceraTipoDescripción
Idempotent-ReplayedstringPresente 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).
Errores de POST /v1/validate
CódigoClaveEjemplo
400invalid_idempotency_key

Formato de Idempotency-Key inválido. Se admiten A-Z a-z 0-9 _ - (de 1 a 255 caracteres).

Envelope
meta.request_id
3c4d5e6f7a8b
401unauthorized

Credenciales de autenticación ausentes o inválidas.

Envelope
meta.request_id
c4d5e6f7a8b9
409idempotency_key_in_progress

Una petición con esta Idempotency-Key sigue en proceso.

Envelope
meta.request_id
2b3c4d5e6f7a
Cabeceras de respuesta
  • Retry-After: integer — Segundos a esperar antes de reintentar
413body_too_large

El cuerpo de la petición es demasiado grande.

Envelope
meta.request_id
1a2b3c4d5e6f
429rate_limit_exceeded

Límite de peticiones excedido. Inténtalo de nuevo en 45 segundos.

Envelope
meta.request_id
f7a8b9c0d1e2
Cabeceras de respuesta
  • Retry-After: integer — Segundos a esperar antes de reintentar. Coincide con la ventana de rate-limit del endpoint (típicamente 60s para listas, 1-5s para operaciones idempotentes en vuelo).
  • X-RateLimit-Limit: integer — Límite de solicitudes configurado para este bucket (emitido sólo en 429).
  • X-RateLimit-Remaining: integer — Solicitudes restantes en la ventana actual — siempre 0 en el momento del 429 (emitido sólo en 429).
  • X-RateLimit-Reset: integer — Unix epoch absoluto (segundos) en que se reinicia la ventana. Emitido sólo en 429, junto con Retry-After. Puede existir sobreescritura por endpoint (p. ej. `rate_limited_login`).

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.