{"openapi":"3.1.0","info":{"title":"Valida API","version":"1.0.0-mvp","summary":"Validacion SARLAFT contra listas vinculantes y de referencia","description":"\nAPI de Valida — producto standalone de MeTRIK SAS para validacion contra listas SARLAFT.\n\n## Alcance normativo (4 tiers)\n\n- **Tier 1 VINCULANTE** (obligacion legal): ONU Consolidated + Lista CSN Colombia\n- **Tier 2 OBLIGATORIA CONSTRUIR**: PEP Colombia (SIGEP + declaracion)\n- **Tier 3 NO VINCULANTE estandar de facto**: OFAC SDN, EU Consolidated\n- **Tier 4 KYC Nacional**: capa de debida diligencia colombiana (pendiente legal)\n\nVer `cerebro/reglas/valida-alcance-normativo.md` para fundamento legal completo.\n\n## Autenticacion\n\nTodas las rutas `/v1/` requieren `Authorization: Bearer <api_key>`. Las api_keys se emiten por cliente (workspace ONE o externo) con hash SHA-256 en BD.\n\n## Disclaimer obligatorio\n\nValida es herramienta tecnologica de consulta automatizada. NO constituye asesoria juridica ni sustituye el Sistema SARLAFT/SAGRILAFT/SIPLAFT del sujeto obligado. La responsabilidad de analisis de matches, decision de vinculacion y reporte ROS a UIAF permanece integramente en el sujeto obligado (Concepto SFC 2011041962-001, Ley 1121/2006 Art. 20, Decreto 830/2021).\n\n## Uso responsable\n\nEl resultado incluye matches con tier explicito. El cliente debe interpretar el score junto con el tier:\n- `exacto` (score >= 0.95) en lista `vinculante_colombia=true`: bloqueo SARLAFT casi cierto\n- `posible` (score entre 0.70 y 0.95): requiere analisis manual del Oficial de Cumplimiento\n- `sin_match`: no se incluye en respuesta\n","contact":{"name":"MeTRIK SAS","email":"mauricio.moreno@metrik.com.co","url":"https://www.metrik.com.co"},"license":{"name":"Proprietary — MeTRIK SAS","identifier":"LicenseRef-MeTRIK-Commercial"}},"servers":[{"url":"https://api.valida.metrikone.co","description":"Produccion"},{"url":"http://localhost:3000","description":"Desarrollo local"}],"tags":[{"name":"Validacion","description":"Consulta de personas y entidades contra listas"},{"name":"Reportes","description":"Reportes PDF auditables con QR de verificacion"},{"name":"Salud","description":"Estado del servicio"},{"name":"Admin","description":"Operaciones internas (ingesta, versionado)"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/health":{"get":{"tags":["Salud"],"summary":"Estado del servicio","security":[],"responses":{"200":{"description":"Servicio operativo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/validate":{"post":{"tags":["Validacion"],"summary":"Consulta puntual contra todas las listas configuradas","description":"Valida una persona natural o juridica contra todas las listas activas con version vigente. Persiste la consulta por 5 anos (Ley 1581/2012). Retorna matches con score combinado (Jaro-Winkler 70% + Levenshtein 30%) sobre nombre y aliases normalizados.\n\n**Rate limiting:** el plan beta permite 1000 consultas/dia. Planes comerciales: ver `/pricing`.\n\n**Idempotencia:** no se aplica. Cada llamada genera nueva `consulta_id` y nuevo hash de reporte.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"},"examples":{"natural":{"summary":"Persona natural colombiana","value":{"tipo":"natural","nombre":"Juan Perez Gomez","documento":{"tipo":"CC","numero":"1077089147"},"fecha_nacimiento":"1985-03-15","pais":"CO"}},"juridica":{"summary":"Persona juridica","value":{"tipo":"juridica","nombre":"Acme Trading SAS","documento":{"tipo":"NIT","numero":"900123456"}}}}}}},"responses":{"200":{"description":"Validacion completada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResponse"}}}},"400":{"description":"Payload invalido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"API key invalida o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error de persistencia","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reporte/{consulta_id}":{"get":{"tags":["Reportes"],"summary":"Descarga PDF del reporte auditable","description":"Genera un PDF con branding Valida + diferenciacion visual de tier + QR de verificacion + hash de integridad. El PDF es reproducible: cualquier consulta_id puede regenerarse desde la BD con los mismos datos.","parameters":[{"name":"consulta_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PDF del reporte","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"API key invalida"},"404":{"description":"Consulta no encontrada o no pertenece al cliente"}}}},"/api/v1/consultas":{"get":{"tags":["Validacion"],"summary":"Listar consultas historicas del cliente","description":"Retorna las consultas mas recientes del cliente autenticado con resumen de severidad y total de matches.","parameters":[{"name":"limite","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"desde","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"severidad","in":"query","schema":{"type":"string","enum":["alto","medio","bajo","sin_hallazgo"]}}],"responses":{"200":{"description":"Lista de consultas","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"consultas":{"type":"array","items":{"$ref":"#/components/schemas/ConsultaResumen"}}}}}}}}}},"/api/admin/ingesta/{slug}":{"post":{"tags":["Admin"],"summary":"Disparar corrida de ingesta para una lista","description":"Requiere `Authorization: Bearer <VALIDA_ADMIN_TOKEN>`. Ejecuta el adapter correspondiente y versiona por hash SHA-256. Idempotente — si el contenido no cambio, devuelve `sin_cambios`.","security":[{"adminToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","enum":["onu_consolidated","ofac_sdn","eu_consolidated","pep_colombia"]}}],"responses":{"200":{"description":"Corrida completada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestaResult"}}}},"401":{"description":"Admin token invalido"},"404":{"description":"Slug no registrado"},"500":{"description":"Error de ingesta"}}},"get":{"tags":["Admin"],"summary":"Listar adapters disponibles","security":[{"adminToken":[]}],"responses":{"200":{"description":"Slugs disponibles","content":{"application/json":{"schema":{"type":"object","properties":{"disponibles":{"type":"array","items":{"type":"string"}}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Bearer <api_key>","description":"API key emitida por MeTRIK al cliente. Se envia en header `Authorization: Bearer <key>`."},"adminToken":{"type":"http","scheme":"bearer","description":"Token admin de Valida para operaciones de ingesta. Distinto de api_key de cliente."}},"schemas":{"HealthResponse":{"type":"object","required":["status","service","version","timestamp"],"properties":{"status":{"type":"string","example":"ok"},"service":{"type":"string","example":"valida"},"version":{"type":"string","example":"0.1.0"},"timestamp":{"type":"string","format":"date-time"}}},"ValidateRequest":{"type":"object","required":["tipo","nombre"],"properties":{"tipo":{"type":"string","enum":["natural","juridica"]},"nombre":{"type":"string","minLength":2,"description":"Nombre completo (natural) o razon social (juridica)."},"documento":{"type":"object","description":"Opcional. Si se incluye y hay match por documento, severidad escala automaticamente.","required":["tipo","numero"],"properties":{"tipo":{"type":"string","enum":["CC","CE","NIT","PAS"]},"numero":{"type":"string","minLength":3}}},"fecha_nacimiento":{"type":"string","format":"date","description":"YYYY-MM-DD. Opcional para personas naturales."},"pais":{"type":"string","minLength":2,"maxLength":2,"description":"ISO 3166-1 alpha-2."}}},"ValidateResponse":{"type":"object","required":["consulta_id","severidad","total_matches","matches","hash_reporte","fecha_reporte","cliente"],"properties":{"consulta_id":{"type":"string","format":"uuid"},"severidad":{"type":"string","enum":["alto","medio","bajo","informativo","sin_hallazgo"]},"total_matches":{"type":"integer","minimum":0},"matches":{"type":"array","items":{"$ref":"#/components/schemas/MatchItem"}},"hash_reporte":{"type":"string","description":"SHA-256 hex del reporte para verificacion."},"consultado":{"$ref":"#/components/schemas/ValidateRequest"},"fecha_reporte":{"type":"string","format":"date-time"},"cliente":{"type":"string","description":"Nombre del cliente que emitio la consulta."}}},"MatchItem":{"type":"object","required":["lista","lista_nombre","tier","vinculante_colombia","nombre_coincidencia","score","resultado"],"properties":{"lista":{"type":"string","description":"Slug unico de la lista."},"lista_nombre":{"type":"string"},"tier":{"type":"string","enum":["1_vinculante","2_obligatoria","3_referencia","4_kyc_nacional"],"description":"Tier normativo de la lista."},"vinculante_colombia":{"type":"boolean"},"nombre_coincidencia":{"type":"string","description":"Nombre o alias de la entrada que genero el match."},"score":{"type":"number","minimum":0,"maximum":1,"description":"Score combinado JW 70% + Lev 30%."},"resultado":{"type":"string","enum":["exacto","posible"]},"fundamento_legal":{"type":"string","nullable":true,"description":"Referencia o programa que justifica la inclusion en lista."}}},"ConsultaResumen":{"type":"object","properties":{"consulta_id":{"type":"string","format":"uuid"},"nombre_consultado":{"type":"string"},"documento_consultado":{"type":"string","nullable":true},"severidad":{"type":"string"},"total_matches":{"type":"integer"},"creada_en":{"type":"string","format":"date-time"}}},"IngestaResult":{"type":"object","properties":{"lista_slug":{"type":"string"},"estado":{"type":"string","enum":["ok","sin_cambios","nueva_version","timeout","http_error","parse_error","cambio_estructura"]},"version_id":{"type":"string","format":"uuid","nullable":true},"total_entradas":{"type":"integer","nullable":true},"diff_altas":{"type":"integer","nullable":true},"diff_bajas":{"type":"integer","nullable":true},"mensaje":{"type":"string","nullable":true}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}}},"ValidationError":{"type":"object","properties":{"error":{"type":"string","example":"validation_error"},"issues":{"type":"array","items":{"type":"object"}}}}}}}