{
  "openapi": "3.1.0",
  "info": {
    "title": "Guest2Host API",
    "version": "1.0.0",
    "description": "Vacation rentals listed by their owners, each booked directly on the owner’s own website. Search stays, check dates, get booking links and send owners a traveler’s question. Read access is free and needs no key. Same operations as the MCP server at https://api.guest2host.com/mcp.",
    "contact": {
      "name": "Guest2Host",
      "url": "https://guest2host.com/contact"
    },
    "termsOfService": "https://guest2host.com/terms"
  },
  "servers": [
    {
      "url": "https://api.guest2host.com"
    }
  ],
  "externalDocs": {
    "url": "https://guest2host.com/developers"
  },
  "paths": {
    "/api/v1/stays": {
      "get": {
        "operationId": "searchStays",
        "summary": "Search vacation rentals",
        "description": "Find vacation rentals listed by their owners that are booked directly on the owner's own website (no platform fees). Filter by place, dates, guests, pets and nightly price. With checkIn and checkOut, only stays open for those dates are returned. Returns up to 25 stays with photo, price, owner-reported rating and booking link.",
        "parameters": [
          {
            "name": "where",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Town, state, region or kind of place, e.g. \"McMinnville\", \"Oregon wine country\", \"lake Alabama\""
            }
          },
          {
            "name": "checkIn",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Check-in date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "checkOut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Check-out date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "guests",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 40,
              "description": "Number of guests the stay must sleep"
            }
          },
          {
            "name": "pets",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "true = only stays that allow pets"
            }
          },
          {
            "name": "maxPricePerNight",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "Highest acceptable \"from\" nightly rate, USD"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 25,
              "description": "Maximum results (default 10)"
            }
          },
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stays/{slug}": {
      "get": {
        "operationId": "getStay",
        "summary": "Get stay details",
        "description": "Full details for one stay: description, amenities, beds and baths, photos, approximate location, host name, owner-reported ratings, links to the same home on Airbnb/Vrbo when the owner lists them, and when its calendar last synced.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The stay’s slug, from /api/v1/stays"
          },
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No stay with that slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stays/{slug}/dates": {
      "get": {
        "operationId": "checkDates",
        "summary": "Check dates",
        "description": "Whether one stay is open for a check-in/check-out window, from the owner's own calendars (synced about every 30 minutes). When the dates are taken, returns up to three nearby open windows of the same length.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The stay’s slug, from /api/v1/stays"
          },
          {
            "name": "checkIn",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Check-in date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "checkOut",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Check-out date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No stay with that slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stays/{slug}/booking-link": {
      "get": {
        "operationId": "getBookingLink",
        "summary": "Get booking link",
        "description": "The link to book a stay on the owner's own website, where the guest books and pays the owner directly. Guest2Host takes no fee and never handles payment. Optional dates and guests are passed along for reference.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The stay’s slug, from /api/v1/stays"
          },
          {
            "name": "checkIn",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Check-in date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "checkOut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Check-out date, YYYY-MM-DD",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "guests",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 40
            }
          },
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No stay with that slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/destinations": {
      "get": {
        "operationId": "listDestinations",
        "summary": "List destinations",
        "description": "The destinations Guest2Host has stays in, with how many stays each has.",
        "parameters": [
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stays/{slug}/inquiries": {
      "post": {
        "operationId": "sendInquiry",
        "summary": "Ask the owner a question",
        "description": "Send a traveler's question to the owner of a stay by email, for example about early check-in or a longer stay. The owner replies to the traveler's email directly. Use only with the traveler's name, email and question, and only after they have agreed to send it. This does not book or hold the dates.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The stay’s slug, from /api/v1/stays"
          },
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No stay with that slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "guestName": {
                    "type": "string",
                    "description": "The traveler's name"
                  },
                  "guestEmail": {
                    "type": "string",
                    "description": "Where the owner should reply"
                  },
                  "message": {
                    "type": "string",
                    "description": "The traveler's question, 10–2000 characters"
                  },
                  "checkIn": {
                    "type": "string",
                    "description": "Check-in date, YYYY-MM-DD",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "checkOut": {
                    "type": "string",
                    "description": "Check-out date, YYYY-MM-DD",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "guests": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40
                  },
                  "guestPhone": {
                    "type": "string",
                    "description": "Optional phone number"
                  }
                },
                "required": [
                  "guestName",
                  "guestEmail",
                  "message"
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/applications": {
      "post": {
        "operationId": "applyToList",
        "summary": "Apply to list a rental",
        "description": "For owners: apply to list a vacation rental on Guest2Host (free, no commission). Sends the owner's name, email and basic property details to the Guest2Host team; once approved, the owner gets a sign-in email and can publish the listing. Use only with the owner's agreement.",
        "parameters": [
          {
            "name": "via",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your agent’s name, to attribute booking-link clicks"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "The request needs changing; `error` says how",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ownerName": {
                    "type": "string"
                  },
                  "ownerEmail": {
                    "type": "string",
                    "description": "Where the sign-in invite goes"
                  },
                  "propertyName": {
                    "type": "string",
                    "description": "e.g. \"Riverbend Cabin\""
                  },
                  "location": {
                    "type": "string",
                    "description": "Town and state, e.g. \"Leavenworth, WA\""
                  },
                  "propertyType": {
                    "type": "string",
                    "enum": [
                      "house",
                      "cottage",
                      "cabin",
                      "carriage-house",
                      "condo",
                      "apartment"
                    ]
                  },
                  "sleeps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40
                  },
                  "directBookingUrl": {
                    "type": "string",
                    "description": "The owner's own booking site, if they have one"
                  },
                  "airbnbUrl": {
                    "type": "string"
                  },
                  "vrboUrl": {
                    "type": "string"
                  },
                  "wantsSiteBuild": {
                    "type": "boolean",
                    "description": "No booking site yet and would like Guest2Host to build one (paid)"
                  },
                  "notes": {
                    "type": "string"
                  }
                },
                "required": [
                  "ownerName",
                  "ownerEmail",
                  "propertyName",
                  "location",
                  "propertyType",
                  "sleeps"
                ]
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
