{
  "openapi": "3.1.0",
  "info": {
    "title": "Lumi — API pública de solo lectura",
    "version": "2026-11-06",
    "description": "Datos oficiales de Lumi (café de especialidad en el Centro de Tijuana) en JSON: negocio, horario, carta con precios, espacios y preguntas frecuentes. Archivos estáticos regenerados con cada publicación; sin autenticación, solo GET. No hay pedidos, pagos ni reservaciones por API: las reservaciones se hacen por WhatsApp 664 980 4080.",
    "contact": {
      "name": "Lumi (reservaciones y dudas por WhatsApp)",
      "url": "https://wa.me/526649804080"
    },
    "x-llms-txt": "https://lumi-nuevo.badabunvps.cloud/llms.txt"
  },
  "servers": [
    {
      "url": "https://lumi-nuevo.badabunvps.cloud",
      "description": "Producción (archivos estáticos tras Cloudflare)"
    }
  ],
  "x-versioning": "Por ruta: /api/v1/ es la versión estable; /api/ (sin versión) sirve lo mismo. Política: v1 no se retira mientras exista el sitio; un cambio incompatible de forma sale como /api/v2/ y se anuncia en /docs/ con al menos 90 días de aviso antes de tocar v1. Añadir campos nuevos no cambia la versión.",
  "x-deprecation-policy": "Versioning policy: URL path versions (/api/v1/). v1 is kept while the site exists; breaking changes ship as /api/v2/ and are announced at /docs/ at least 90 days before v1 changes. Additive fields do not bump the version.",
  "x-rate-limit": "30 peticiones por segundo por IP (nginx); cabeceras RateLimit-Policy y RateLimit-Limit en cada respuesta; 429 con cuerpo JSON al pasarse.",
  "externalDocs": {
    "description": "Guía para desarrolladores y agentes",
    "url": "https://lumi-nuevo.badabunvps.cloud/docs/"
  },
  "tags": [
    {
      "name": "lumi",
      "description": "Datos del café"
    }
  ],
  "paths": {
    "/api/v1/negocio.json": {
      "get": {
        "operationId": "get_negocio",
        "summary": "Datos del negocio: nombre, dirección, coordenadas, horario, amenidades, redes y contacto.",
        "description": "Datos del negocio: nombre, dirección, coordenadas, horario, amenidades, redes y contacto. Archivo estático; también disponible sin versión en /api/negocio.json.",
        "tags": [
          "lumi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "schema": {
                  "type": "string"
                },
                "description": "30 peticiones por segundo por IP (IETF RateLimit headers)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "nombre",
                    "direccion",
                    "geo",
                    "horario",
                    "contacto"
                  ],
                  "properties": {
                    "nombre": {
                      "type": "string"
                    },
                    "nombreAlterno": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descripcion": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "direccion": {
                      "type": "object",
                      "required": [
                        "calle",
                        "ciudad",
                        "texto"
                      ],
                      "properties": {
                        "calle": {
                          "type": "string"
                        },
                        "colonia": {
                          "type": "string"
                        },
                        "cp": {
                          "type": "string"
                        },
                        "ciudad": {
                          "type": "string"
                        },
                        "estado": {
                          "type": "string"
                        },
                        "pais": {
                          "type": "string"
                        },
                        "texto": {
                          "type": "string"
                        }
                      }
                    },
                    "geo": {
                      "type": "object",
                      "required": [
                        "lat",
                        "lng"
                      ],
                      "properties": {
                        "lat": {
                          "type": "number"
                        },
                        "lng": {
                          "type": "number"
                        }
                      }
                    },
                    "mapa": {
                      "type": "string",
                      "format": "uri"
                    },
                    "zonaHoraria": {
                      "type": "string"
                    },
                    "horario": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "dias",
                          "abre",
                          "cierra"
                        ],
                        "properties": {
                          "dias": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "abre": {
                            "type": "string",
                            "pattern": "^\\d{2}:\\d{2}$"
                          },
                          "cierra": {
                            "type": "string",
                            "pattern": "^\\d{2}:\\d{2}$"
                          }
                        }
                      }
                    },
                    "precios": {
                      "type": "object",
                      "properties": {
                        "moneda": {
                          "type": "string"
                        },
                        "minimo": {
                          "type": "number"
                        },
                        "maximo": {
                          "type": "number"
                        }
                      }
                    },
                    "amenidades": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "atributosGoogle": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "contacto": {
                      "type": "object",
                      "properties": {
                        "reservaciones": {
                          "type": "object",
                          "properties": {
                            "canal": {
                              "type": "string"
                            },
                            "numero": {
                              "type": "string"
                            },
                            "e164": {
                              "type": "string"
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "urlConMensaje": {
                              "type": "string",
                              "format": "uri"
                            },
                            "datosQuePide": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "otrasDudas": {
                          "type": "object",
                          "properties": {
                            "instagram": {
                              "type": "string",
                              "format": "uri"
                            },
                            "facebook": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      }
                    },
                    "redes": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string",
                        "format": "uri"
                      }
                    },
                    "actualizado": {
                      "type": "string",
                      "format": "date"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No existe ese recurso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones (30 por segundo por IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/horario.json": {
      "get": {
        "operationId": "get_horario",
        "summary": "Horario de apertura por día (formato 24 h, hora de Tijuana).",
        "description": "Horario de apertura por día (formato 24 h, hora de Tijuana). Archivo estático; también disponible sin versión en /api/horario.json.",
        "tags": [
          "lumi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "schema": {
                  "type": "string"
                },
                "description": "30 peticiones por segundo por IP (IETF RateLimit headers)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "zonaHoraria",
                    "horario"
                  ],
                  "properties": {
                    "zonaHoraria": {
                      "type": "string"
                    },
                    "actualizado": {
                      "type": "string",
                      "format": "date"
                    },
                    "horario": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "dias",
                          "abre",
                          "cierra"
                        ],
                        "properties": {
                          "dias": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "abre": {
                            "type": "string"
                          },
                          "cierra": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "texto": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "dias": {
                            "type": "string"
                          },
                          "abre": {
                            "type": "string"
                          },
                          "cierra": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No existe ese recurso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones (30 por segundo por IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/menu.json": {
      "get": {
        "operationId": "get_menu",
        "summary": "Carta completa: 8 categorías con productos, tamaños y precios en MXN.",
        "description": "Carta completa: 8 categorías con productos, tamaños y precios en MXN. Archivo estático; también disponible sin versión en /api/menu.json.",
        "tags": [
          "lumi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "schema": {
                  "type": "string"
                },
                "description": "30 peticiones por segundo por IP (IETF RateLimit headers)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "moneda",
                    "categorias"
                  ],
                  "properties": {
                    "moneda": {
                      "type": "string",
                      "enum": [
                        "MXN"
                      ]
                    },
                    "actualizado": {
                      "type": "string",
                      "format": "date"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "categorias": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "nombre",
                          "productos"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "nombre": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          },
                          "tamanos": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "productos": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "nombre",
                                "precios"
                              ],
                              "properties": {
                                "nombre": {
                                  "type": "string"
                                },
                                "detalle": {
                                  "type": "string"
                                },
                                "precioCaliente": {
                                  "type": "number"
                                },
                                "servicio": {
                                  "type": "string"
                                },
                                "precios": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "required": [
                                      "precio"
                                    ],
                                    "properties": {
                                      "tamano": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "precio": {
                                        "type": "number"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No existe ese recurso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones (30 por segundo por IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/espacios.json": {
      "get": {
        "operationId": "get_espacios",
        "summary": "Espacios que se pueden reservar y cómo reservarlos.",
        "description": "Espacios que se pueden reservar y cómo reservarlos. Archivo estático; también disponible sin versión en /api/espacios.json.",
        "tags": [
          "lumi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "schema": {
                  "type": "string"
                },
                "description": "30 peticiones por segundo por IP (IETF RateLimit headers)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "espacios",
                    "comoReservar"
                  ],
                  "properties": {
                    "resumen": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "actualizado": {
                      "type": "string",
                      "format": "date"
                    },
                    "comoReservar": {
                      "type": "object",
                      "required": [
                        "canal",
                        "numero",
                        "url"
                      ],
                      "properties": {
                        "canal": {
                          "type": "string"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "urlConMensaje": {
                          "type": "string",
                          "format": "uri"
                        },
                        "datosQuePide": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "nota": {
                          "type": "string"
                        }
                      }
                    },
                    "espacios": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "nombre",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "nombre": {
                            "type": "string"
                          },
                          "titulo": {
                            "type": "string"
                          },
                          "descripcion": {
                            "type": "string"
                          },
                          "destacados": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          },
                          "markdown": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    },
                    "fotos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "titulo": {
                            "type": "string"
                          },
                          "pagina": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No existe ese recurso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones (30 por segundo por IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/preguntas.json": {
      "get": {
        "operationId": "get_preguntas",
        "summary": "Preguntas frecuentes con sus respuestas en texto plano.",
        "description": "Preguntas frecuentes con sus respuestas en texto plano. Archivo estático; también disponible sin versión en /api/preguntas.json.",
        "tags": [
          "lumi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "schema": {
                  "type": "string"
                },
                "description": "30 peticiones por segundo por IP (IETF RateLimit headers)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "preguntas"
                  ],
                  "properties": {
                    "actualizado": {
                      "type": "string",
                      "format": "date"
                    },
                    "preguntas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "pregunta",
                          "respuesta"
                        ],
                        "properties": {
                          "pregunta": {
                            "type": "string"
                          },
                          "respuesta": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No existe ese recurso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones (30 por segundo por IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "negocio": {
        "type": "object",
        "required": [
          "nombre",
          "direccion",
          "geo",
          "horario",
          "contacto"
        ],
        "properties": {
          "nombre": {
            "type": "string"
          },
          "nombreAlterno": {
            "type": [
              "string",
              "null"
            ]
          },
          "descripcion": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "direccion": {
            "type": "object",
            "required": [
              "calle",
              "ciudad",
              "texto"
            ],
            "properties": {
              "calle": {
                "type": "string"
              },
              "colonia": {
                "type": "string"
              },
              "cp": {
                "type": "string"
              },
              "ciudad": {
                "type": "string"
              },
              "estado": {
                "type": "string"
              },
              "pais": {
                "type": "string"
              },
              "texto": {
                "type": "string"
              }
            }
          },
          "geo": {
            "type": "object",
            "required": [
              "lat",
              "lng"
            ],
            "properties": {
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              }
            }
          },
          "mapa": {
            "type": "string",
            "format": "uri"
          },
          "zonaHoraria": {
            "type": "string"
          },
          "horario": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dias",
                "abre",
                "cierra"
              ],
              "properties": {
                "dias": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "abre": {
                  "type": "string",
                  "pattern": "^\\d{2}:\\d{2}$"
                },
                "cierra": {
                  "type": "string",
                  "pattern": "^\\d{2}:\\d{2}$"
                }
              }
            }
          },
          "precios": {
            "type": "object",
            "properties": {
              "moneda": {
                "type": "string"
              },
              "minimo": {
                "type": "number"
              },
              "maximo": {
                "type": "number"
              }
            }
          },
          "amenidades": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "atributosGoogle": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contacto": {
            "type": "object",
            "properties": {
              "reservaciones": {
                "type": "object",
                "properties": {
                  "canal": {
                    "type": "string"
                  },
                  "numero": {
                    "type": "string"
                  },
                  "e164": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "urlConMensaje": {
                    "type": "string",
                    "format": "uri"
                  },
                  "datosQuePide": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "otrasDudas": {
                "type": "object",
                "properties": {
                  "instagram": {
                    "type": "string",
                    "format": "uri"
                  },
                  "facebook": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          },
          "redes": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "actualizado": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "horario": {
        "type": "object",
        "required": [
          "zonaHoraria",
          "horario"
        ],
        "properties": {
          "zonaHoraria": {
            "type": "string"
          },
          "actualizado": {
            "type": "string",
            "format": "date"
          },
          "horario": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dias",
                "abre",
                "cierra"
              ],
              "properties": {
                "dias": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "abre": {
                  "type": "string"
                },
                "cierra": {
                  "type": "string"
                }
              }
            }
          },
          "texto": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dias": {
                  "type": "string"
                },
                "abre": {
                  "type": "string"
                },
                "cierra": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "menu": {
        "type": "object",
        "required": [
          "moneda",
          "categorias"
        ],
        "properties": {
          "moneda": {
            "type": "string",
            "enum": [
              "MXN"
            ]
          },
          "actualizado": {
            "type": "string",
            "format": "date"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "categorias": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "slug",
                "nombre",
                "productos"
              ],
              "properties": {
                "slug": {
                  "type": "string"
                },
                "nombre": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "tamanos": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "productos": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "nombre",
                      "precios"
                    ],
                    "properties": {
                      "nombre": {
                        "type": "string"
                      },
                      "detalle": {
                        "type": "string"
                      },
                      "precioCaliente": {
                        "type": "number"
                      },
                      "servicio": {
                        "type": "string"
                      },
                      "precios": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "precio"
                          ],
                          "properties": {
                            "tamano": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "precio": {
                              "type": "number"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "espacios": {
        "type": "object",
        "required": [
          "espacios",
          "comoReservar"
        ],
        "properties": {
          "resumen": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "actualizado": {
            "type": "string",
            "format": "date"
          },
          "comoReservar": {
            "type": "object",
            "required": [
              "canal",
              "numero",
              "url"
            ],
            "properties": {
              "canal": {
                "type": "string"
              },
              "numero": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "urlConMensaje": {
                "type": "string",
                "format": "uri"
              },
              "datosQuePide": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "nota": {
                "type": "string"
              }
            }
          },
          "espacios": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "slug",
                "nombre",
                "url"
              ],
              "properties": {
                "slug": {
                  "type": "string"
                },
                "nombre": {
                  "type": "string"
                },
                "titulo": {
                  "type": "string"
                },
                "descripcion": {
                  "type": "string"
                },
                "destacados": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "markdown": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "fotos": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "titulo": {
                  "type": "string"
                },
                "pagina": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "preguntas": {
        "type": "object",
        "required": [
          "preguntas"
        ],
        "properties": {
          "actualizado": {
            "type": "string",
            "format": "date"
          },
          "preguntas": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "pregunta",
                "respuesta"
              ],
              "properties": {
                "pregunta": {
                  "type": "string"
                },
                "respuesta": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "not_found",
                  "rate_limited"
                ]
              },
              "message": {
                "type": "string"
              },
              "docs": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}
