Validador SPEI · API

API de CEP · Documentación

Integra la validación de transferencias SPEI y la descarga del Comprobante Electrónico de Pago (CEP) oficial de Banco de México en tu propio software — en JSON, PDF, XML o ZIP. API REST, sin SDKs: funciona con curl, fetch o cualquier cliente HTTP.

Pensada para bancos, fintechs, ERPs, conciliadores y tesorerías que necesitan obtener los CEP de sus operaciones automáticamente, sin operar a mano el formulario web de Banxico. Tú envías los datos de la transferencia; nosotros consultamos a Banxico y te devolvemos el comprobante.

Flujo típico de integración: 1) lista los bancos una vez para mapear los códigos → 2) valida la transferencia → 3) descarga el CEP con el mismo cuerpo JSON. Pruébalo en vivo en /docs (Swagger).

Primeros pasos

De cero a validar un CEP en tres pasos. Usa los datos de tu comprobante SPEI (fecha, clave de rastreo, montos y cuentas).

1 · Obtén los códigos de banco

Lista las instituciones para conocer el code del emisor y receptor.

curl $BASE/api/banks
# [{ "code": "40002", "name": "BANAMEX" }, { "code": "90684", "name": "TRANSFER" }, ...]

2 · Valida la transferencia

Envía los datos del pago y recibe el CEP en JSON.

curl -X POST $BASE/api/cep/validate \
  -H "Content-Type: application/json" \
  -d '{
    "fecha": "2026-06-10",
    "clave_rastreo": "085909274480316161",
    "emisor": "40002",
    "receptor": "90684",
    "cuenta": "684180142033702249",
    "monto": "9000.00"
  }'

3 · Descarga el comprobante

Con el mismo cuerpo JSON, baja el PDF oficial (o XML / ZIP). Esta es la vía recomendada para integraciones servidor-a-servidor.

curl -X POST "$BASE/api/cep/download?formato=PDF" \
  -H "Content-Type: application/json" \
  -d '{
    "fecha": "2026-06-10",
    "clave_rastreo": "085909274480316161",
    "emisor": "40002",
    "receptor": "90684",
    "cuenta": "684180142033702249",
    "monto": "9000.00"
  }' \
  -o cep.pdf
¿Tienes el PDF o una foto del comprobante? Súbelo y extraemos los datos automáticamente con POST /api/cep/batch.

Base URL

Todas las rutas son relativas a tu host. En estos ejemplos:

http://localhost:8000

Autenticación

Los endpoints de CEP aceptan una API key que identifica a tu integración. Envíala siempre que la tengas; cuando el servicio la requiere, es obligatoria. Los endpoints /api/health y /api/banks son siempre públicos.

Puedes enviar la llave de tres formas (en orden de preferencia):

MétodoEjemplo
Header X-API-KeyX-API-Key: TU_API_KEY
Bearer tokenAuthorization: Bearer TU_API_KEY
Query param (para descargas)?api_key=TU_API_KEY
Una llave inválida responde 401 unauthorized. ¿Necesitas una API key para tu software? Solicítala en ceppro.mx.

GET/api/health

Health

Verifica que el servicio está disponible.

curl $BASE/api/health

Respuesta 200

{ "status": "ok", "version": "0.1.0" }

GET/api/banks

Listar bancos

Devuelve el catálogo de instituciones participantes en SPEI. Usa los code para los campos emisor y receptor. La respuesta se cachea (1 h) en el navegador.

curl $BASE/api/banks

Respuesta 200

[
  { "code": "40002", "name": "BANAMEX" },
  { "code": "40012", "name": "BBVA BANCOMER" },
  { "code": "90684", "name": "TRANSFER" }
]

POST/api/cep/validate

Validar CEP

Valida una transferencia contra Banxico y devuelve los datos estructurados del comprobante en JSON. Ver parámetros para el detalle de campos.

curl -X POST $BASE/api/cep/validate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: TU_API_KEY" \
  -d '{
    "fecha": "2026-06-10",
    "clave_rastreo": "085909274480316161",
    "emisor": "40002",
    "receptor": "90684",
    "cuenta": "684180142033702249",
    "monto": "9000.00"
  }'

Respuesta 200

{
  "clave_rastreo": "085909274480316161",
  "fecha_operacion": "20260610",
  "hora_operacion": "15:32:34",
  "monto": "9000.00",
  "iva": "0.00",
  "concepto": "pago",
  "emisor": "BANAMEX",
  "receptor": "TRANSFER",
  "ordenante_nombre": "ANGEL ISSAC,PEREZ/MARTINEZ",
  "ordenante_cuenta": "002910702140629588",
  "beneficiario_nombre": "TODO MUNDO FINTECH-PRO SA DE CV",
  "beneficiario_cuenta": "684180142033702249",
  "beneficiario_rfc": "TMF180212UKA",
  "sello": "SQeXs/GkbMJ3Ae+He..."
}

POSTGET/api/cep/download

Descargar CEP

Valida y devuelve el comprobante oficial como archivo binario. Elige el formato con el parámetro de query formato = PDF · XML · ZIP (por defecto PDF). Hay dos formas, con los mismos datos que validar:

  • POST (recomendado para integraciones) — cuerpo JSON, igual que validate. Sin codificar nada en la URL.
  • GET — todos los datos en la query string. Útil para enlaces de descarga directos que el navegador puede abrir.
# POST (recomendado): mismo cuerpo JSON que validate
curl -X POST "$BASE/api/cep/download?formato=PDF" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: TU_API_KEY" \
  -d '{
    "fecha": "2026-06-10",
    "clave_rastreo": "085909274480316161",
    "emisor": "40002",
    "receptor": "90684",
    "cuenta": "684180142033702249",
    "monto": "9000.00"
  }' \
  -o cep.pdf

# GET: enlace directo (descargable en el navegador)
curl -G $BASE/api/cep/download \
  --data-urlencode "fecha=2026-06-10" \
  --data-urlencode "clave_rastreo=085909274480316161" \
  --data-urlencode "emisor=40002" \
  --data-urlencode "receptor=90684" \
  --data-urlencode "cuenta=684180142033702249" \
  --data-urlencode "monto=9000.00" \
  --data-urlencode "formato=PDF" \
  --data-urlencode "api_key=TU_API_KEY" \
  -o cep.pdf

Respuesta: el archivo binario con Content-Type application/pdf · application/xml · application/zip y Content-Disposition: attachment.


POST/api/cep/batch

Lote por archivos

Sube hasta 10 comprobantes (PDF o imagen). El servicio extrae los campos de cada archivo (texto de PDF o OCR de imagen) y valida cada uno contra Banxico. Se envía como multipart/form-data con el campo repetido files.

Banxico's own batch tool (CEP-SCL) is protected by reCAPTCHA and can't be automated, so this endpoint runs the per-CEP flow for each file. Extraction is best-effort — a misread field simply returns not_found for that item.
curl -X POST $BASE/api/cep/batch \
  -H "X-API-Key: TU_API_KEY" \
  -F "files=@comprobante1.pdf" \
  -F "files=@captura2.png"

Respuesta 200

{
  "items": [
    {
      "filename": "comprobante1.pdf",
      "status": "valid",          // valid | pending | no_cep | needs_input | not_found | extract_failed | error
      "request": { "fecha": "2026-06-10", "clave_rastreo": "...", "...": "..." },
      "details": { "beneficiario_nombre": "...", "monto": "9000.00" }
    },
    { "filename": "captura2.png", "status": "not_found", "message": "..." }
  ]
}

Descarga los archivos de cada valid con /api/cep/download usando los campos de request.


Parámetros

Todos son obligatorios. Para validate y POST download van en el cuerpo JSON; para GET download, como query string. formato siempre va como parámetro de query.

CampoTipoDescripción
fechastringREQFecha de operación, formato YYYY-MM-DD.
clave_rastreostringREQClave de rastreo o número de referencia (≤ 40 caracteres). Se detecta automáticamente: solo dígitos y ≤ 7 → referencia; en otro caso → clave de rastreo.
emisorstringREQCódigo del banco emisor (ver /api/banks).
receptorstringREQCódigo del banco receptor.
cuentastringREQCuenta beneficiaria: CLABE, tarjeta o teléfono.
montostringREQMonto en pesos, p. ej. 9000.00.
formatostringOPCSolo download: PDF (default), XML o ZIP.

Códigos de error

Los errores devuelven JSON con error y detail (excepto 422, que usa el formato de validación estándar).

HTTPerrorSignificado
401unauthorizedAPI key faltante o inválida (cuando el servidor tiene auth activada).
404not_foundBanxico no encontró una transferencia con esos datos.
409cep_pendingBanxico identificó el pago, pero el CEP aún no está disponible (reintenta más tarde).
409cep_statusBanxico encontró la operación, pero está en un estado sin CEP descargable (p. ej. devuelta). Incluye estado cuando se reconoce.
422Parámetros inválidos o faltantes (validación).
502banxico_unavailableBanxico no respondió o devolvió un error transitorio.
503captcha_enforcedBanxico exige captcha (rate-limiting); reintenta más tarde.
503busyServicio saturado de lotes en curso; reintenta en unos segundos (solo endpoints de lote/ZIP).

Ejemplo 404

{ "error": "not_found", "detail": "Banxico no encontró una transferencia que coincida con los datos proporcionados." }

Límites de uso e idempotencia

Banxico aplica rate-limiting por IP a su servicio de CEP. La API lo mitiga con throttling, reintentos con backoff y caché de comprobantes (los CEP son inmutables, así que una consulta repetida es instantánea y no vuelve a golpear a Banxico).

Recomendaciones para integrar

  • Trata cada consulta como idempotente: validar o descargar la misma transferencia siempre devuelve el mismo CEP. Puedes reintentar sin efectos secundarios.
  • Reintenta con backoff exponencial ante 429 rate_limited, 502 banxico_unavailable, 503 captcha_enforced y 503 busy (p. ej. 2 s, 4 s, 8 s).
  • Los endpoints de lote y ZIP (/api/cep/batch, /api/cep/batch/stream, /api/cep/download-zip) tienen un límite por IP más estricto que las consultas individuales, porque cada uno consulta hasta 10 CEP. Procesa los lotes de forma secuencial, no en paralelo.
  • 409 cep_pending significa que el pago existe pero el CEP aún no está listo: reintenta más tarde (minutos/horas), no de inmediato.
  • 409 cep_status significa que la operación existe pero está en un estado sin CEP descargable (p. ej. devuelta): no reintentes, revisa el campo estado y el detail que Banxico reporta.
  • Evita ráfagas concurrentes desde una sola IP; encola y procesa a un ritmo moderado para no disparar el captcha de Banxico.
Volumen alto: para flujos sostenidos (cientos por hora), apóyate en la caché, encola las solicitudes y mantén un ritmo moderado. Si necesitas un límite mayor o una API key dedicada, escríbenos desde ceppro.mx.