Arquitecturas de datos: cómo definir contratos de SLA internos cuando el dato viene de APIs externas
Arquitecturas de datos: cómo definir contratos de SLA internos cuando el dato viene de APIs externas
Hay un error de diseño que se repite con más frecuencia de la que debería: confundir el SLA del proveedor de datos con el SLA del pipeline propio. Son dos cosas distintas. El SLA del proveedor mide lo que él garantiza. El SLA interno mide lo que tu arquitectura entrega al consumidor final. Ningún proveedor puede sustituir al segundo.
Cuando el dato proviene de APIs externas —señales del universo público, feeds de menciones, resultados de análisis derivado— el equipo técnico tiende a trasladar la responsabilidad hacia upstream. Si el proveedor responde en menos de 500 ms con un 99,5 % de disponibilidad, se asume que el pipeline entregará algo similar. Esa suposición es incorrecta y en producción genera incidentes que tardan días en diagnosticarse.
Diseñar contratos de SLA internos explícitos es la diferencia entre una arquitectura reactiva y una arquitectura que puede comprometer entregas a otros sistemas, a equipos de negocio y a clientes.
Por qué el SLA externo no viaja por el pipeline
Entre la llamada a una API externa y el dato consumible por el analista o el modelo hay, como mínimo: lógica de paginación, normalización de esquema, enriquecimiento, almacenamiento intermedio y en muchos casos una cola asíncrona. Cada capa añade latencia variable y puntos de fallo propios.
Supón que tu proveedor garantiza disponibilidad del 99,5 % mensual. Eso equivale a hasta 3,6 horas de caída al mes. Si además tu pipeline tiene un procesamiento asíncrono con reintentos cada 5 minutos y una ventana de disponibilidad de 2 horas para el consumidor, el SLA real que puedes garantizar internamente es significativamente inferior. La aritmética de disponibilidades en cascada es multiplicativa, no aditiva.
El dato llega degradado en tiempo, en frescura o en completitud sin que nadie haya definido cuál de esas tres dimensiones es la más crítica para el caso de uso.
Las tres dimensiones del contrato interno
Un contrato de SLA interno para pipelines con datos externos debe cubrir al menos tres dimensiones:
1. Latencia de entrega. ¿Cuánto tiempo puede pasar entre que el dato existe en la fuente y que está disponible para el consumidor? Esto no es solo latencia de red; incluye tiempo de procesamiento, encolado y reintentos. Define un percentil (p95, p99), no una media. La media oculta los casos que rompen flujos críticos.
2. Frescura del dato. ¿Cuál es la antigüedad máxima aceptable del dato en el momento de consumo? En flujos de análisis de menciones o tendencias, un dato con 4 horas de antigüedad puede ser perfectamente válido para análisis de tendencia semanal y completamente inútil para una alerta de crisis en tiempo real. El contrato debe especificar la ventana temporal aceptable por caso de uso, no por pipeline.
3. Completitud. ¿Qué porcentaje de los registros esperados debe estar presente para que el lote se considere válido? Si tu pipeline procesa señales de múltiples fuentes y una falla parcialmente, ¿cuándo activas el circuito de alerta? Sin un umbral explícito, el pipeline sigue corriendo con datos incompletos sin que nadie lo sepa.
Cómo instrumentar el contrato sin sobreingeniería
El error habitual al intentar implementar esto es construir un sistema de monitorización complejo antes de tener los umbrales correctos. Empieza simple:
# Ejemplo mínimo: validación de frescura antes de procesar el lote
from datetime import datetime, timezone, timedelta
MAX_FRESHNESS_HOURS = 2 # definido en el contrato interno
def validate_freshness(records: list[dict]) -> bool:
now = datetime.now(timezone.utc)
cutoff = now - timedelta(hours=MAX_FRESHNESS_HOURS)
stale = [r for r in records if r["published_at"] < cutoff]
ratio_stale = len(stale) / len(records) if records else 1.0
if ratio_stale > 0.1: # más del 10 % de registros fuera de ventana
raise ValueError(f"Lote con {ratio_stale:.0%} de datos fuera de ventana de frescura")
return True
Este fragmento hace una sola cosa: verificar que el lote no tiene más de un 10 % de registros fuera de la ventana de frescura definida en el contrato. Si lo supera, el pipeline no procesa. Esa decisión —no procesar en lugar de procesar con datos degradados— es el núcleo del contrato.
Lo mismo aplica para completitud: define cuántos registros esperas por ventana temporal (basándote en histórico) y rechaza el lote si el volumen cae por debajo del umbral acordado. No sigas procesando en silencio.
Dónde viven los contratos y quién los firma
El contrato de SLA interno no debe vivir solo en el código. Debe existir como documento explícito, versionado junto al esquema del pipeline, y revisado cuando cambia el proveedor, el caso de uso o el consumidor.
Un formato mínimo viable:
pipeline: mentions_enrichment
version: "2.1"
consumer: sentiment_dashboard
sla:
latency_p95_minutes: 15
freshness_max_hours: 2
completeness_min_ratio: 0.90
breach_action: halt_and_alert
upstream_dependency: external_api_v3
reviewed_at: "2026-08-30"
Ese YAML se convierte en la referencia cuando hay un incidente. El equipo no debate si el pipeline debería haber seguido corriendo; la respuesta ya está en el documento. También facilita la conversación con el proveedor externo: si su API introduce una degradación que rompe sistemáticamente tu contrato interno, tienes los datos para abrir una conversación técnica fundamentada.
Herramientas como FeedScale exponen métricas de consumo que permiten construir esa línea base histórica sin instrumentación adicional en el lado del proveedor.
El SLA interno como herramienta de diseño, no de auditoría
La trampa más frecuente es tratar el contrato de SLA interno como un documento de auditoría posterior al incidente. Su valor real es preventivo: obliga al equipo a tomar decisiones de diseño explícitas antes de llegar a producción.
¿Cuánto tiempo puede aguantar el consumidor sin dato fresco? ¿Qué pasa si el proveedor externo introduce un retraso de 30 minutos sin previo aviso? ¿El pipeline tiene circuit breaker o sigue encolando trabajo indefinidamente?
Esas preguntas, respondidas con números en lugar de intuiciones, son las que distinguen una arquitectura que aguanta de una que solo funciona cuando todo va bien. Y en pipelines que dependen de APIs externas para el procesamiento de señales públicas, la variabilidad del upstream es la norma, no la excepción.
Define el contrato antes de conectar el primer endpoint. Cuando ya estás en producción, el coste de haberlo omitido se paga con incidentes, no con documentos.