{
  "openapi": "3.1.0",
  "info": {
    "title": "MinpakuX Open Platform (MOP) API",
    "description": "REST API for minpaku/minsu property management, booking, availability, and local guides.\n\nMarkets: Japan (民泊), Korea (민박), Taiwan (民宿)\nLanguages: en, zh, zh-TW, ja, ko\n",
    "version": "1.0.0",
    "contact": {
      "name": "Solanalink Engineering",
      "email": "support@solanalink.jp",
      "url": "https://minpakux.solanalink.jp/en/developer"
    },
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://minpakux.solanalink.jp/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/properties": {
      "get": {
        "operationId": "searchProperties",
        "summary": "Search properties",
        "description": "List active properties with rooms and host info. Supports filtering by region, city, and pagination.",
        "tags": [
          "Properties"
        ],
        "parameters": [
          {
            "name": "region",
            "in": "query",
            "description": "Market region filter",
            "schema": {
              "type": "string",
              "enum": [
                "JAPAN",
                "KOREA",
                "TAIWAN"
              ]
            }
          },
          {
            "name": "city",
            "in": "query",
            "description": "City name (partial match)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Property status filter",
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "DRAFT",
                "SUSPENDED"
              ],
              "default": "ACTIVE"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Results per page",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of results to skip",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of properties",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/properties/{propertyId}": {
      "get": {
        "operationId": "getProperty",
        "summary": "Get property details",
        "description": "Detailed property info including rooms, host profile, and refund policy. All text fields include multilingual variants (Zh, Ja, Ko).",
        "tags": [
          "Properties"
        ],
        "parameters": [
          {
            "name": "propertyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Property details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyDetailResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/availability": {
      "get": {
        "operationId": "checkAvailability",
        "summary": "Check room availability",
        "description": "Get daily availability calendar for rooms in a property. Returns availability status, nightly price, and minimum stay for each date.\nMaximum date range is 90 days. Prices reflect calendar overrides, weekend pricing, and base rates.\n",
        "tags": [
          "Availability"
        ],
        "parameters": [
          {
            "name": "propertyId",
            "in": "query",
            "required": true,
            "description": "Property ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roomId",
            "in": "query",
            "description": "Filter to specific room (omit for all rooms)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": true,
            "description": "Start date (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Availability calendar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/bookings": {
      "post": {
        "operationId": "createBooking",
        "summary": "Create reservation",
        "description": "Create a new reservation. Uses distributed locking to prevent double-booking.\nAutomatically calculates pricing with nightly rates, weekend pricing, calendar overrides, extra guest fees, cleaning fee, and service fee (5%).\nMaximum stay: 30 nights.\n\nSupports idempotency via the `Idempotency-Key` header to prevent duplicate bookings on network retry.\nKeys are stored for 24 hours. Sending the same key with an identical payload returns the cached response.\nSending the same key with a different payload returns 409 IDEMPOTENCY_CONFLICT.\n",
        "tags": [
          "Bookings"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key to prevent duplicate bookings on retry (recommended format: UUID v4).\nCached for 24 hours per API key. Same key + same body = cached response.\nSame key + different body = 409 IDEMPOTENCY_CONFLICT.\n",
            "schema": {
              "type": "string",
              "example": "550e8400-e29b-41d4-a716-446655440000"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBookingRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Booking created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Room unavailable, booking conflict, or idempotency key conflict.\nError codes: DATE_UNAVAILABLE, BOOKING_CONFLICT, IDEMPOTENCY_CONFLICT.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/bookings/dry-run": {
      "post": {
        "operationId": "simulateBooking",
        "summary": "Simulate booking (price check)",
        "description": "Calculate booking price and check availability without creating a reservation.\nUse this before createBooking to preview pricing breakdown including nightly rates, fees, and total.\n",
        "tags": [
          "Bookings"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DryRunRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pricing simulation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DryRunResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Room unavailable for requested dates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/properties/{propertyId}/rooms": {
      "get": {
        "operationId": "getPropertyRooms",
        "summary": "List rooms for a property",
        "description": "Get all available rooms for a property with full pricing details. Sorted by base price ascending.",
        "tags": [
          "Properties"
        ],
        "parameters": [
          {
            "name": "propertyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of rooms",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/properties/{propertyId}/reviews": {
      "get": {
        "operationId": "getPropertyReviews",
        "summary": "List reviews for a property",
        "description": "Get published guest reviews for a property. Includes overall and category ratings (cleanliness, accuracy, communication, location, check-in, value).",
        "tags": [
          "Properties"
        ],
        "parameters": [
          {
            "name": "propertyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of reviews",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/bookings/{bookingId}": {
      "get": {
        "operationId": "getBooking",
        "summary": "Get booking details",
        "description": "Get full booking details including property, room, pricing breakdown, guest info, and access code.",
        "tags": [
          "Bookings"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Booking details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingDetailResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/bookings/{bookingId}/cancel": {
      "post": {
        "operationId": "cancelBooking",
        "summary": "Cancel a booking",
        "description": "Cancel a booking with refund calculation. Uses pre-execution authorization pattern:\n- Without `X-Confirm: true` header: returns 428 with refund preview (no changes made)\n- With `X-Confirm: true` header: executes cancellation and processes Stripe refund\n",
        "tags": [
          "Bookings"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Confirm",
            "in": "header",
            "description": "Set to \"true\" to execute the cancellation. Omit for preview only.",
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Booking cancelled successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelBookingResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Booking cannot be cancelled (already cancelled, completed, etc.)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "428": {
            "description": "Confirmation required — returns refund preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfirmationRequiredResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/pricing": {
      "post": {
        "operationId": "calculatePricing",
        "summary": "Calculate pricing for a room",
        "description": "Calculate total price for a room and date range. Lighter than dry-run — no availability check, just pricing math.\nReturns nightly price breakdown with calendar overrides, weekend pricing, fees, and constraints.\n",
        "tags": [
          "Pricing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PricingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pricing calculation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/oauth/authorize": {
      "get": {
        "operationId": "oauthAuthorize",
        "summary": "OAuth 2.1 authorization",
        "description": "Start the OAuth 2.1 authorization code flow with mandatory PKCE.\nValidates the client and redirects to the consent screen where the host approves or denies access.\n",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "code"
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "description": "Public OAuth client ID (mpx_client_*)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "description": "Must match a registered redirect URI",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": true,
            "description": "Space-separated scopes",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "description": "PKCE S256 code challenge",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "S256"
              ]
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "Opaque state for CSRF protection",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorization page rendered (when not auto-redirecting)"
          },
          "302": {
            "description": "Redirect to consent screen"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "operationId": "oauthToken",
        "summary": "Exchange code or refresh token",
        "description": "OAuth 2.1 token endpoint. Supports:\n- `authorization_code` grant with PKCE code_verifier\n- `refresh_token` grant with token rotation\n",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/OAuthTokenRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OAuthTokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthTokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid grant or request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "error_description": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid client credentials"
          }
        }
      }
    },
    "/oauth/introspect": {
      "post": {
        "operationId": "oauthIntrospect",
        "summary": "Introspect an access token",
        "description": "Check if an access token is active and get its metadata (RFC 7662).",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token introspection result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthIntrospectionResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "operationId": "oauthRevoke",
        "summary": "Revoke a token",
        "description": "Revoke an access or refresh token (RFC 7009). Always returns 200 per spec.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token revoked (or already invalid)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/guides": {
      "get": {
        "operationId": "searchGuides",
        "summary": "Search local guides",
        "description": "List published local area guides for a property. Includes multilingual content, location data, and engagement metrics.",
        "tags": [
          "Guides"
        ],
        "parameters": [
          {
            "name": "propertyId",
            "in": "query",
            "required": true,
            "description": "Property ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Guide type filter",
            "schema": {
              "type": "string",
              "enum": [
                "RESTAURANT",
                "TRANSPORT",
                "ATTRACTION",
                "SHOPPING",
                "EMERGENCY",
                "CUSTOM"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of guides",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuideListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key from the MinpakuX Developer Portal (format: mop_live_xxx)"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Invalid request parameters",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (60 requests/minute)",
        "headers": {
          "Retry-After": {
            "description": "Seconds until rate limit resets",
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code (e.g., AUTH_INVALID, RATE_LIMITED, INVALID_PARAMS)"
              },
              "message": {
                "type": "string",
                "description": "Human-readable error message"
              },
              "is_retriable": {
                "type": "boolean",
                "description": "Whether the request can be retried (true for 429/5xx)"
              },
              "retry_after": {
                "type": "integer",
                "description": "Seconds to wait before retrying (present for rate-limited responses)"
              },
              "doc_url": {
                "type": "string",
                "description": "Link to relevant API documentation"
              },
              "alternative_action": {
                "type": "string",
                "description": "Suggested alternative action for the agent"
              },
              "details": {
                "type": "object",
                "description": "Additional error context"
              }
            },
            "required": [
              "code",
              "message",
              "is_retriable"
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "PropertySummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "nameZh": {
            "type": [
              "string",
              "null"
            ]
          },
          "nameJa": {
            "type": [
              "string",
              "null"
            ]
          },
          "nameKo": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "type": "string",
            "enum": [
              "JAPAN",
              "KOREA",
              "TAIWAN"
            ]
          },
          "country": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "propertyType": {
            "type": "string"
          },
          "coverImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "host": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "handle": {
                "type": "string"
              },
              "rating": {
                "type": "number"
              },
              "reviewCount": {
                "type": "integer"
              }
            }
          },
          "rooms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoomSummary"
            }
          }
        }
      },
      "RoomSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "roomType": {
            "type": "string"
          },
          "baseGuests": {
            "type": "integer"
          },
          "maxGuests": {
            "type": "integer"
          },
          "basePrice": {
            "type": "number",
            "description": "Base nightly price"
          },
          "currency": {
            "type": "string",
            "enum": [
              "JPY",
              "KRW",
              "TWD",
              "CNY",
              "USD"
            ]
          },
          "weekendPrice": {
            "type": [
              "number",
              "null"
            ]
          },
          "cleaningFee": {
            "type": "number"
          },
          "minStay": {
            "type": "integer"
          },
          "maxStay": {
            "type": "integer"
          }
        }
      },
      "PropertyListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PropertySummary"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationMeta"
              }
            }
          }
        }
      },
      "PropertyDetailResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PropertySummary"
              },
              {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "latitude": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "longitude": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "checkInTime": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "checkOutTime": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "selfCheckIn": {
                    "type": "boolean"
                  },
                  "amenities": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "houseRules": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "refundPolicy": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "rules": {
                        "description": "Tiered refund rules sorted by daysBeforeCheckIn"
                      },
                      "defaultRefundPercent": {
                        "type": "integer"
                      },
                      "gracePeriodHours": {
                        "type": "integer"
                      }
                    }
                  }
                }
              }
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "AvailabilityResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "propertyId": {
                "type": "string"
              },
              "startDate": {
                "type": "string",
                "format": "date"
              },
              "endDate": {
                "type": "string",
                "format": "date"
              },
              "rooms": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "roomId": {
                      "type": "string"
                    },
                    "roomName": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "dates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "available": {
                            "type": "boolean"
                          },
                          "reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "property_blocked",
                              "blocked",
                              "booked",
                              "unavailable"
                            ]
                          },
                          "price": {
                            "type": "number"
                          },
                          "minStay": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "CreateBookingRequest": {
        "type": "object",
        "required": [
          "propertyId",
          "roomId",
          "checkInDate",
          "checkOutDate",
          "guest"
        ],
        "properties": {
          "propertyId": {
            "type": "string"
          },
          "roomId": {
            "type": "string"
          },
          "checkInDate": {
            "type": "string",
            "format": "date",
            "description": "Check-in date (YYYY-MM-DD)"
          },
          "checkOutDate": {
            "type": "string",
            "format": "date",
            "description": "Check-out date (YYYY-MM-DD)"
          },
          "adults": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          },
          "children": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "infants": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "guest": {
            "type": "object",
            "required": [
              "name",
              "email"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "phone": {
                "type": "string"
              }
            }
          },
          "specialRequests": {
            "type": "string"
          }
        }
      },
      "BookingResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "PENDING"
                ]
              },
              "propertyId": {
                "type": "string"
              },
              "roomId": {
                "type": "string"
              },
              "checkInDate": {
                "type": "string",
                "format": "date"
              },
              "checkOutDate": {
                "type": "string",
                "format": "date"
              },
              "nights": {
                "type": "integer"
              },
              "guests": {
                "type": "object",
                "properties": {
                  "adults": {
                    "type": "integer"
                  },
                  "children": {
                    "type": "integer"
                  },
                  "infants": {
                    "type": "integer"
                  },
                  "total": {
                    "type": "integer"
                  }
                }
              },
              "pricing": {
                "$ref": "#/components/schemas/PricingBreakdown"
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "DryRunRequest": {
        "type": "object",
        "required": [
          "propertyId",
          "roomId",
          "checkInDate",
          "checkOutDate"
        ],
        "properties": {
          "propertyId": {
            "type": "string"
          },
          "roomId": {
            "type": "string"
          },
          "checkInDate": {
            "type": "string",
            "format": "date"
          },
          "checkOutDate": {
            "type": "string",
            "format": "date"
          },
          "adults": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          },
          "children": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          }
        }
      },
      "DryRunResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "available": {
                "type": "boolean"
              },
              "propertyId": {
                "type": "string"
              },
              "roomId": {
                "type": "string"
              },
              "checkInDate": {
                "type": "string",
                "format": "date"
              },
              "checkOutDate": {
                "type": "string",
                "format": "date"
              },
              "nights": {
                "type": "integer"
              },
              "guests": {
                "type": "object",
                "properties": {
                  "adults": {
                    "type": "integer"
                  },
                  "children": {
                    "type": "integer"
                  },
                  "total": {
                    "type": "integer"
                  }
                }
              },
              "pricing": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PricingBreakdown"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "nightlyPrices": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "format": "date"
                            },
                            "price": {
                              "type": "number"
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "PricingBreakdown": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "JPY",
              "KRW",
              "TWD",
              "CNY",
              "USD"
            ]
          },
          "roomRate": {
            "type": "number",
            "description": "Total room rate (sum of nightly prices)"
          },
          "cleaningFee": {
            "type": "number"
          },
          "extraGuestFee": {
            "type": "number",
            "description": "Fee for guests exceeding base guest count"
          },
          "serviceFee": {
            "type": "number",
            "description": "Platform service fee (5% of room rate + extra guest fee)"
          },
          "totalAmount": {
            "type": "number",
            "description": "Grand total (roomRate + cleaningFee + extraGuestFee + serviceFee)"
          }
        }
      },
      "GuideListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "slug": {
                  "type": "string"
                },
                "guideType": {
                  "type": "string",
                  "enum": [
                    "RESTAURANT",
                    "TRANSPORT",
                    "ATTRACTION",
                    "SHOPPING",
                    "EMERGENCY",
                    "CUSTOM"
                  ]
                },
                "title": {
                  "type": "string"
                },
                "titleZh": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "titleJa": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "titleKo": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "excerpt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "content": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "coverImage": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "locationTags": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "string"
                  }
                },
                "latitude": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "longitude": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "viewCount": {
                  "type": "integer"
                },
                "publishedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "author": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "handle": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationMeta"
              }
            }
          }
        }
      },
      "RoomDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "nameZh": {
            "type": [
              "string",
              "null"
            ]
          },
          "nameJa": {
            "type": [
              "string",
              "null"
            ]
          },
          "nameKo": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "descriptionZh": {
            "type": [
              "string",
              "null"
            ]
          },
          "descriptionJa": {
            "type": [
              "string",
              "null"
            ]
          },
          "descriptionKo": {
            "type": [
              "string",
              "null"
            ]
          },
          "roomType": {
            "type": "string"
          },
          "baseGuests": {
            "type": "integer"
          },
          "maxGuests": {
            "type": "integer"
          },
          "extraGuestFee": {
            "type": "number"
          },
          "basePrice": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "weekendPrice": {
            "type": [
              "number",
              "null"
            ]
          },
          "cleaningFee": {
            "type": "number"
          },
          "sizeSquareMeters": {
            "type": [
              "number",
              "null"
            ]
          },
          "beds": {
            "type": [
              "array",
              "null"
            ]
          },
          "facilities": {
            "type": [
              "array",
              "null"
            ]
          },
          "images": {
            "type": [
              "array",
              "null"
            ]
          },
          "coverImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "minStay": {
            "type": "integer"
          },
          "maxStay": {
            "type": "integer"
          }
        }
      },
      "RoomListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoomDetail"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "ReviewSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "rating": {
            "type": "integer",
            "description": "Overall rating (1-5)"
          },
          "comment": {
            "type": [
              "string",
              "null"
            ]
          },
          "commentZh": {
            "type": [
              "string",
              "null"
            ]
          },
          "commentJa": {
            "type": [
              "string",
              "null"
            ]
          },
          "commentKo": {
            "type": [
              "string",
              "null"
            ]
          },
          "categories": {
            "type": "object",
            "properties": {
              "cleanliness": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "accuracy": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "communication": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "location": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "checkIn": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "value": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "guest": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "image": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReviewListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReviewSummary"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationMeta"
              }
            }
          }
        }
      },
      "BookingDetailResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "property": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "nameZh": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "nameJa": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "nameKo": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "room": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "nameZh": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "nameJa": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "nameKo": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "checkInDate": {
                "type": "string",
                "format": "date"
              },
              "checkOutDate": {
                "type": "string",
                "format": "date"
              },
              "nights": {
                "type": "integer"
              },
              "guests": {
                "type": "object",
                "properties": {
                  "adults": {
                    "type": "integer"
                  },
                  "children": {
                    "type": "integer"
                  },
                  "infants": {
                    "type": "integer"
                  },
                  "total": {
                    "type": "integer"
                  }
                }
              },
              "pricing": {
                "$ref": "#/components/schemas/PricingBreakdown"
              },
              "guestEmail": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "specialRequests": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "accessCode": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "cancelledAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "CancelBookingResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "CANCELLED",
                  "REFUNDED"
                ]
              },
              "refund": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number"
                  },
                  "currency": {
                    "type": "string"
                  }
                }
              },
              "cancelledAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "ConfirmationRequiredResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "CONFIRMATION_REQUIRED"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable description of the action and its consequences"
              },
              "is_retriable": {
                "type": "boolean"
              },
              "preview": {
                "type": "object",
                "description": "Preview of the action that will be taken"
              },
              "confirm_header": {
                "type": "string",
                "description": "Header to add for confirmation (X-Confirm: true)"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      },
      "PricingRequest": {
        "type": "object",
        "required": [
          "roomId",
          "checkInDate",
          "checkOutDate"
        ],
        "properties": {
          "roomId": {
            "type": "string"
          },
          "checkInDate": {
            "type": "string",
            "format": "date"
          },
          "checkOutDate": {
            "type": "string",
            "format": "date"
          },
          "guests": {
            "type": "integer",
            "minimum": 1,
            "default": 1
          }
        }
      },
      "PricingResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "roomId": {
                "type": "string"
              },
              "checkInDate": {
                "type": "string",
                "format": "date"
              },
              "checkOutDate": {
                "type": "string",
                "format": "date"
              },
              "nights": {
                "type": "integer"
              },
              "guests": {
                "type": "integer"
              },
              "pricing": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PricingBreakdown"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "nightlyPrices": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "format": "date"
                            },
                            "price": {
                              "type": "number"
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "constraints": {
                "type": "object",
                "properties": {
                  "minStay": {
                    "type": "integer"
                  },
                  "maxStay": {
                    "type": "integer"
                  },
                  "maxGuests": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "processingTime": {
                "type": "string"
              }
            }
          }
        }
      },
      "OAuthTokenRequest": {
        "type": "object",
        "required": [
          "grant_type",
          "client_id",
          "client_secret"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": [
              "authorization_code",
              "refresh_token"
            ]
          },
          "client_id": {
            "type": "string",
            "description": "Public OAuth client ID"
          },
          "client_secret": {
            "type": "string",
            "description": "OAuth client secret"
          },
          "code": {
            "type": "string",
            "description": "Authorization code (for authorization_code grant)"
          },
          "redirect_uri": {
            "type": "string",
            "description": "Must match the authorize request (for authorization_code grant)"
          },
          "code_verifier": {
            "type": "string",
            "description": "PKCE code verifier (for authorization_code grant)"
          },
          "refresh_token": {
            "type": "string",
            "description": "Refresh token (for refresh_token grant)"
          }
        }
      },
      "OAuthTokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "description": "OAuth access token (mpx_at_*)"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "Bearer"
            ]
          },
          "expires_in": {
            "type": "integer",
            "description": "Token lifetime in seconds (3600 = 1 hour)"
          },
          "refresh_token": {
            "type": "string",
            "description": "Refresh token for obtaining new access tokens (mpx_rt_*)"
          },
          "scope": {
            "type": "string",
            "description": "Space-separated granted scopes"
          }
        }
      },
      "OAuthIntrospectionResponse": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean",
            "description": "Whether the token is currently active"
          },
          "scope": {
            "type": "string",
            "description": "Space-separated scopes (only if active)"
          },
          "client_id": {
            "type": "string",
            "description": "OAuth client ID (only if active)"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "Bearer"
            ]
          },
          "exp": {
            "type": "integer",
            "description": "Token expiration as Unix timestamp (only if active)"
          },
          "sub": {
            "type": "string",
            "description": "User ID of the host who granted access (only if active)"
          }
        }
      }
    }
  }
}