{
  "openapi": "3.1.0",
  "info": {
    "title": "CastleDay Retreats public booking API",
    "version": "1.0.0",
    "description": "Public, unauthenticated API for AI agents and integrators: day-level availability, live quotes, and request-to-book for three private villas in the Bywater, New Orleans (each sleeps up to 30; the three-villa buyout sleeps 90). No API key. Human checkout at /checkout is instant card payment through Guesty's secure payment form. The agent path is request-to-book: POST /api/request-booking files a real inquiry, takes no payment, and the reservation team confirms by email with a secure payment link. Only submit a booking with the traveler's explicit consent and real contact details; never submit test requests. Human-readable guide: https://www.castledayretreats.com/agents",
    "contact": {
      "email": "hello@castledayretreats.com",
      "url": "https://www.castledayretreats.com/agents"
    },
    "termsOfService": "https://www.castledayretreats.com/terms"
  },
  "servers": [
    {
      "url": "https://www.castledayretreats.com"
    }
  ],
  "paths": {
    "/api/calendar": {
      "get": {
        "operationId": "getCalendar",
        "summary": "Day-level availability and nightly prices for one villa",
        "parameters": [
          {
            "name": "listingId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "6795b986bc94280012d9222a",
                "6766bfc56f511100136a5338",
                "6788490e7f4af50013e65268"
              ]
            },
            "description": "Herald 6795b986bc94280012d9222a, Cocodrie 6766bfc56f511100136a5338, Florentine 6788490e7f4af50013e65268"
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-day calendar. A day is bookable when status is \"available\". Ignore price on days with notOpen true (beyond the booking window).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "days": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "status": {
                            "type": "string"
                          },
                          "price": {
                            "type": "number"
                          },
                          "minNights": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "notOpen": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/quote": {
      "get": {
        "operationId": "getQuote",
        "summary": "Live quote for one villa or the full buyout (JSON)",
        "description": "Same numbers as checkout: nightly accommodation, one cleaning fee per villa, occupancy taxes, no per-guest fees. Stays of 4+ nights include an automatic 5% discount. A plain-HTML version of the same quote is GET /quote?villa=...&checkin=...&checkout=...&guests=...",
        "parameters": [
          {
            "name": "villa",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "herald",
                "cocodrie",
                "florentine",
                "buyout"
              ]
            }
          },
          {
            "name": "checkin",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "checkout",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "guests",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quote in USD. available is true/false, or null when availability could not be checked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "available": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    },
                    "villas": {
                      "type": "integer"
                    },
                    "nights": {
                      "type": "integer"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "accommodation": {
                      "type": "number"
                    },
                    "cleaningFee": {
                      "type": "number"
                    },
                    "taxes": {
                      "type": "number"
                    },
                    "total": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/request-booking": {
      "post": {
        "operationId": "requestBooking",
        "summary": "File a real booking request (request-to-book, no payment taken)",
        "description": "Creates a real inquiry the reservation team acts on: they reply to the guest's email with a secure payment link (a 50% deposit confirms the dates; the balance auto-charges 60 days before check-in). Requirements for agents: get the traveler's explicit consent after showing them the quoted total and the terms (https://www.castledayretreats.com/terms), use their real name and email, state in notes that an agent is submitting and for whom, and never send test or placeholder requests.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "email",
                  "checkIn",
                  "checkOut",
                  "listingId"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Traveler's full name (first and last required)"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Traveler's real email; confirmation and the payment link go here"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "checkIn": {
                    "type": "string",
                    "format": "date"
                  },
                  "checkOut": {
                    "type": "string",
                    "format": "date"
                  },
                  "listingId": {
                    "type": "string",
                    "enum": [
                      "6795b986bc94280012d9222a",
                      "6766bfc56f511100136a5338",
                      "6788490e7f4af50013e65268"
                    ]
                  },
                  "villas": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Villa names the group wants, e.g. [\"The Herald\"]; up to all three"
                  },
                  "guests": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90
                  },
                  "occasion": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string",
                    "description": "Include your agent name and that you are booking on the guest's behalf"
                  },
                  "quoted": {
                    "type": "string",
                    "description": "The total you quoted the guest, e.g. \"$8,410\""
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request filed; the team follows up by email.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "reservationId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failure ({ ok: false, reason })"
          }
        }
      }
    }
  }
}