{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/conversoriaecnae-es/json-schema/conversoriaecnae-es-kyb-enrich-response-schema.json",
  "title": "KybEnrichResponse",
  "description": "Respuesta del endpoint `/kyb/enrich`.",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/conversoriaecnae-es-openapi.yml#/components/schemas/KybEnrichResponse",
  "type": "object",
  "properties": {
    "match": {
      "$ref": "#/$defs/ActivityMatch"
    },
    "classification": {
      "$ref": "#/$defs/ActivityClassification"
    },
    "fiscal_profile": {
      "type": "object",
      "description": "Perfil fiscal de la actividad para evaluación de riesgo KYB.",
      "properties": {
        "sector_riesgo": {
          "type": "string",
          "description": "Nivel de riesgo fiscal del sector (bajo, medio, alto)."
        },
        "iva_regimen": {
          "type": "string",
          "description": "Régimen de IVA aplicable."
        },
        "irpf_regimen": {
          "type": "string",
          "description": "Régimen de IRPF aplicable."
        },
        "retencion_irpf_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Porcentaje de retención IRPF aplicable."
        },
        "modelo_036_casillas_relevantes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Casillas del Modelo 036 relevantes para esta actividad."
        }
      }
    },
    "obligaciones": {
      "type": "array",
      "description": "Obligaciones fiscales (modelos AEAT) aplicables.",
      "items": {
        "$ref": "#/$defs/Obligacion"
      }
    },
    "subvenciones": {
      "$ref": "#/$defs/ActivitySubvencionesBlock"
    },
    "registro": {
      "allOf": [
        {
          "$ref": "#/$defs/BormeRegistroBlock"
        }
      ],
      "description": "Presente SOLO cuando se envía `company_name` en la petición y hay coincidencia BORME. Se omite por completo (no aparece la clave) cuando no se envía `company_name` o no hay match — nunca se emite como `null`."
    },
    "vies": {
      "allOf": [
        {
          "$ref": "#/$defs/ViesResult"
        }
      ],
      "description": "Presente SOLO cuando se envía `nif` en la petición (con `code` o `activity_text`). Se omite por completo (no aparece la clave) cuando no se envía `nif` — nunca se emite como `null`. Un fallo de VIES nunca hace fallar el resto del dossier: el bloque se incluye igualmente con `consultado:false`."
    },
    "deudores_aeat": {
      "allOf": [
        {
          "$ref": "#/$defs/DeudoresResult"
        }
      ],
      "description": "Presente SOLO cuando se envía `nif` en la petición (con `code` o `activity_text`). Se omite por completo (no aparece la clave) cuando no se envía `nif` — nunca se emite como `null`. Un fallo de la consulta de deudores nunca hace fallar el resto del dossier: el bloque se incluye igualmente con `comprobado:false`. Señal dentro del expediente de diligencia debida, nunca un listado independiente."
    },
    "estado_registral": {
      "allOf": [
        {
          "$ref": "#/$defs/EstadoRegistral"
        }
      ],
      "description": "Presente SOLO cuando se envía `company_name` en la petición (con `code` o `activity_text`) y hay coincidencia en el histórico de actos BORME (normativa-api). Se omite por completo (no aparece la clave) cuando no se envía `company_name`, la consulta upstream falla, o el nombre es ambiguo sin `provincia` — nunca se emite como `null`."
    },
    "riesgo_resumen": {
      "allOf": [
        {
          "$ref": "#/$defs/RiesgoResumen"
        }
      ],
      "description": "Presente siempre que la petición envíe `company_name` o `nif` (junto a `code` o `activity_text`) — agrega estado_registral, vies, deudores_aeat y sector_riesgo. Se omite por completo cuando la petición no envía ninguna de esas dos señales (solo `code`/`activity_text`)."
    },
    "audit": {
      "type": "object",
      "description": "Metadatos de auditoría y trazabilidad de la respuesta.",
      "properties": {
        "source": {
          "type": "string",
          "description": "Identificador de la fuente de los datos."
        },
        "sources_oficiales": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Fuentes oficiales que respaldan la clasificación. Incluye 'BORME' cuando la respuesta trae un bloque 'registro' o un bloque 'estado_registral' (una sola vez aunque traiga ambos), 'VIES' cuando trae un bloque 'vies' con consultado:true, y 'AEAT (art. 95 bis)' cuando trae un bloque 'deudores_aeat' con comprobado:true."
        },
        "data_version": {
          "type": [
            "string",
            "null"
          ],
          "description": "Versión del catálogo usado (ISO timestamp)."
        },
        "generated_at": {
          "type": "string",
          "format": "date-time"
        },
        "data_residency": {
          "type": "string",
          "description": "Región de residencia de los datos (RGPD)."
        }
      }
    },
    "_meta": {
      "$ref": "#/$defs/Meta"
    }
  },
  "$defs": {
    "ActivityClassification": {
      "type": "object",
      "description": "Clasificación IAE y CNAE 2025 del match.",
      "properties": {
        "iae": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "Código con puntos."
            },
            "codeNormalized": {
              "type": "string",
              "description": "Código sin puntos (normalizado)."
            },
            "titulo": {
              "type": "string"
            }
          }
        },
        "cnae2025": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "Código con puntos."
            },
            "codeNormalized": {
              "type": "string",
              "description": "Código sin puntos (normalizado)."
            },
            "titulo": {
              "type": "string"
            }
          }
        }
      }
    },
    "ActivityMatch": {
      "type": "object",
      "description": "Resultado de la resolución del código o actividad.",
      "properties": {
        "confidence": {
          "type": [
            "number",
            "null"
          ],
          "description": "Confianza del match (0.0–1.0). null para lexical/no-match."
        },
        "method": {
          "type": "string",
          "enum": [
            "exact_code",
            "semantic",
            "lexical"
          ],
          "description": "Método de resolución: `exact_code` (código exacto), `semantic` (búsqueda semántica) o `lexical` (búsqueda léxica sin embedding)."
        },
        "alternatives": {
          "type": "array",
          "description": "Alternativas de menor confianza cuando el match semántico es ambiguo.",
          "items": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "titulo": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "iae",
                  "cnae"
                ]
              },
              "score": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        }
      }
    },
    "ActivitySubvencionesBlock": {
      "type": [
        "object",
        "null"
      ],
      "description": "Subvenciones BDNS/SNPSAP abiertas para la sección CNAE de la actividad resuelta. `null` cuando la actividad no tiene correspondencia CNAE 2025 (no se pudo derivar sección) o si el dato no está disponible. NUNCA incluye `fecha_cierre` — el dato de BDNS es poco fiable como plazo y no debe usarse para tomar decisiones de fecha límite.",
      "properties": {
        "seccion": {
          "type": [
            "string",
            "null"
          ],
          "description": "Sección CNAE (A–U) derivada del código CNAE 2025 resuelto."
        },
        "abiertas_count": {
          "type": "integer",
          "description": "Convocatorias abiertas en esta sección CNAE."
        },
        "para_actividad_economica_count": {
          "type": "integer",
          "description": "Subconjunto de abiertas_count dirigido a autónomos/pyme/empresa (tipos_beneficiarios)."
        },
        "destacadas": {
          "type": "array",
          "maxItems": 3,
          "description": "Hasta 3 convocatorias abiertas más relevantes para la actividad.",
          "items": {
            "type": "object",
            "properties": {
              "codigo_bdns": {
                "type": "string"
              },
              "titulo": {
                "type": "string"
              },
              "organo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "importe": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Dotación de la convocatoria (no por beneficiario)."
              },
              "url_oficial": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri"
              }
            }
          }
        },
        "fuente": {
          "type": "string"
        }
      }
    },
    "BormeRegistroBlock": {
      "type": "object",
      "description": "Datos de constitución de empresa (BORME) fusionados en el dossier cuando se envía `company_name` y hay coincidencia. Cobertura: constituciones desde 2026-01 (no es el Registro Mercantil completo).",
      "properties": {
        "denominacion": {
          "type": "string",
          "description": "Denominación social tal como consta en BORME."
        },
        "provincia": {
          "type": [
            "string",
            "null"
          ]
        },
        "capital_eur": {
          "type": [
            "number",
            "null"
          ]
        },
        "objeto_social": {
          "type": [
            "string",
            "null"
          ]
        },
        "cnae_registral": {
          "type": [
            "string",
            "null"
          ],
          "description": "CNAE declarado en la constitución (puede diferir del CNAE clasificado por actividad)."
        },
        "cnae_confidence": {
          "type": [
            "number",
            "null"
          ]
        },
        "fecha_constitucion": {
          "type": [
            "string",
            "null"
          ],
          "description": "Fecha de publicación en BORME del acto de constitución (proxy — BORME no expone una fecha de constitución independiente)."
        },
        "match_quality": {
          "type": "string",
          "enum": [
            "exact",
            "multiple",
            "fuzzy"
          ],
          "description": "`exact`: única coincidencia tras normalizar la denominación. `multiple`: varias empresas homónimas — se devuelve la constitución más reciente. `fuzzy`: coincidencia aproximada (reservado, no emitido actualmente)."
        },
        "fuente": {
          "type": "string",
          "enum": [
            "BORME"
          ]
        },
        "cobertura": {
          "type": "string",
          "enum": [
            "constituciones desde 2026-01"
          ]
        }
      }
    },
    "DeudoresResult": {
      "type": "object",
      "description": "Contraste del NIF/CIF enviado en `nif` con la publicación oficial de deudores a la Hacienda Pública (art. 95 bis LGT), como señal dentro del expediente de diligencia debida — nunca un listado independiente. Art. 95 bis.4 LGT: la publicación oficial no debe indexarse ni republicarse tal cual.",
      "properties": {
        "comprobado": {
          "type": "boolean",
          "description": "false cuando la consulta a AEAT no respondió (timeout, error de red o payload inesperado) — el resto del dossier se devuelve igualmente."
        },
        "aparece": {
          "type": "boolean",
          "description": "Presente solo cuando comprobado=true. Indica si el NIF/CIF figura en la publicación vigente de deudores."
        },
        "importe_eur": {
          "type": "number",
          "description": "Presente solo cuando comprobado=true y aparece=true. Importe publicado en la lista oficial de deudores (art. 95 bis LGT)."
        },
        "edicion": {
          "type": "string",
          "description": "Presente solo cuando comprobado=true. Edición de la publicación consultada."
        },
        "fuente": {
          "type": "string",
          "enum": [
            "AEAT art. 95 bis LGT"
          ],
          "description": "Presente solo cuando comprobado=true."
        }
      }
    },
    "EstadoRegistral": {
      "type": "object",
      "description": "Ciclo de vida de la empresa en el Registro Mercantil (BORME) y señales de drift, fusionado en el dossier cuando se envía `company_name` y hay coincidencia en el histórico de actos BORME (vía normativa-api, distinto de `registro`, que lee la constitución local). Cobertura: actos BORME desde 2026-01 (cobertura parcial del historial registral, no el Registro Mercantil completo).",
      "properties": {
        "estado": {
          "type": "string",
          "enum": [
            "activa",
            "extinguida",
            "disuelta",
            "en_concurso"
          ],
          "description": "Precedencia: concurso > extincion > disolucion > activa (por defecto cuando ninguno de los anteriores aplica)."
        },
        "ultimo_acto": {
          "type": "string",
          "description": "Tipo del acto BORME más reciente por fecha."
        },
        "fecha_ultimo_acto": {
          "type": "string",
          "description": "Fecha del acto más reciente."
        },
        "senales_drift": {
          "type": "array",
          "description": "Actos que suponen una divergencia entre la actividad/datos declarados y los registrados — señal de re-verificación (art. 10.2 RD 304/2014).",
          "items": {
            "type": "object",
            "properties": {
              "tipo": {
                "type": "string",
                "enum": [
                  "cambio_objeto_social",
                  "cambio_denominacion",
                  "cambio_domicilio"
                ]
              },
              "fecha": {
                "type": "string"
              }
            }
          }
        },
        "hoja": {
          "type": "string",
          "description": "Hoja registral BORME de la empresa emparejada."
        },
        "match_quality": {
          "type": "string",
          "enum": [
            "exact",
            "multiple"
          ],
          "description": "`exact`: única coincidencia tras normalizar la denominación (con desambiguación por provincia si hacía falta). `multiple`: varias empresas homónimas sin provincia que las distinga — se devuelve el acto más reciente."
        },
        "fuente": {
          "type": "string",
          "enum": [
            "BORME (Registro Mercantil)"
          ]
        },
        "cobertura": {
          "type": "string"
        }
      }
    },
    "Meta": {
      "type": "object",
      "description": "Metadatos del envelope para endpoints con clave: plan actual, cuota restante y días restantes de la prueba (solo plan trial) y nudge de upgrade a Empresa (solo plan Profesional al ≥80% de cuota).",
      "required": [
        "plan",
        "remaining"
      ],
      "properties": {
        "plan": {
          "type": "string",
          "description": "Plan de la clave (free, trial, profesional, empresa, enterprise). `trial` = prueba Profesional de 14 días sin tarjeta; al terminar, la clave pasa a free."
        },
        "remaining": {
          "type": "integer",
          "description": "Peticiones restantes de la cuota diaria."
        },
        "trial_ends_in_days": {
          "type": "integer",
          "minimum": 0,
          "description": "Días completos que quedan de la prueba Profesional (redondeo hacia arriba). Presente solo con plan `trial`."
        },
        "upgrade_hint": {
          "type": "string",
          "description": "Mensaje legible de upgrade a Empresa. Presente solo en plan Profesional al consumir ≥80% de la cuota. Las claves Free ya no reciben este nudge: ven el campo bloqueado (`locked: true`) en `associated_cnae` / `associated_iae`."
        },
        "upgrade": {
          "$ref": "#/$defs/UpgradeMeta"
        }
      }
    },
    "Obligacion": {
      "type": "object",
      "description": "Una obligación fiscal (modelo AEAT) aplicable al código.",
      "properties": {
        "modelo_id": {
          "type": "string"
        },
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "periodicidad": {
          "type": [
            "string",
            "null"
          ]
        },
        "confidence": {
          "type": [
            "number",
            "null"
          ]
        },
        "reason": {
          "type": [
            "string",
            "null"
          ]
        },
        "fecha_proximo_plazo": {
          "type": [
            "string",
            "null"
          ],
          "description": "Fecha nominal del calendario AEAT (sin prórroga de días inhábiles aplicada)."
        }
      }
    },
    "RiesgoResumen": {
      "type": "object",
      "description": "Semáforo de riesgo que agrega estado_registral, vies, deudores_aeat y el sector de riesgo fiscal. Se incluye siempre que la petición envíe `company_name` o `nif` (aunque los bloques subyacentes no encuentren coincidencia) — un resultado limpio se expresa como `nivel:\"verde\"` explícito, nunca omitido.",
      "properties": {
        "nivel": {
          "type": "string",
          "enum": [
            "verde",
            "ambar",
            "rojo"
          ],
          "description": "rojo: estado extinguida/en_concurso, deudores_aeat.aparece, o vies.valido=false. ambar: estado disuelta, cualquier señal de drift, o sector_riesgo=\"alto\". verde: ninguno de los anteriores."
        },
        "motivos": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Explicación en español de cada señal que activó el nivel — vacío cuando nivel=\"verde\"."
        },
        "senales_evaluadas": {
          "type": "integer",
          "description": "Cuántos de los 4 bloques de entrada (estado_registral, vies, deudores_aeat, sector_riesgo) estaban presentes en la petición — no cuántos dispararon una alerta."
        }
      }
    },
    "UpgradeMeta": {
      "type": "object",
      "description": "Forma estructurada del nudge de upgrade para renderizar UI nativa. Presente solo en plan Profesional al ≥80% de cuota (nudge a Empresa).",
      "properties": {
        "hint": {
          "type": "string"
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "current_plan": {
          "type": "string"
        },
        "recommended_plan": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "label": {
              "type": "string"
            },
            "daily_limit": {
              "type": "integer"
            },
            "monthly_price_eur": {
              "type": "integer"
            }
          }
        },
        "daily_limit_after": {
          "type": "integer"
        },
        "price_eur_monthly": {
          "type": "integer"
        }
      }
    },
    "ViesResult": {
      "type": "object",
      "description": "Resultado de la validación VIES (Comisión Europea) del NIF/CIF enviado en `nif`. Dato meramente informativo, no constituye asesoramiento fiscal.",
      "properties": {
        "consultado": {
          "type": "boolean",
          "description": "false cuando VIES no respondió (timeout, error de red o payload inesperado) — el resto del dossier se devuelve igualmente."
        },
        "valido": {
          "type": "boolean",
          "description": "Presente solo cuando consultado=true. Indica si el NIF/CIF está registrado como operador intracomunitario válido en VIES."
        },
        "fecha_consulta": {
          "type": "string",
          "description": "Presente solo cuando consultado=true. Fecha/hora de la consulta a VIES (ISO 8601)."
        },
        "nota": {
          "type": "string",
          "description": "Presente solo cuando consultado=true."
        },
        "error": {
          "type": "string",
          "enum": [
            "no disponible"
          ],
          "description": "Presente solo cuando consultado=false."
        }
      }
    }
  }
}