{
  "openapi": "3.1.0",
  "info": {
    "title": "Fralli & Giovi Wedding API",
    "version": "1.0.0",
    "description": "Public read-only API with the information of the Fralli & Giovi wedding (June 6, 2026, Punta Licosa, Cilento). No authentication. Rate limit: 60 requests per minute per IP.",
    "contact": {
      "email": "info@fralliegiovi.com",
      "url": "https://fralliegiovi.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://fralliegiovi.com"
    }
  ],
  "externalDocs": {
    "url": "https://fralliegiovi.com/docs"
  },
  "paths": {
    "/api/v1/info": {
      "get": {
        "operationId": "getWeddingInfo",
        "summary": "Wedding info",
        "description": "Returns date, venue, dress code, RSVP deadline and contact email of the wedding.",
        "tags": [
          "wedding"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WeddingInfo"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/schedule": {
      "get": {
        "operationId": "getSchedule",
        "summary": "Weekend schedule",
        "description": "Returns the list of events of the wedding weekend (June 5–7, 2026).",
        "tags": [
          "wedding"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    }
                  },
                  "required": [
                    "events"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/travel": {
      "get": {
        "operationId": "getTravelInfo",
        "summary": "How to get there",
        "description": "Returns directions to the venue by plane, train and car.",
        "tags": [
          "wedding"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelOption"
                      }
                    }
                  },
                  "required": [
                    "options"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/accommodations": {
      "get": {
        "operationId": "listAccommodations",
        "summary": "Recommended accommodations",
        "description": "Returns the hotels, B&Bs and farmhouses recommended near the venue.",
        "tags": [
          "wedding"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accommodations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Accommodation"
                      }
                    }
                  },
                  "required": [
                    "accommodations"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/pages": {
      "get": {
        "operationId": "listPages",
        "summary": "Site pages",
        "description": "Returns the public pages of the website with a short description.",
        "tags": [
          "wedding"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Page"
                      }
                    }
                  },
                  "required": [
                    "pages"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "headers": {
              "RateLimit-Policy": {
                "description": "Rate limit policy (IETF draft): 60 requests per 60 seconds.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and seconds until reset.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details.",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "resolution": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code"
        ]
      },
      "WeddingInfo": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "couple": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "ceremonyStart": {
            "type": "string",
            "format": "date-time"
          },
          "receptionEnd": {
            "type": "string",
            "format": "date-time"
          },
          "venue": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "area": {
                "type": "string"
              },
              "streetAddress": {
                "type": "string"
              },
              "postalCode": {
                "type": "string"
              },
              "locality": {
                "type": "string"
              },
              "region": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              }
            }
          },
          "dressCode": {
            "type": "string"
          },
          "adultsOnly": {
            "type": "boolean"
          },
          "rsvpDeadline": {
            "type": "string",
            "format": "date"
          },
          "status": {
            "type": "string",
            "enum": [
              "upcoming",
              "past"
            ]
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contactEmail": {
            "type": "string",
            "format": "email"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          }
        },
        "required": [
          "name",
          "date",
          "venue"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "day": {
            "type": "string",
            "format": "date"
          },
          "start": {
            "type": "string"
          },
          "end": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "titleEn": {
            "type": "string"
          },
          "place": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "day",
          "start",
          "title",
          "place"
        ]
      },
      "TravelOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "mode",
          "summary"
        ]
      },
      "Accommodation": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "area": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "priceRange": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "type",
          "area"
        ]
      },
      "Page": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "title"
        ]
      }
    }
  }
}