API de validación documental: guía para desarrolladores
Integre la validación documental en su aplicación: API REST, webhooks, ejemplos de código en Python y Node.js. Guía técnica para desarrolladores.

Resumir este artículo con
La API de validación documental de CheckFile sigue un modelo REST asíncrono: los documentos se cargan vía POST /v1/files, se procesan en una cola de IA (OCR + detección de fraude + motor de reglas) y los resultados se entregan en 2-15 segundos mediante polling o webhooks. Esta guía cubre autenticación, endpoints, ejemplos de código en Python y Node.js, payloads de webhook, gestión de errores y patrones de integración que escalan de prototipo a producción. El Reglamento (UE) 2024/1624 (AMLR), aplicable desde julio de 2027, exige que las entidades obligadas documenten cada verificación documental -- requisito que la API satisface de forma nativa mediante registros de auditoría inmutables.
Arquitectura general
La API de CheckFile sigue un modelo estándar de procesamiento asíncrono. Cada petición es trazable desde la carga hasta el veredicto, cumpliendo los requisitos de auditabilidad del Reglamento (UE) 2024/1624 sobre prevención del blanqueo de capitales. Los documentos se cargan vía REST, se encolan para análisis con IA, y los resultados se entregan mediante polling o callbacks de webhook. Esta arquitectura desacoplada permite al sistema procesar documentos a escala sin bloquear su aplicación.
+-------------------+
| API de resultados|
| GET /files/{id} |
+--------^----------+
|
App cliente | Poll o consulta
| |
| POST /v1/files +-------+--------+
+------------------------------->| API de carga |
| +-------+--------+
| |
| v
| +--------+--------+
| | Cola de proceso |
| | (validación IA) |
| +--------+--------+
| |
| Callback webhook |
|<---------------------------------------+
| POST su-endpoint
Tres decisiones de diseño clave dan forma a esta arquitectura:
-
Asíncrono por defecto. La validación documental implica OCR, detección de fraude, cruce de referencias y evaluación de reglas. Estas operaciones tardan de 2 a 15 segundos según la complejidad del documento. La API acepta las cargas inmediatamente y las procesa en segundo plano.
-
Entrega dual. Puede consultar el endpoint de estado o registrar un webhook. El polling funciona para integraciones sencillas; los webhooks son el enfoque recomendado para sistemas en producción que procesan más de unos pocos documentos por minuto.
-
Cargas idempotentes. Cada carga devuelve un
file_idúnico. Recargar el mismo documento con la misma clave de idempotencia devuelve el resultado existente en lugar de reprocesarlo, ahorrando tiempo y créditos de API.
Autenticación y seguridad
Todas las peticiones a la API requieren autenticación mediante clave API (servidor a servidor) u OAuth 2.0 (acceso con ámbito de usuario). La API impone TLS 1.3 en todos los canales y rechaza conexiones con TLS 1.2 o anterior.
Las directrices OWASP API Security Top 10 2023 clasifican la autenticación rota (API2:2023) como una de las principales vulnerabilidades en APIs de producción; el uso de firmas HMAC-SHA256 en webhooks y claves API por entorno mitiga este riesgo de forma directa.
Autenticación por clave API
Para integraciones servidor a servidor, pase su clave API en el header X-API-Key:
curl -H "X-API-Key: ck_live_abc123..." \
https://api.checkfile.ai/v1/files
Las claves API están limitadas a su organización. Puede generar múltiples claves en el panel --una por entorno (desarrollo, staging, producción) es la práctica recomendada. Las claves con prefijo ck_test_ apuntan al entorno sandbox; las claves con prefijo ck_live_ apuntan a producción.
OAuth 2.0 para acceso con ámbito de usuario
Si su aplicación actúa en nombre de usuarios finales (por ejemplo, un SaaS multi-tenant), utilice OAuth 2.0 con el flujo de código de autorización. Esto proporciona pistas de auditoría a nivel de usuario y control granular de permisos.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=CODIGO_AUTH
&client_id=SU_CLIENT_ID
&client_secret=SU_CLIENT_SECRET
&redirect_uri=https://suapp.com/callback
Los tokens de acceso expiran tras 1 hora. Utilice el refresh token para obtener nuevos tokens de acceso sin reautenticarse.
Límites de tasa
Los límites de tasa se aplican por clave API, medidos en peticiones por minuto:
| Plan | Límite de tasa | Ráfaga permitida | Cargas concurrentes |
|---|---|---|---|
| Starter | 100 req/min | 150 req/min (ventana de 30s) | 5 |
| Business | 500 req/min | 750 req/min (ventana de 30s) | 25 |
| Enterprise | Ilimitado | Ilimitado | Ilimitado |
Cuando supera el límite de tasa, la API devuelve 429 Too Many Requests con un header Retry-After indicando cuántos segundos esperar. Consulte los precios para detalles de los planes.
Seguridad de transporte
Todo el tráfico está cifrado con TLS 1.3. La API rechaza conexiones que utilicen TLS 1.2 o anterior. El certificate pinning está disponible para clientes Enterprise. Todos los documentos cargados se cifran en reposo con AES-256 y se eliminan automáticamente tras el período de retención configurado en los ajustes de su cuenta. Más información sobre nuestras prácticas de seguridad.
Endpoints principales
La API expone seis endpoints REST bajo la URL base https://api.checkfile.ai, versionados en la ruta (/v1). Todos devuelven JSON; los endpoints de carga aceptan multipart/form-data.
| Método | Endpoint | Descripción |
|---|---|---|
POST |
/api/v1/files |
Cargar un documento individual para validación |
POST |
/api/v1/files/batch |
Cargar múltiples archivos como expediente |
GET |
/api/v1/files/{id}/status |
Consultar estado de procesamiento de una carga |
GET |
/api/v1/files/{id}/results |
Obtener resultados de validación |
POST |
/api/v1/rules |
Configurar reglas de negocio personalizadas |
GET |
/api/v1/webhooks |
Listar endpoints de webhook registrados |
Todos los endpoints aceptan y devuelven JSON (excepto los de carga de archivos, que aceptan multipart/form-data). La URL base es https://api.checkfile.ai. El versionado de la API se basa en la ruta; la versión estable actual es v1.
Cargar y validar -- Paso a paso
El flujo de trabajo más común es: cargar documentos, esperar al procesamiento, obtener resultados. Aquí está el flujo completo en Python y Node.js.
Python (requests)
import requests
import time
API_KEY = "ck_live_abc123..."
BASE_URL = "https://api.checkfile.ai/v1"
HEADERS = {"X-API-Key": API_KEY}
# Paso 1: Cargar un lote de documentos como expediente
response = requests.post(
f"{BASE_URL}/files/batch",
headers=HEADERS,
files=[
("files", ("contrato.pdf", open("contrato.pdf", "rb"), "application/pdf")),
("files", ("acuerdo.pdf", open("acuerdo.pdf", "rb"), "application/pdf")),
("files", ("nota_simple.pdf", open("nota_simple.pdf", "rb"), "application/pdf")),
],
data={"rule_set": "equipment-leasing"}
)
response.raise_for_status()
file_id = response.json()["id"]
print(f"Expediente cargado: {file_id}")
# Paso 2: Consultar hasta completarse
while True:
status_resp = requests.get(
f"{BASE_URL}/files/{file_id}/status",
headers=HEADERS
)
status = status_resp.json()["status"]
if status in ("completed", "failed"):
break
time.sleep(2) # Consultar cada 2 segundos
# Paso 3: Obtener resultados
results = requests.get(
f"{BASE_URL}/files/{file_id}/results",
headers=HEADERS
).json()
for doc in results["documents"]:
print(f"{doc['filename']}: {doc['verdict']} (confianza: {doc['confidence']})")
if doc["alerts"]:
for alert in doc["alerts"]:
print(f" - {alert['severity']}: {alert['message']}")
Node.js (fetch + FormData)
import fs from 'node:fs';
const API_KEY = process.env.CHECKFILE_API_KEY;
const BASE_URL = 'https://api.checkfile.ai/v1';
// Paso 1: Cargar un lote de documentos
const form = new FormData();
form.append('files', new Blob([fs.readFileSync('contrato.pdf')]), 'contrato.pdf');
form.append('files', new Blob([fs.readFileSync('acuerdo.pdf')]), 'acuerdo.pdf');
form.append('files', new Blob([fs.readFileSync('nota_simple.pdf')]), 'nota_simple.pdf');
form.append('rule_set', 'equipment-leasing');
const uploadRes = await fetch(`${BASE_URL}/files/batch`, {
method: 'POST',
headers: { 'X-API-Key': API_KEY },
body: form,
});
const { id: fileId } = await uploadRes.json();
console.log(`Expediente cargado: ${fileId}`);
// Paso 2: Consultar hasta completarse
let status = 'processing';
while (status !== 'completed' && status !== 'failed') {
await new Promise((r) => setTimeout(r, 2000));
const statusRes = await fetch(`${BASE_URL}/files/${fileId}/status`, {
headers: { 'X-API-Key': API_KEY },
});
({ status } = await statusRes.json());
}
// Paso 3: Obtener resultados
const results = await fetch(`${BASE_URL}/files/${fileId}/results`, {
headers: { 'X-API-Key': API_KEY },
}).then((r) => r.json());
for (const doc of results.documents) {
console.log(`${doc.filename}: ${doc.verdict} (confianza: ${doc.confidence})`);
for (const alert of doc.alerts) {
console.log(` - ${alert.severity}: ${alert.message}`);
}
}
Ambos ejemplos siguen el mismo patrón de tres pasos: cargar, consultar, obtener. Para sistemas en producción, sustituya el bucle de polling por un listener de webhook (cubierto en la siguiente sección).
Payloads de webhook
Los webhooks eliminan el polling y son el método recomendado para sistemas en producción que procesan más de 10 expedientes por minuto.
El AMLR (Reglamento UE 2024/1624), en vigor desde julio de 2027, exige que las entidades obligadas conserven registros de cada verificación documental durante 5 años -- los payloads de webhook con timestamp, file_id y verdict constituyen la evidencia de auditoría exigida por el Art. 77 del reglamento. Registre una URL de webhook en el panel o vía la API, y CheckFile enviará un payload JSON firmado a su endpoint cuando el procesamiento se complete o se detecte una alerta.
Evento de validación completada
{
"event": "validation.completed",
"timestamp": "2026-02-09T14:32:08Z",
"data": {
"file_id": "dossier_8f3a2b1c",
"rule_set": "equipment-leasing",
"verdict": "approved",
"processing_time_ms": 4280,
"documents": [
{
"filename": "contrato.pdf",
"type": "contract",
"verdict": "valid",
"confidence": 0.97,
"alerts": []
},
{
"filename": "acuerdo.pdf",
"type": "agreement",
"verdict": "valid",
"confidence": 0.95,
"alerts": []
},
{
"filename": "nota_simple.pdf",
"type": "company_registration",
"verdict": "valid",
"confidence": 0.99,
"alerts": []
}
]
}
}
Evento de alerta detectada
Cuando la IA detecta un posible problema durante la validación, se dispara un evento de alerta inmediatamente --antes de que la validación completa termine. Esto permite a su aplicación reaccionar a incidencias de alta severidad en tiempo real.
{
"event": "validation.alert",
"timestamp": "2026-02-09T14:32:06Z",
"data": {
"file_id": "dossier_8f3a2b1c",
"document": {
"filename": "nota_simple.pdf",
"type": "company_registration"
},
"alert": {
"code": "DOC_EXPIRED",
"severity": "high",
"message": "La Nota Simple del Registro Mercantil caducó el 30/11/2025",
"field": "validity_date",
"extracted_value": "2025-11-30",
"expected": "El documento debe tener menos de 3 meses de antigüedad"
}
}
}
Verificación de firmas de webhook
Cada petición de webhook incluye un header X-Checkfile-Signature que contiene una firma HMAC-SHA256. Verifíquelo contra su secreto de webhook para asegurarse de que el payload no ha sido manipulado:
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
Buenas prácticas de gestión de errores
La API devuelve códigos de estado HTTP estándar. Los errores de cliente (4xx) no deben reintentarse sin corrección; los errores de servidor (5xx) deben gestionarse con backoff exponencial con jitter.
| Código | Significado | Causa | Acción recomendada |
|---|---|---|---|
400 |
Petición incorrecta | Cuerpo malformado, tipo de archivo no soportado, campo requerido ausente | Corrija la petición. Consulte el campo error.details para detalles. |
401 |
No autorizado | Clave API inválida o ausente | Verifique su clave API. Compruebe espacios o truncamiento. |
413 |
Payload demasiado grande | El archivo supera el límite de 50 MB por documento | Comprima el archivo o divida documentos multipágina. |
429 |
Demasiadas peticiones | Límite de tasa excedido | Espere según el valor del header Retry-After. |
500 |
Error interno del servidor | Fallo inesperado del servidor | Reintente con backoff exponencial. Si persiste, contacte con soporte. |
Estrategia de reintentos con backoff exponencial
Para errores transitorios (429, 500, 502, 503), implemente backoff exponencial con jitter:
import time
import random
import requests
def api_request_with_retry(method, url, max_retries=5, **kwargs):
for attempt in range(max_retries):
response = requests.request(method, url, **kwargs)
if response.status_code < 400:
return response
if response.status_code in (429, 500, 502, 503):
base_delay = min(2 ** attempt, 60) # Tope en 60 segundos
jitter = random.uniform(0, base_delay * 0.5)
delay = base_delay + jitter
if response.status_code == 429:
retry_after = response.headers.get("Retry-After")
if retry_after:
delay = float(retry_after)
time.sleep(delay)
continue
# Error no reintenible
response.raise_for_status()
raise Exception(f"Máximo de reintentos excedido para {url}")
Principios clave: nunca reintente errores 400 del cliente (excepto 429), siempre respete el header Retry-After, y añada jitter para evitar problemas de rebaño cuando múltiples clientes reintentan simultáneamente.
Patrones de integración
Tres patrones cubren la mayoría de escenarios de integración. La latencia típica de un documento individual es de 2-4 segundos; un expediente de 8-12 documentos con el conjunto de reglas de leasing de equipos tarda una media de 12 segundos (P95: 28 segundos).
Patrón 1: Validación en tiempo real (Cargar, Consultar, Mostrar)
Ideal para: flujos orientados al usuario donde el usuario final espera resultados (por ejemplo, formularios de onboarding).
El usuario envía el documento
|
v
POST /v1/files --> devuelve file_id
|
v
GET /v1/files/{id}/status (consultar cada 2s)
|
v
status == "completed"
|
v
GET /v1/files/{id}/results --> mostrar al usuario
Latencia típica: 3-8 segundos para un solo documento. Muestre un indicador de progreso al usuario. Si el procesamiento supera los 15 segundos, muestre un mensaje y ofrezca notificar por email.
Patrón 2: Procesamiento por lotes (Cargar lote, Notificación por webhook)
Ideal para: flujos de back-office que procesan grandes volúmenes (por ejemplo, importaciones nocturnas, onboarding masivo).
El sistema carga N expedientes
|
v
POST /v1/files/batch (para cada expediente)
|
v
La cola de procesamiento gestiona todos los expedientes
|
v
El webhook se dispara para cada expediente completado
|
v
Su handler de webhook actualiza la base de datos interna
Este patrón desacopla completamente el envío del procesamiento. Su sistema envía y se olvida, y luego reacciona a los eventos de webhook. Para lotes muy grandes (más de 1.000 expedientes), escalone las cargas a 50 por minuto para mantenerse dentro de los límites de tasa y evitar sobrecargar su propio handler de webhook.
Patrón 3: Integración CRM (Salesforce, HubSpot, personalizado)
Ideal para: equipos que gestionan expedientes de clientes dentro de un CRM y quieren que el estado de validación se sincronice automáticamente.
El CRM desencadena la carga (p. ej., cambio de etapa del negocio)
|
v
El middleware llama a POST /v1/files/batch
|
v
El webhook se dispara al completarse
|
v
El middleware mapea el resultado a campos del CRM
|
v
El registro del CRM se actualiza (campos personalizados: validation_status, alerts)
La capa de middleware (una función serverless ligera o una plataforma de integración como Zapier/Make) traduce entre la API de CheckFile y el modelo de datos de su CRM. Mapeos de campos de CRM habituales:
| Campo CheckFile | Campo CRM | Ejemplo de valor |
|---|---|---|
verdict |
Estado de validación | Aprobado / Requiere revisión / Rechazado |
documents[].alerts |
Notas de validación | "DNI/NIE caducado el 30/11/2025" |
processing_time_ms |
Duración de procesamiento | 4280 |
confidence |
Puntuación de confianza | 0,97 |
Benchmarks de rendimiento
Los tiempos de procesamiento reflejan el pipeline completo: OCR, análisis de IA, cruce de referencias y evaluación de reglas. Los benchmarks siguientes se midieron en infraestructura de producción bajo carga típica; el tiempo de carga de red no está incluido.
El SEPBLAC (Servicio Ejecutivo de la Comisión de Prevención del Blanqueo de Capitales) señala que la automatización de la diligencia debida documental reduce el tiempo de verificación hasta un 80 % respecto al proceso manual, cumpliendo los requisitos de inmediatez del Art. 20 del Reglamento (UE) 2024/1624.
| Escenario | N.o de documentos | Conjunto de reglas | Tiempo medio de procesamiento | Tiempo P95 |
|---|---|---|---|---|
| Documento de identidad individual | 1 | Por defecto | 2,1s | 4,8s |
| Contrato individual (multipágina) | 1 | Por defecto | 3,4s | 6,2s |
| Expediente estándar | 8-12 | Leasing de equipos | 12s | 28s |
| Expediente complejo | 15-20 | Cumplimiento completo | 22s | 45s |
| Lote (100 expedientes) | 800-1.200 | Leasing de equipos | 8 min | 14 min |
| Lote (500 expedientes) | 4.000-6.000 | Leasing de equipos | 35 min | 52 min |
Estos tiempos reflejan el procesamiento de extremo a extremo incluyendo OCR, análisis IA, cruce de referencias y evaluación de reglas. El tiempo de carga (transferencia de red) no está incluido y depende de su velocidad de conexión y del tamaño de los archivos.
Para aplicaciones sensibles a la latencia, dos optimizaciones ayudan:
-
Compresión previa a la carga. Reducir el tamaño de un PDF de 5 MB a 1 MB recorta el tiempo de carga sin afectar la precisión de validación. La API acepta archivos de hasta 50 MB, pero los archivos más pequeños se mueven más rápido por el pipeline.
-
Cargas en paralelo. El endpoint de lotes acepta hasta 20 archivos por petición. Para expedientes más grandes, divida en múltiples peticiones por lotes y cargue en paralelo (dentro de su límite de concurrencia).
Primeros pasos
El camino de cero a una integración funcional en producción sigue cinco pasos secuenciales:
- Cree una cuenta y genere una clave API de prueba (prefijo
ck_test_) desde el panel. - Cargue un documento de prueba usando el ejemplo
curlanterior o los ejemplos de código de esta guía. - Registre un webhook para recibir resultados de forma asíncrona.
- Configure un conjunto de reglas que se ajuste a sus requisitos de negocio.
- Pase a producción reemplazando su clave de prueba por una clave en vivo (prefijo
ck_live_).
La documentación completa de endpoints, SDKs (Python, Node.js, Go) y un explorador de API interactivo están disponibles en docs.checkfile.ai. Si tiene preguntas sobre qué plan se ajusta a su volumen, consulte los precios o contacte directamente con el equipo de ingeniería.
Preguntas frecuentes
¿Cuánto tiempo tarda la API en validar un documento?
El tiempo de procesamiento depende del tipo y complejidad del documento. Un documento de identidad individual se procesa en una media de 2,1 segundos (P95: 4,8 segundos), mientras que un expediente estándar de 8 a 12 documentos con el conjunto de reglas de leasing tarda unos 12 segundos de media (P95: 28 segundos). Estos tiempos incluyen el pipeline completo de OCR, análisis de IA, cruce de referencias y evaluación de reglas, pero no el tiempo de carga de red, que depende del tamaño de los archivos y la velocidad de conexión.
¿Cuál es la diferencia entre usar polling y webhooks para recibir resultados?
El polling consiste en consultar repetidamente el endpoint de estado cada pocos segundos hasta que el procesamiento finalice, lo que es sencillo de implementar pero ineficiente para volúmenes altos. Los webhooks, en cambio, son el método recomendado para producción: CheckFile envía automáticamente un payload JSON firmado a su endpoint cuando el procesamiento se completa, eliminando el bucle de consulta y permitiendo que su sistema reaccione a eventos en tiempo real. Para flujos que procesan más de 10 expedientes por minuto, los webhooks reducen la carga en su infraestructura y garantizan que nunca se pierda un resultado.
¿Cómo puedo verificar que un payload de webhook no ha sido manipulado?
Cada petición de webhook incluye un header X-Checkfile-Signature con una firma HMAC-SHA256 calculada sobre el cuerpo del payload usando su secreto de webhook. Para verificarla, recalcule el HMAC en su servidor usando ese mismo secreto y compare el resultado con el valor del header usando una comparación de tiempo constante como hmac.compare_digest() en Python para evitar ataques de temporización. Esta verificación de firma es una práctica de seguridad obligatoria recomendada por OWASP para cualquier integración de webhook en producción.
¿Los registros de validación generados por la API son suficientes para cumplir con el AMLR?
Sí. El Reglamento AMLR (UE 2024/1624), aplicable desde julio de 2027, exige que las entidades obligadas conserven registros de cada verificación documental durante al menos 5 años. Los payloads de webhook incluyen un timestamp, el file_id único del expediente, el veredicto de validación y los detalles de cada alerta detectada, constituyendo la evidencia de auditoría exigida por el artículo 77 del reglamento. Estos registros son inmutables y trazables, lo que satisface los requisitos de auditabilidad sin necesidad de infraestructura adicional.
¿Cómo debo gestionar los errores de tasa límite (429) en producción?
Cuando supera el límite de tasa de su plan, la API devuelve un error 429 con un header Retry-After que indica cuántos segundos debe esperar antes de reintentar. La mejor práctica es implementar backoff exponencial con jitter para evitar el efecto de manada cuando múltiples instancias de su aplicación reintentan simultáneamente. Nunca reintente errores 400 sin corregir la petición primero, ya que indican un problema en el cuerpo o los parámetros de la solicitud que no se resolverá por sí solo.
Lectura relacionada: Para patrones de integración específicos de ERP, incluyendo Salesforce y SAP, consulte nuestra guía de integración con API, webhooks y ERP. Si está evaluando si construir la validación internamente o usar una API como esta, nuestro análisis de construir vs comprar proporciona una comparación detallada de costes a 3 años. Para buenas prácticas de seguridad de webhooks alineadas con las directrices de seguridad de API OWASP 2023, siempre verifique las firmas HMAC como se muestra en los ejemplos anteriores. Las entidades obligadas bajo el Reglamento (UE) 2024/1624 deben conservar los registros de verificación durante 5 años; los payloads de webhook firmados y el file_id único por expediente satisfacen este requisito de forma nativa.