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.
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.pdfBase URL
Todas las rutas son relativas a tu host. En estos ejemplos:
http://localhost:8000Autenticació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étodo | Ejemplo |
|---|---|
Header X-API-Key | X-API-Key: TU_API_KEY |
| Bearer token | Authorization: Bearer TU_API_KEY |
| Query param (para descargas) | ?api_key=TU_API_KEY |
401 unauthorized.
¿Necesitas una API key para tu software? Solicítala en ceppro.mx.
Health
Verifica que el servicio está disponible.
curl $BASE/api/health
const r = await fetch("$BASE/api/health");
console.log(await r.json());
import requests
requests.get("$BASE/api/health").json()
Respuesta 200
{ "status": "ok", "version": "0.1.0" }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
const banks = await (await fetch("$BASE/api/banks")).json();
import requests
banks = requests.get("$BASE/api/banks").json()
Respuesta 200
[
{ "code": "40002", "name": "BANAMEX" },
{ "code": "40012", "name": "BBVA BANCOMER" },
{ "code": "90684", "name": "TRANSFER" }
]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"
}'
const res = await fetch("$BASE/api/cep/validate", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": "TU_API_KEY" },
body: JSON.stringify({
fecha: "2026-06-10",
clave_rastreo: "085909274480316161",
emisor: "40002", receptor: "90684",
cuenta: "684180142033702249", monto: "9000.00"
})
});
const cep = await res.json();
import requests
cep = requests.post("$BASE/api/cep/validate",
headers={"X-API-Key": "TU_API_KEY"},
json={
"fecha": "2026-06-10",
"clave_rastreo": "085909274480316161",
"emisor": "40002", "receptor": "90684",
"cuenta": "684180142033702249", "monto": "9000.00",
}).json()
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..."
}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 quevalidate. 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
const body = {
fecha: "2026-06-10", clave_rastreo: "085909274480316161",
emisor: "40002", receptor: "90684",
cuenta: "684180142033702249", monto: "9000.00"
};
const res = await fetch("$BASE/api/cep/download?formato=PDF", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": "TU_API_KEY" },
body: JSON.stringify(body)
});
const blob = await res.blob();
import requests
r = requests.post("$BASE/api/cep/download",
params={"formato": "PDF"},
headers={"X-API-Key": "TU_API_KEY"},
json={
"fecha": "2026-06-10", "clave_rastreo": "085909274480316161",
"emisor": "40002", "receptor": "90684",
"cuenta": "684180142033702249", "monto": "9000.00",
})
open("cep.pdf", "wb").write(r.content)
Respuesta: el archivo binario con
Content-Type application/pdf · application/xml ·
application/zip y Content-Disposition: attachment.
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.
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"
const fd = new FormData();
fd.append("files", file1);
fd.append("files", file2);
const res = await fetch("$BASE/api/cep/batch", {
method: "POST", headers: { "X-API-Key": "TU_API_KEY" }, body: fd
});
const { items } = await res.json();
import requests
files = [
("files", open("comprobante1.pdf", "rb")),
("files", open("captura2.png", "rb")),
]
r = requests.post("$BASE/api/cep/batch",
headers={"X-API-Key": "TU_API_KEY"}, files=files).json()
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.
| Campo | Tipo | Descripción | |
|---|---|---|---|
fecha | string | REQ | Fecha de operación, formato YYYY-MM-DD. |
clave_rastreo | string | REQ | Clave 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. |
emisor | string | REQ | Código del banco emisor (ver /api/banks). |
receptor | string | REQ | Código del banco receptor. |
cuenta | string | REQ | Cuenta beneficiaria: CLABE, tarjeta o teléfono. |
monto | string | REQ | Monto en pesos, p. ej. 9000.00. |
formato | string | OPC | Solo 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).
| HTTP | error | Significado |
|---|---|---|
401 | unauthorized | API key faltante o inválida (cuando el servidor tiene auth activada). |
404 | not_found | Banxico no encontró una transferencia con esos datos. |
409 | cep_pending | Banxico identificó el pago, pero el CEP aún no está disponible (reintenta más tarde). |
409 | cep_status | Banxico encontró la operación, pero está en un estado sin CEP descargable (p. ej. devuelta). Incluye estado cuando se reconoce. |
422 | — | Parámetros inválidos o faltantes (validación). |
502 | banxico_unavailable | Banxico no respondió o devolvió un error transitorio. |
503 | captcha_enforced | Banxico exige captcha (rate-limiting); reintenta más tarde. |
503 | busy | Servicio 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_enforcedy503 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_pendingsignifica que el pago existe pero el CEP aún no está listo: reintenta más tarde (minutos/horas), no de inmediato.409 cep_statussignifica que la operación existe pero está en un estado sin CEP descargable (p. ej. devuelta): no reintentes, revisa el campoestadoy eldetailque Banxico reporta.- Evita ráfagas concurrentes desde una sola IP; encola y procesa a un ritmo moderado para no disparar el captcha de Banxico.