{"openapi":"3.1.0","info":{"title":"EnergiAlert — API pública","version":"0.1.9","summary":"Precio de la luz en España (PVPC y mercado mayorista) y cuándo conviene consumir.","description":"Datos oficiales de Red Eléctrica de España (ESIOS) para la tarifa 2.0TD de la Península.\n\nSin registro, sin clave y sin coste. **Límite: 120 peticiones por minuto y IP.**\n\nToda respuesta correcta llega envuelta en `{ \"success\": true, \"data\": … }`. Los errores llevan `code`, y el cliente decide por `code`, nunca por el texto.\n\n**Unidades.** `eurKwh` va en €/kWh en los dos mercados, también en el mayorista (para citarlo en su unidad, €/MWh, ×1000), y **sin** impuestos; `eurKwhWithTaxes` **con** impuesto eléctrico e IVA, y solo existe en PVPC (`null` en el mayorista). Los precios pueden ser negativos: es un valor real, no un error, y no significa que la luz sea gratis (queda el término de potencia).\n\n**Fechas.** Fechas `YYYY-MM-DD` en hora de Madrid; por defecto, hoy. El día del cambio de hora tiene 23 o 25 horas: hay que recorrer los tramos que llegan, nunca asumir 24.\n\n**Atribución.** Los datos son de e·sios (Red Eléctrica de España). Al reutilizarlos hay que citar la fuente y la fecha de actualización, que viaja en `updatedAt`.","license":{"name":"Datos de ESIOS (REE) — ver condiciones de reutilización","url":"https://www.esios.ree.es/es/pagina/aviso-legal"}},"servers":[{"url":"https://energialert.com/v1","description":"Producción"}],"paths":{"/prices":{"get":{"summary":"Precios de un día","description":"Tramos del día con `published`, `stepMinutes` (60 en PVPC, 15 en mayorista), mínimo, máximo y media, y `updatedAt` con la última lectura de ESIOS.\n\nFechas `YYYY-MM-DD` en hora de Madrid; por defecto, hoy. El día del cambio de hora tiene 23 o 25 horas: hay que recorrer los tramos que llegan, nunca asumir 24.","parameters":[{"name":"date","in":"query","required":false,"description":"Día en hora de Madrid, `YYYY-MM-DD`. Por defecto, hoy.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"market","in":"query","required":false,"description":"`pvpc` (tarifa regulada, horaria) o `spot` (mercado mayorista, cuartohorario desde el 1/10/2025).","schema":{"type":"string","enum":["pvpc","spot"],"default":"pvpc"}}],"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/prices/now":{"get":{"summary":"Precio de este momento","description":"Tramo en curso de PVPC y del mayorista, con `nextChangeAt`, `dayPercentile` y `level` (`cheap`/`normal`/`expensive`) **relativo a ese mismo día**, no a un umbral fijo.","responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/periods":{"get":{"summary":"Tramos P1/P2/P3 de un día","description":"Periodos regulados 2.0TD de la Península. Son tramos de peaje, no el semáforo de precio.","parameters":[{"name":"date","in":"query","required":false,"description":"Día en hora de Madrid, `YYYY-MM-DD`. Por defecto, hoy.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/summary":{"get":{"summary":"Resumen del día","description":"Mejores franjas de 2 y 3 h, franja cara, comparaciones y `breaksPattern`: si la franja barata cae fuera de los dos valles habituales.","parameters":[{"name":"date","in":"query","required":false,"description":"Día en hora de Madrid, `YYYY-MM-DD`. Por defecto, hoy.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"market","in":"query","required":false,"description":"`pvpc` (tarifa regulada, horaria) o `spot` (mercado mayorista, cuartohorario desde el 1/10/2025).","schema":{"type":"string","enum":["pvpc","spot"],"default":"pvpc"}}],"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/records":{"get":{"summary":"Mínimos","description":"Mínimos de hoy, del mes y del año.","responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/grid/now":{"get":{"summary":"Estado de la red ahora","description":"Renovable, CO₂, demanda y mix. `null` si no hay lecturas de menos de 30 minutos.","responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/grid":{"get":{"summary":"Estado de la red de un día","description":"Serie del día.","parameters":[{"name":"date","in":"query","required":false,"description":"Día en hora de Madrid, `YYYY-MM-DD`. Por defecto, hoy.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/power-charges":{"get":{"summary":"Término de potencia 2.0TD","description":"Peajes y cargos regulados en €/kW y año, sin y con impuestos, con su fuente del BOE. 503 si el año no está sembrado.","parameters":[{"name":"date","in":"query","required":false,"description":"Día en hora de Madrid, `YYYY-MM-DD`. Por defecto, hoy.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/insights/hourly-pattern":{"get":{"summary":"¿Es más barata la luz de noche?","description":"PVPC por hora de reloj en los últimos 365 días: noche (0-8 h) frente a mediodía (12-16 h) y mes a mes. 503 con menos de 60 días de histórico.","responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/tariff-check/reference":{"get":{"summary":"Precio fijo que empata con el PVPC","description":"Media del PVPC del último año ponderada con el perfil de consumo oficial de REE, sin y con impuestos.","responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Parámetros inválidos (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"},"503":{"description":"Sin datos suficientes todavía (`code: SERVICE_UNAVAILABLE`)"}}}},"/recommendations":{"post":{"summary":"Mejor franja por aparato","description":"Mejor, habitual y peor franja para cada aparato, con el coste en euros. El perfil de tarifa viaja en el cuerpo: no hay estado ni cuenta.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"profile":{"type":"pvpc"},"appliances":[{"kind":"washer"}]}}}},"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Cuerpo inválido (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"}}}},"/widget":{"post":{"summary":"Todo lo que necesita un widget","description":"Precio actual, próxima franja barata, 36 horas y `refreshAfter` (cuándo volver a preguntar).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"profile":{"type":"pvpc"},"appliances":[]}}}},"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Cuerpo inválido (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"}}}},"/tariff-check":{"post":{"summary":"¿Me conviene el precio fijo?","description":"Compara un precio fijo con el PVPC del último año ponderado con el perfil de REE. `note` se muestra siempre.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":{"fixedPriceEurKwh":0.14,"annualKwh":3000}}}},"responses":{"200":{"description":"Correcto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"Cuerpo inválido (`code: VALIDATION_ERROR`)"},"429":{"description":"Límite de peticiones (`code: RATE_LIMITED`)"}}}}},"components":{"schemas":{"Envelope":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"description":"El contenido del endpoint."}}}}}}