{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/boletinclaro-es/json-schema/boletinclaro-es-respuesta-entradas-schema.json",
  "title": "RespuestaEntradas",
  "description": "Envoltorio común de las respuestas de lista. No hay paginación: una búsqueda semántica ordena por parecido, y la fila 400 de un ranking así no significa nada.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/boletinclaro-es-openapi.json#/components/schemas/RespuestaEntradas",
  "properties": {
    "busqueda": {
      "$ref": "#/$defs/SearchMetadata"
    },
    "consulta": {
      "description": "La consulta tal y como se aplicó, ya recortada si venía por encima del máximo.",
      "type": "string"
    },
    "resultados": {
      "description": "Entradas encontradas, ordenadas por relevancia.",
      "items": {
        "$ref": "#/$defs/Entrada"
      },
      "type": "array"
    },
    "total": {
      "description": "Cuántas filas trae ESTA respuesta. No es cuántas hay en total.",
      "type": "integer"
    }
  },
  "required": [
    "total",
    "resultados"
  ],
  "type": "object",
  "$defs": {
    "Entrada": {
      "description": "Una publicación: una convocatoria de subvención, una licitación o una entrada de boletín. Un solo tipo para las tres porque eso es lo que son los datos — el mismo documento desde todas las fuentes.\n\n**La clave es la tripleta `fuente` + `fecha_publicacion` + `identificador`.** El identificador es la referencia de la fuente oficial, pero en algunas gacetas (BOPV, BOB, BORM) es una secuencia que se reinicia cada año: quien use solo `fuente` + `identificador` acabará fusionando dos entradas distintas de años distintos.",
      "properties": {
        "ambito": {
          "description": "`nacional` cuando aplica a todo el país; `local` cuando va atada a lugares concretos.",
          "enum": [
            "nacional",
            "local"
          ],
          "type": "string"
        },
        "anuncio_previo": {
          "description": "Solo en licitaciones de PLACSP: `true` cuando es un anuncio previo, una licitación anunciada a la que aún no se puede presentar oferta. Su `fecha_fin`, si viene, es la orientativa del anuncio y no el cierre: la licitación, cuando se publica, suele traer otra. Si no aparece, no es un anuncio previo.",
          "type": "boolean"
        },
        "codigos_ubicacion": {
          "description": "Jerarquía del INE de lo más concreto a lo más general (municipio, provincia, comunidad), para cruzarla con tus datos. Vacía en las entradas de ámbito nacional.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "enlace": {
          "description": "URL oficial de la fuente.",
          "format": "uri",
          "type": "string"
        },
        "fecha_fin": {
          "description": "Cierre del plazo. Es lo que usamos para decidir si algo sigue abierto. Solo una parte de las convocatorias lo publica. Si `anuncio_previo` es `true`, no es un plazo: es la fecha prevista que estima el anuncio.",
          "format": "date",
          "type": "string"
        },
        "fecha_inicio": {
          "description": "Apertura del plazo, cuando la fuente la publica.",
          "format": "date",
          "type": "string"
        },
        "fecha_publicacion": {
          "description": "Cuándo salió en el boletín. AAAA-MM-DD.",
          "format": "date",
          "type": "string"
        },
        "ficha": {
          "description": "Nuestra página del mismo elemento. **No guardes el identificador que aparece dentro de esta URL**: es la clave de nuestra página, no de la entrada.",
          "format": "uri",
          "type": "string"
        },
        "fuente": {
          "description": "Código corto de la fuente: BDNS, PLACSP, TED, EUFUNDING, BOE, BOJA, DOG…",
          "type": "string"
        },
        "identificador": {
          "description": "Referencia propia de la fuente oficial. Estable en el único sitio que no controlamos nosotros.",
          "type": "string"
        },
        "importe": {
          "description": "Importe en la moneda de `moneda`. Cuando la fuente no publica importe el campo **no aparece**, en vez de venir a cero: así una suma tuya no se queda corta en silencio. Un cero que sí viene es un cero de verdad.",
          "format": "double",
          "type": "number"
        },
        "moneda": {
          "description": "Código ISO 4217.",
          "type": "string"
        },
        "seccion": {
          "description": "Sección del boletín, cuando la fuente la marca.",
          "type": "string"
        },
        "tipo": {
          "description": "Qué es la entrada. Se deriva de la fuente, así que no puede contradecir al filtro que la trajo.",
          "enum": [
            "subvencion",
            "licitacion",
            "boletin"
          ],
          "type": "string"
        },
        "titulo": {
          "description": "Título tal y como lo publica la fuente.",
          "type": "string"
        },
        "ubicacion": {
          "description": "Nombres completos de los lugares, para leerlos. Una entrada por lugar real, no una por nivel de la jerarquía. Se omiten si la geografía no está disponible; los códigos viajan igual.",
          "items": {
            "type": "string"
          },
          "type": "array"
        }
      },
      "required": [
        "titulo",
        "fuente",
        "tipo"
      ],
      "type": "object"
    },
    "SearchMetadata": {
      "properties": {
        "candidatos_leidos": {
          "type": "integer"
        },
        "grupos_consulta": {
          "type": "integer"
        },
        "limite_candidatos": {
          "type": "integer"
        },
        "truncada": {
          "description": "La selección de candidatos o el resultado se recortó; no es una exportación exhaustiva.",
          "type": "boolean"
        }
      },
      "required": [
        "limite_candidatos",
        "candidatos_leidos",
        "grupos_consulta",
        "truncada"
      ],
      "type": "object"
    }
  }
}