{
  "openapi": "3.0.1",
  "info": {
    "title": "OPTIMA Hotel Rate Scraper",
    "description": "Captures direct-booking prices from any hotel or ryokan running the OPTIMA booking engine (*.reservation.jp): selling price, pre-discount price, discount rate, member price and remaining rooms for every room x plan x future check-in date, including sold-out dates.",
    "version": "0.1",
    "x-build-id": "2yNR50gUy31QOpA4y"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/cobocus~optima-hotel-rate-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-cobocus-optima-hotel-rate-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/cobocus~optima-hotel-rate-scraper/runs": {
      "post": {
        "operationId": "runs-sync-cobocus-optima-hotel-rate-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/cobocus~optima-hotel-rate-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-cobocus-optima-hotel-rate-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "propertyUrls"
        ],
        "properties": {
          "propertyUrls": {
            "title": "Property URLs",
            "type": "array",
            "description": "One or more OPTIMA booking-engine URLs. Paste any page of the property's own booking site - the search form, the room list, anything: https://go-botanicalpoolclub.reservation.jp/ja/hotels/bpc/searchInput. Both site shapes are supported: group sites (/ja/hotels/<code>/...) and single-property sites (/ja/...). Any number of properties.",
            "items": {
              "type": "string"
            }
          },
          "monthsAhead": {
            "title": "Months ahead",
            "minimum": 1,
            "maximum": 18,
            "type": "integer",
            "description": "Scan every day from today through this many months ahead. Ignored if both Start date and End date are set. Run this Actor daily to build a rolling 'today + N months' time series.",
            "default": 6
          },
          "startDate": {
            "title": "Start date (advanced)",
            "type": "string",
            "description": "Advanced: explicit range start, YYYY-MM-DD. Leave empty to start from today in Japan (recommended for daily monitoring). Dates before today are rejected by the site - it silently serves today's availability instead - so such rows are reported as not collected rather than guessed at."
          },
          "endDate": {
            "title": "End date (advanced)",
            "type": "string",
            "description": "Advanced: explicit range end, YYYY-MM-DD, inclusive. Leave empty to use Start date + Months ahead."
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Number of adult guests per room. A property that cannot host this many adults in any room returns no rooms at all for every date, so match it to the property you are tracking.",
            "default": 2
          },
          "nights": {
            "title": "Nights",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Length of stay. The check-out date is derived from each check-in date plus this many nights. Prices are for the whole stay, not per night.",
            "default": 1
          },
          "rooms": {
            "title": "Rooms",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Number of rooms to search for per booking.",
            "default": 1
          },
          "child1": {
            "title": "Children - band 1",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "OPTIMA splits children into five configurable age/meal bands whose exact labels are set per property (typically elementary-school age down to infants without meal or bedding). Band 1 is the oldest band. Leave all at 0 for an adults-only search.",
            "default": 0
          },
          "child2": {
            "title": "Children - band 2",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Children in band 2. See band 1 for how OPTIMA splits child ages.",
            "default": 0
          },
          "child3": {
            "title": "Children - band 3",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Children in band 3. See band 1 for how OPTIMA splits child ages.",
            "default": 0
          },
          "child4": {
            "title": "Children - band 4",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Children in band 4. See band 1 for how OPTIMA splits child ages.",
            "default": 0
          },
          "child5": {
            "title": "Children - band 5",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Children in band 5, the youngest. See band 1 for how OPTIMA splits child ages.",
            "default": 0
          },
          "dayUse": {
            "title": "Day-use plans",
            "type": "boolean",
            "description": "Search day-use (no overnight stay) plans instead of overnight stays. Most properties offer none, in which case every date comes back with no rooms.",
            "default": false
          },
          "includeSoldOut": {
            "title": "Include sold-out dates",
            "type": "boolean",
            "description": "Keep rows for dates and rooms with nothing bookable. Recommended ON: knowing when a property sells out is itself rate data, and OPTIMA lists its unbookable rooms explicitly.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency (advanced)",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Maximum number of requests in flight at once, across all properties. Capped at 10. One request per check-in date, and OPTIMA serves 0.7-2.5 MB of uncompressed HTML per request, so a live production site should not be hit harder than this.",
            "default": 5
          },
          "runSummaryDatasetName": {
            "title": "Run summary dataset name",
            "type": "string",
            "description": "Optional. Name of a dataset to append this run's summary to, as a single row per run. Useful on a schedule: consecutive daily runs build one small table you can read at a glance to confirm each run collected every date, instead of aggregating tens of thousands of rate rows. Named datasets are retained indefinitely. The summary is always written to this run's key-value store as OUTPUT regardless of this setting."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy, OFF by default. This is deliberate and measured, not an oversight: OPTIMA is a property's own booking engine with no anti-bot measures, and no IP blocking or rate limiting was seen across hundreds of requests. It also serves 0.7-2.5 MB of UNCOMPRESSED HTML per check-in date, and the shared datacenter proxy pool moves that at roughly 23 KB/s - an A/B on the Apify platform, same property and same 7 dates, took 211 s through the proxy against 10.2 s without it, for identical data and zero errors either way. Residential proxy is billed per GB and would cost more than a run earns. Turn a proxy on if a property ever starts blocking you; nothing else about the run changes.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}