{"openapi":"3.1.0","info":{"title":"Quedaplaza API","version":"0.1.0","summary":"Disponibilidad verificable de plazas de cuidados en España","description":"API de disponibilidad de servicios de cuidados. La V0 cubre residencias de mayores de la Comunidad de Madrid.\n\nCada respuesta de disponibilidad es una **observación fechada** con método de verificación y nivel de confianza. Cuando el dato supera su TTL, el estado efectivo pasa a `UNKNOWN`: la API prefiere decir *no lo sé* antes que afirmar una plaza que quizá ya no exista.\n\nNo se almacenan ni se aceptan datos personales ni de salud.","contact":{"name":"Quedaplaza"}},"servers":[{"url":"https://quedaplaza.es"}],"tags":[{"name":"search","description":"Búsqueda de disponibilidad"},{"name":"facilities","description":"Catálogo de proveedores de cuidados"},{"name":"availability","description":"Ingesta y reconfirmación de disponibilidad"},{"name":"ops","description":"Salud y métricas de frescura"}],"paths":{"/health":{"get":{"tags":["ops"],"operationId":"health","summary":"Estado del servicio","responses":{"200":{"description":"OK"}}}},"/v1/search":{"get":{"tags":["search"],"operationId":"searchAvailabilityGet","summary":"Buscar disponibilidad (parámetros en query)","parameters":[{"name":"near","in":"query","required":false,"description":"Municipio de referencia, p. ej. `Getafe`","schema":{"type":"string"}},{"name":"lat","in":"query","required":false,"description":"Latitud del punto de búsqueda","schema":{"type":"number"}},{"name":"lon","in":"query","required":false,"description":"Longitud del punto de búsqueda","schema":{"type":"number"}},{"name":"radius_km","in":"query","required":false,"description":"Radio de búsqueda en km (por defecto 25)","schema":{"type":"number"}},{"name":"stay_type","in":"query","required":false,"description":"PERMANENT | TEMPORARY | RESPITE | DAY","schema":{"type":"string"}},{"name":"room_type","in":"query","required":false,"description":"PRIVATE | SHARED | ANY","schema":{"type":"string"}},{"name":"max_monthly_price_eur","in":"query","required":false,"description":"Precio mensual máximo","schema":{"type":"number"}},{"name":"max_data_age_hours","in":"query","required":false,"description":"Antigüedad máxima aceptable del dato (por defecto 72)","schema":{"type":"number"}},{"name":"include_unknown","in":"query","required":false,"description":"Incluir centros sin dato fresco","schema":{"type":"boolean"}},{"name":"limit","in":"query","required":false,"description":"Número máximo de resultados (máx. 50)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Resultados de disponibilidad","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Consulta inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["search"],"operationId":"searchAvailability","summary":"Buscar disponibilidad","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchQuery"}}}},"responses":{"200":{"description":"Resultados de disponibilidad","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Consulta inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/facilities":{"get":{"tags":["facilities"],"operationId":"listFacilities","summary":"Listar centros del catálogo","parameters":[{"name":"municipality","in":"query","required":false,"description":"Filtrar por municipio","schema":{"type":"string"}},{"name":"query","in":"query","required":false,"description":"Búsqueda por texto en nombre o municipio","schema":{"type":"string"}},{"name":"provider_type","in":"query","required":false,"description":"Tipo de proveedor","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Máximo de resultados (por defecto 50)","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"Desplazamiento para paginación","schema":{"type":"integer"}}],"responses":{"200":{"description":"Centros","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FacilityList"}}}}}}},"/v1/facilities/{id}":{"get":{"tags":["facilities"],"operationId":"getFacility","summary":"Ficha de un centro con su disponibilidad evaluada","parameters":[{"name":"id","in":"path","required":true,"description":"Identificador del centro, p. ej. `es-md-res-000218`","schema":{"type":"string"}}],"responses":{"200":{"description":"Ficha del centro","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FacilityDetail"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/facilities/{id}/availability":{"get":{"tags":["availability"],"operationId":"getFacilityAvailability","summary":"Disponibilidad actual e histórico de observaciones","parameters":[{"name":"id","in":"path","required":true,"description":"Identificador del centro","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Número de observaciones históricas (por defecto 50)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Disponibilidad","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["availability"],"operationId":"reportAvailability","summary":"Registrar una nueva observación de disponibilidad","description":"Append-only: cada llamada crea una observación nueva, nunca modifica la anterior.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Identificador del centro","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAvailability"}}}},"responses":{"201":{"description":"Observación registrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Observation"}}}},"401":{"description":"No autorizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/availability/refresh-requests":{"post":{"tags":["availability"],"operationId":"requestAvailabilityRefresh","summary":"Solicitar la reconfirmación de la disponibilidad de un centro","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequestInput"}}}},"responses":{"202":{"description":"Petición aceptada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["availability"],"operationId":"listRefreshRequests","summary":"Listar peticiones de reconfirmación","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"PENDING | SENT | ANSWERED | EXPIRED | FAILED","schema":{"type":"string"}},{"name":"provider_id","in":"query","required":false,"description":"Filtrar por centro","schema":{"type":"string"}}],"responses":{"200":{"description":"Peticiones","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequestList"}}}}}}},"/v1/stats/freshness":{"get":{"tags":["ops"],"operationId":"freshnessStats","summary":"KPIs de frescura del inventario (North Star V0)","responses":{"200":{"description":"KPIs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreshnessStats"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"AvailabilityStatus":{"type":"string","enum":["AVAILABLE","FULL","WAITLIST","UNKNOWN"],"description":"`UNKNOWN` significa que el dato ha caducado, no que el centro esté completo."},"VerificationMethod":{"type":"string","enum":["ERP_API","PROVIDER_PORTAL","PHONE_AGENT","WHATSAPP","EMAIL","MANUAL_INTERNAL","PUBLIC_WEB","SYNTHETIC"]},"SearchQuery":{"type":"object","properties":{"near":{"type":"string","examples":["Getafe"]},"lat":{"type":"number"},"lon":{"type":"number"},"radius_km":{"type":"number","default":25,"maximum":200},"provider_type":{"type":"string","default":"NURSING_HOME"},"stay_type":{"type":"string","default":"PERMANENT"},"room_type":{"type":"string","enum":["PRIVATE","SHARED","ANY"]},"max_monthly_price_eur":{"type":"number"},"min_available_units":{"type":"integer","minimum":1},"features":{"type":"array","items":{"type":"string"}},"max_data_age_hours":{"type":"number","default":72},"min_confidence":{"type":"number","default":0.35},"include_unknown":{"type":"boolean","default":false},"sort":{"type":"string","enum":["relevance","distance","confidence","price"]},"limit":{"type":"integer","default":10,"maximum":50}}},"EvaluatedAvailability":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AvailabilityStatus"},"reported_status":{"$ref":"#/components/schemas/AvailabilityStatus"},"available_units":{"type":["integer","null"]},"monthly_price_eur":{"type":["number","null"]},"verification_method":{"$ref":"#/components/schemas/VerificationMethod"},"observed_at":{"type":"string","format":"date-time"},"age_hours":{"type":"number"},"confidence":{"type":"number","minimum":0,"maximum":1},"expires_at":{"type":"string","format":"date-time"},"is_stale":{"type":"boolean"},"stay_type":{"type":"string"},"room_type":{"type":"string"}}},"SearchResponse":{"type":"object","properties":{"generated_at":{"type":"string","format":"date-time"},"center":{"type":"object","additionalProperties":true},"coverage":{"type":"object","description":"Qué parte del entorno conocemos realmente.","properties":{"candidates_in_radius":{"type":"integer"},"with_known_availability":{"type":"integer"},"with_available_places":{"type":"integer"},"stale_or_unknown":{"type":"integer"},"median_data_age_hours":{"type":["number","null"]}}},"results":{"type":"array","items":{"type":"object","additionalProperties":true}},"notice":{"type":"string"}}},"Facility":{"type":"object","additionalProperties":true},"FacilityList":{"type":"object","properties":{"total":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Facility"}}}},"FacilityDetail":{"type":"object","additionalProperties":true},"AvailabilityResponse":{"type":"object","additionalProperties":true},"Observation":{"type":"object","additionalProperties":true},"ReportAvailability":{"type":"object","required":["status","verification_method"],"properties":{"status":{"$ref":"#/components/schemas/AvailabilityStatus"},"stay_type":{"type":"string","default":"PERMANENT"},"room_type":{"type":"string","default":"ANY"},"available_units":{"type":["integer","null"]},"monthly_price_eur":{"type":["number","null"]},"verification_method":{"$ref":"#/components/schemas/VerificationMethod"},"reported_by":{"type":["string","null"]},"note":{"type":["string","null"]},"observed_at":{"type":"string","format":"date-time"}}},"RefreshRequestInput":{"type":"object","required":["provider_id"],"properties":{"provider_id":{"type":"string"},"stay_type":{"type":["string","null"]},"room_type":{"type":["string","null"]},"requested_by":{"type":["string","null"]},"reason":{"type":["string","null"]}}},"RefreshRequest":{"type":"object","additionalProperties":true},"RefreshRequestList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RefreshRequest"}}}},"FreshnessStats":{"type":"object","additionalProperties":true}}}}