apiCEPDocs

    Referencia de la API de apiCEP

    La API de apiCEP permite validar comprobantes de transferencia SPEI mediante la combinación de análisis OCR de imágenes con verificación en tiempo real contra el sistema CEP (Comprobante Electrónico de Pago) de Banxico. Envía la imagen del comprobante junto con los datos del beneficiario, y la API devuelve un resultado validado y estructurado, incluyendo el CEP oficial.

    URL Base

    https://api.apicep.cloud

    Autenticación

    Todas las solicitudes requieren una API key válida enviada en el encabezado Authorization usando el esquema Bearer.

    Authorization: Bearer TU_API_KEY

    Las solicitudes sin una clave válida retornan 401 Unauthorized. Si excedes la cuota de tu plan, la API retorna 429 Too Many Requests.

    Límite de Solicitudes (Rate Limiting)

    La información del límite se devuelve en cada respuesta a través de estos encabezados:

    EncabezadoDescripción
    X-RateLimit-LimitTotal de solicitudes permitidas en el periodo actual
    X-RateLimit-RemainingSolicitudes restantes en el periodo actual
    X-RateLimit-ResetTimestamp (ISO 8601) en que se restablece la cuota

    Endpoint

    POST
    /validate-transfer

    Valida un comprobante de transferencia SPEI contra el registro CEP de Banxico.

    POST https://api.apicep.cloud/validate-transfer

    Solicitud (Request)

    Encabezados

    EncabezadoValorRequerido
    AuthorizationBearer TU_API_KEY✅ Sí
    Content-Typeapplication/json✅ Sí

    Modos de Validación

    El endpoint soporta dos modos de validación según los campos enviados en el body:

    • Modo OCR — envía imageUrl con la URL del comprobante. La API extrae los datos automáticamente y los valida contra Banxico.
    • Modo Directo (sin OCR) — envía el objeto sender con los datos de la transferencia. En este modo imageUrl no es requerido.

    Esquema del Body — Modo OCR

    {
    "imageUrl": "https://ejemplo.com/comprobante.jpg",
    "beneficiary": {
    "clabe": "012180015469165113",
    "bank": "BBVA MEXICO",
    "name": "Juan Pérez"
    }
    }

    Esquema del Body — Modo Directo (con sender)

    {
    "beneficiary": {
    "clabe": "012180015469165113",
    "bank": "BBVA MEXICO",
    "name": "Juan Pérez"
    },
    "sender": {
    "date": "2026-01-17",
    "amount": 1,
    "bank": "HSBC",
    "trackingKey": "HSBC712057",
    "referenceNumber": "0170126"
    }
    }

    Esquema del Body — Modo OCR con potentialBeneficiaries

    {
    "imageUrl": "https://ejemplo.com/comprobante.jpg",
    "potentialBeneficiaries": [
    {
    "clabe": "127180016477999560",
    "bank": "AZTECA"
    },
    {
    "phoneNumber": "1234567890",
    "bank": "BBVA"
    },
    {
    "cardNumber": "1234567890123456",
    "bank": "BANORTE"
    },
    {
    "clabe": "123456789012345678",
    "bank": "BANORTE"
    }
    ]
    }

    Campos de Nivel Superior

    CampoTipoRequeridoDescripción
    imageUrlstringCondicionalURL pública del comprobante de transferencia (JPEG, PNG o PDF). Requerido cuando no se envía sender. Tamaño máximo: 1 MB.
    beneficiaryobjectCondicionalDatos del beneficiario del pago. Requerido cuando no se envía potentialBeneficiaries.
    senderobjectCondicionalDatos del ordenante para validar sin OCR. Si se envía, imageUrl no es requerido.
    potentialBeneficiariesarrayCondicionalArray de objetos beneficiary para validación multi-cuenta. Solo funciona en modo OCR. Si se envía, beneficiary no es requerido.

    Objeto beneficiary

    ⚠ Se debe proporcionar exactamente uno de los campos clabe, phoneNumber o cardNumber.
    CampoTipoRequeridoDescripción
    clabestringCondicionalCLABE interbancaria de 18 dígitos
    phoneNumberstringCondicionalNúmero de teléfono móvil de 10 dígitos
    cardNumberstringCondicionalNúmero de tarjeta de débito de 16 dígitos
    bankstring✅ SíNombre del banco beneficiario. Ver Bancos Válidos
    namestringNoNombre esperado del beneficiario (referencia interna)

    Objeto sender

    ⚠ Se debe enviar al menos uno de los campos trackingKey o referenceNumber (pueden enviarse ambos, pero al menos uno es obligatorio).
    CampoTipoRequeridoDescripción
    datestring✅ SíFecha de la operación (YYYY-MM-DD)
    amountnumber✅ SíMonto de la transferencia en MXN
    bankstring✅ SíBanco ordenante. Ver Bancos Válidos
    trackingKeystringCondicionalClave de rastreo SPEI. Obligatorio si no se envía referenceNumber.
    referenceNumberstringCondicionalNúmero de referencia del pago. Obligatorio si no se envía trackingKey.

    Reglas de formato

    • clabe — exactamente 18 dígitos
    • phoneNumber — exactamente 10 dígitos
    • cardNumber — exactamente 16 dígitos

    Array potentialBeneficiaries

    ℹ Este campo permite enviar múltiples candidatos de beneficiarios. El sistema utiliza los datos extraídos por OCR del comprobante para determinar automáticamente cuál es el beneficiario correcto. Solo disponible en modo OCR (requiere imageUrl).
    ⚠ Cuando se envía potentialBeneficiaries, la propiedad beneficiary no es obligatoria. El sistema buscará coincidencias entre los datos extraídos por OCR y los candidatos proporcionados.
    CampoTipoRequeridoDescripción
    clabestringCondicionalCLABE interbancaria de 18 dígitos
    phoneNumberstringCondicionalNúmero de teléfono móvil de 10 dígitos
    cardNumberstringCondicionalNúmero de tarjeta de débito de 16 dígitos
    bankstring✅ SíNombre del banco beneficiario. Ver Bancos Válidos
    ⚠ Cada objeto del array debe proporcionar exactamente uno de los campos clabe, phoneNumber o cardNumber.

    Cómo funciona la selección

    El sistema compara los datos extraídos por OCR (banco destino, nombre del beneficiario, CLABE o cuenta detectada) contra cada candidato en potentialBeneficiaries. El candidato con mayor coincidencia se utiliza como beneficiario definitivo para la validación CEP. Si ningún candidato coincide, la validación retornará status: "error".

    Bancos Válidos

    El campo beneficiary.bank acepta el nombre del banco beneficiario.

    ACTINVER
    AFIRME
    albo
    ARCUS FI
    ASP INTEGRA OPC
    AZTECA
    BaBien
    BAJIO
    BANAMEX
    BANCO COVALTO
    BANCOMEXT
    BANCOPPEL
    BANCO S3
    BANCREA
    BANJERCITO
    BANKAOOL
    BANK OF AMERICA
    BANK OF CHINA
    BANOBRAS
    BANORTE
    BANREGIO
    BANSI
    BANXICO
    BARCLAYS
    BBASE
    BBVA MEXICO
    BMONEX
    CAJA POP MEXICA
    CAJA TELEFONIST
    CASHI CUENTA
    CB INTERCAM
    CI BOLSA
    CITI MEXICO
    CLS
    CoDi Valida
    COMPARTAMOS
    CONSUBANCO
    COOPDESARROLLO
    CREDICAPITAL
    CREDICLUB
    CRISTOBAL COLON
    Cuenca
    Dep y Pag Dig
    DONDE
    FINAMEX
    FINCOMUN
    FINCO PAY
    FONDEADORA
    FONDO (FIRA)
    GBM
    HEY BANCO
    HIPOTECARIA FED
    HSBC
    ICBC
    INBURSA
    INDEVAL
    INMOBILIARIO
    INTERCAM BANCO
    INVEX
    JP MORGAN
    KAPITAL
    KLAR
    KUSPIT
    LIBERTAD
    MASARI
    Mercado Pago W
    MexPago
    MIFEL
    MIZUHO BANK
    MONEXCB
    MUFG
    MULTIVA BANCO
    NAFIN
    NU MEXICO
    NVIO
    PAGATODO
    Peibo
    PROFUTURO
    REVOLUT
    SABADELL
    SANTANDER
    SCOTIABANK
    SHINHAN
    SPIN BY OXXO
    STP
    TESORED
    TRANSFER
    UALA
    UBER PRO CARD
    UNAGRA
    VALMEX
    VALUE
    VECTOR
    VE POR MAS
    VOLKSWAGEN

    Códigos de Estado HTTP

    CódigoSignificado
    200Solicitud procesada correctamente. Revisa el campo status en el body para conocer el resultado.
    400Solicitud inválida — campos faltantes o con formato incorrecto.
    401No autorizado — API key ausente o inválida.
    405Método no permitido — solo se acepta POST.
    429Límite de solicitudes excedido.
    500Error interno del servidor.
    ℹ️ Un 200 no significa que la transferencia sea válida — significa que la solicitud fue procesada. Siempre revisa el campo status.

    Encabezados de Respuesta

    EncabezadoDescripción
    X-Processing-TimeTiempo total de procesamiento en el servidor (ej. 2340ms)
    X-RateLimit-RemainingSolicitudes restantes en la ventana de cuota actual
    X-RateLimit-ResetTimestamp ISO 8601 del restablecimiento de cuota
    X-RateLimit-LimitTotal de solicitudes permitidas por periodo

    Esquema del Body de Respuesta

    {
    "validationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "valid",
    "confidence": 0.97,
    "extracted": {
    "senderBank": "HSBC",
    "receiverBank": "BBVA MEXICO",
    "trackingKey": "2024010112345678",
    "referenceNumber": "987654321",
    "amount": 1500.00,
    "date": "2024-01-15",
    "senderName": "María García",
    "beneficiaryName": "Juan Pérez",
    "paymentConcept": "Pago de renta"
    },
    "validation": {
    "banxicoConfirmed": true,
    "cepStatus": "LIQUIDADA",
    "cepPreviouslyValidated": false,
    "cepDetails": { "..." : "..." }
    },
    "downloads": {
    "cepXml": "https://storage.apicep.cloud/...",
    "cepPdf": "https://storage.apicep.cloud/...",
    "originalImage": "https://storage.apicep.cloud/..."
    },
    "processingTime": {
    "ocr": "1.20s",
    "validation": "3.45s",
    "total": "4.68s"
    }
    }

    Campos de la Respuesta

    Nivel Superior

    CampoTipoDescripción
    validationIdstringIdentificador único de esta validación (UUID)
    statusstringResultado de la validación (ver Valores de Status)
    confidencenumberPuntaje de confianza del OCR de 0.0 a 1.0
    extractedobjectDatos extraídos del comprobante mediante OCR
    validationobjectResultado de la consulta al registro CEP de Banxico
    downloadsobjectURLs de descarga para el CEP y la imagen del comprobante
    processingTimeobjectDesglose del tiempo por etapa de procesamiento
    missingFieldsstring[]Lista de campos obligatorios que el OCR no pudo extraer (solo presente cuando status es "error" por datos faltantes)
    errorstringDescripción del error (solo presente cuando status es "error")

    Objeto extracted

    Todos los campos son opcionales — su presencia depende de lo que el OCR haya podido leer.

    CampoTipoDescripción
    senderBankstringNombre del banco emisor
    receiverBankstringNombre del banco destino
    trackingKeystringClave de rastreo SPEI
    referenceNumberstringNúmero de referencia del pago
    amountnumberMonto de la transferencia en MXN
    datestringFecha de operación (YYYY-MM-DD)
    senderNamestringNombre del ordenante
    beneficiaryNamestringNombre del beneficiario
    paymentConceptstringConcepto del pago

    Objeto validation

    CampoTipoDescripción
    banxicoConfirmedbooleantrue si Banxico confirmó la transferencia
    cepStatusstringEstatus oficial del CEP (ej. "LIQUIDADA")
    cepPreviouslyValidatedboolean | nullnull si no se obtuvo digitalSignature del CEP; false si este CEP no había sido validado anteriormente; true si ya fue validado en una solicitud previa
    cepDetailsobjectDatos del XML oficial del CEP (ver abajo)

    Objeto cepDetails

    Solo se incluye cuando banxicoConfirmed es true.

    CampoTipoDescripción
    operationDatestringFecha en que se ejecutó la operación
    processingDatestringFecha en que SPEI procesó la operación
    processingTimestringHora de procesamiento (HH:MM:SS)
    speiKeystringClave interna del sistema SPEI
    trackingKeystringClave de rastreo SPEI
    senderBankstringNombre del banco emisor
    senderNamestringNombre completo del ordenante
    senderAccountTypestringTipo de cuenta del ordenante
    senderAccountstringNúmero de cuenta del ordenante
    senderRfcstringRFC del ordenante
    receiverBankstringNombre del banco receptor
    beneficiaryNamestringNombre del beneficiario
    beneficiaryAccountTypestringTipo de cuenta del beneficiario
    beneficiaryAccountstringNúmero de cuenta del beneficiario
    beneficiaryRfcstringRFC del beneficiario
    amountnumberMonto de la transferencia en MXN
    ivanumberMonto del IVA, si aplica
    paymentConceptstringConcepto del pago según el CEP
    digitalSignaturestringSello digital SAT del CEP
    certificateNumberstringNúmero de certificado de la firma digital

    Objeto downloads

    CampoTipoDescripción
    cepXmlstringURL al archivo XML oficial del CEP
    cepPdfstringURL al archivo PDF oficial del CEP
    originalImagestringURL a la copia almacenada del comprobante enviado

    Todas las URLs se sirven desde https://storage.apicep.cloud.

    ⚠ Las URLs de cepXml, cepPdf y originalImage se eliminan automáticamente 15 días después de la validación. Descarga y almacena los archivos en tu propio sistema si necesitas conservarlos por más tiempo.

    Objeto processingTime

    CampoTipoDescripción
    ocrstringTiempo en análisis OCR (ej. "1.20s")
    validationstringTiempo en consultar CEP de Banxico (ej. "3.45s")
    totalstringTiempo total (ej. "4.68s")

    Valores de Status

    StatusSignificado
    valid
    La transferencia fue confirmada por Banxico — el comprobante es auténtico.
    invalid
    La transferencia no fue encontrada en el registro CEP de Banxico.
    pending
    La validación aún está en progreso (reservado para flujos asíncronos).
    error
    Ocurrió un error durante el procesamiento — revisa el campo error.
    Nota sobre el status: El status "valid" depende directamente de la existencia del CEP. Si el CEP no existe al momento de la consulta, el estatus será "invalid". El CEP normalmente se genera segundos después de la transferencia, pero existen escenarios en los que Banxico puede tardar horas en generarlo.

    Cómo Funciona

    El endpoint /validate-transfer ejecuta el siguiente flujo:

    1. 1

      Descarga de imagen

      Descarga el comprobante desde la imageUrl proporcionada y almacena una copia en storage.apicep.cloud.

    2. 2

      Extracción OCR

      Analiza la imagen para extraer campos SPEI (clave de rastreo, monto, fecha, bancos, nombres).

    3. 3

      Consulta CEP

      Verifica el registro CEP de Banxico usando los datos extraídos y la cuenta del beneficiario proporcionada.

    4. 4

      Parseo XML

      Si se encuentra un CEP, descarga y parsea el XML oficial para obtener el objeto cepDetails estructurado.

    5. 5

      Respuesta

      Retorna el resultado de validación, datos extraídos, detalles del CEP y URLs de descarga.

    Referencia de Errores

    400 Bad Request

    Mensaje de ErrorCausa
    imageUrl is requiredEl campo imageUrl no fue enviado en el body
    beneficiary must include one of: clabe, phoneNumber, or cardNumberNo se proporcionó ningún identificador de cuenta
    beneficiary must include only one of: clabe, phoneNumber, or cardNumberSe proporcionó más de un identificador de cuenta
    beneficiary.clabe must be exactly 18 digitsLa CLABE tiene un formato inválido
    beneficiary.phoneNumber must be exactly 10 digitsEl número de teléfono tiene un formato inválido
    beneficiary.cardNumber must be exactly 16 digitsEl número de tarjeta tiene un formato inválido
    beneficiary.bank is requiredEl campo beneficiary.bank no fue enviado
    El archivo proporcionado no es una imagen válida (content-type: <tipo>). Solo se admiten formatos de imagen: JPEG, PNG, GIF, WebP, BMP, TIFF, HEIC.La URL en imageUrl apunta a un archivo cuyo Content-Type no corresponde a un formato de imagen soportado

    403 Forbidden

    Retornado cuando el usuario no tiene un plan activo con solicitudes disponibles:

    CódigoMensajeCausa
    NO_ACTIVE_PLANNo active plan with remaining requests. Purchase a new plan at apicep.cloudEl API key es válido pero el plan asociado no tiene solicitudes disponibles o ha expirado. Adquiere un nuevo plan en apicep.cloud

    200 con status: "error"

    Estos son errores de procesamiento que se retornan con código 200:

    ErrorCausa
    Failed to download imageLa imageUrl no era accesible al momento del procesamiento
    Failed to extract data from imageEl OCR retornó confianza cero — calidad de imagen insuficiente
    El OCR no pudo extraer los siguientes datos obligatorios...El OCR no pudo leer uno o más campos requeridos: fecha de la operación, clave de rastreo o número de referencia, institución emisora del pago, monto del pago. La respuesta incluye el arreglo missingFields con los campos faltantes.

    Ejemplo de respuesta con campos faltantes

    Cuando el OCR no puede extraer todos los datos obligatorios, la API retorna status: "error" con un mensaje descriptivo y el arreglo missingFields indicando exactamente qué campos faltan. Los campos obligatorios son: fecha de la operación, clave de rastreo o número de referencia, institución emisora del pago y monto del pago.

    {
    "validationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "error",
    "confidence": 0.45,
    "extracted": {
    "senderBank": "HSBC",
    "amount": 1500.00
    },
    "validation": { "banxicoConfirmed": false },
    "processingTime": {
    "ocr": "1.10s",
    "total": "1.15s"
    },
    "error": "El OCR no pudo extraer los siguientes datos obligatorios del comprobante: fecha de la operación, clave de rastreo o número de referencia. Por favor envía una imagen más clara.",
    "missingFields": [
    "fecha de la operación",
    "clave de rastreo o número de referencia"
    ]
    }

    Ejemplos de Código

    curl -X POST https://api.apicep.cloud/validate-transfer \
    -H "Authorization: Bearer TU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "imageUrl": "https://ejemplo.com/comprobante.jpg",
    "beneficiary": {
    "clabe": "012180015469165113",
    "bank": "BBVA MEXICO",
    "name": "Juan Pérez"
    }
    }'

    Buenas Prácticas para Operaciones Masivas

    Si necesitas validar múltiples comprobantes de transferencia en un solo proceso, te recomendamos no enviar todas las solicitudes al mismo tiempo. En su lugar, procésalas de forma secuencial con un intervalo de espera entre cada llamada. Sugerimos 1 segundo entre cada una.

    ¿Por qué? Enviar demasiadas solicitudes simultáneas puede generar condiciones de carrera, timeouts o respuestas inconsistentes.

    ¿Cómo implementarlo? Usa una función sleep entre cada llamada dentro de tu ciclo:

    const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
    const comprobantes = [
    { imageUrl: 'https://ejemplo.com/comprobante1.jpg', clabe: '012180015469165113', bank: 'BBVA MEXICO', name: 'Juan Pérez' },
    { imageUrl: 'https://ejemplo.com/comprobante2.jpg', clabe: '014180015469165114', bank: 'BANAMEX', name: 'María García' },
    { imageUrl: 'https://ejemplo.com/comprobante3.jpg', clabe: '006180015469165115', bank: 'BANORTE', name: 'Carlos López' },
    // ...más comprobantes
    ];
    for (const comprobante of comprobantes) {
    const response = await fetch('https://api.apicep.cloud/validate-transfer', {
    method: 'POST',
    headers: {
    'Authorization': 'Bearer TU_API_KEY',
    'Content-Type': 'application/json',
    },
    body: JSON.stringify({
    imageUrl: comprobante.imageUrl,
    beneficiary: {
    clabe: comprobante.clabe,
    bank: comprobante.bank,
    },
    }),
    });
    const result = await response.json();
    if (result.status === 'valid' && result.validation.banxicoConfirmed) {
    console.log(`Transferencia verificada por Banxico ✅`);
    console.log('Monto:', result.extracted.amount);
    console.log('CEP PDF:', result.downloads.cepPdf);
    } else {
    console.log(`No se pudo verificar la transferencia ❌`);
    console.log('Razón:', result.error);
    }
    await sleep(1_000); // ⏳ espera 1 segundo antes del siguiente comprobante
    }

    Este patrón se llama throttling del lado del cliente y es una buena práctica estándar en integraciones que manejan operaciones masivas. Garantiza que tu proceso sea estable, predecible y fácil de depurar en caso de errores.

    Notas

    • Las imágenes del comprobante deben ser accesibles públicamente vía HTTPS al momento de la solicitud.
    • Las URLs pre-firmadas son compatibles siempre que sigan vigentes durante el procesamiento.