{
  "openapi": "3.0.1",
  "info": {
    "title": "Klook Activity Availability & Prices",
    "description": "Scrape Klook availability and prices. Just add an activity URL or id and get every bookable date, time slot and ticket type with the exact price, remaining stock, sold-out flag and booking cut-off. Track price changes between runs. $0.50 per 1,000 slots.",
    "version": "1.0",
    "x-build-id": "IhD0qMvZgA6SCvYEG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/boncross~klook-availability/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-boncross-klook-availability",
        "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/boncross~klook-availability/runs": {
      "post": {
        "operationId": "runs-sync-boncross-klook-availability",
        "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/boncross~klook-availability/run-sync": {
      "post": {
        "operationId": "run-sync-boncross-klook-availability",
        "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",
        "properties": {
          "activities": {
            "title": "Activities or packages",
            "type": "array",
            "description": "Klook activity URLs or activity ids, or a package link (the address with ?package_id= in it). An activity is expanded into every package it sells, so you can paste the address of the page you are looking at, such as the Hong Kong Disneyland one.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs (bulk upload)",
            "type": "array",
            "description": "Klook page addresses, with the option to load them in bulk from a file, a Google Sheet or a remote list. Use this when you have more links than you want to paste. Combined with anything in the list above.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxPackagesPerActivity": {
            "title": "Max packages per activity",
            "minimum": 0,
            "type": "integer",
            "description": "When an activity is expanded, price at most this many of its packages. 0 means all of them.",
            "default": 0
          },
          "maxItems": {
            "title": "Maximum results for the whole run",
            "minimum": 0,
            "type": "integer",
            "description": "A run-wide ceiling across every target. The per-target limit above applies to each one separately, so ten targets at 50 each returns 500; set this to cap the total. Zero means no run-wide limit. Rows that report an input the actor could not resolve are not counted here and are never charged for.",
            "default": 0
          },
          "maxSlotsPerPackage": {
            "title": "Max slots per package",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many rows per package. 0 means no limit.",
            "default": 0
          },
          "dateFrom": {
            "title": "From date",
            "type": "string",
            "description": "Earliest date to keep, as YYYY-MM-DD. When this or To date is set, Days ahead is not used.",
            "default": ""
          },
          "dateTo": {
            "title": "To date",
            "type": "string",
            "description": "Latest date to keep, as YYYY-MM-DD. When this or From date is set, Days ahead is not used.",
            "default": ""
          },
          "daysAhead": {
            "title": "Days ahead",
            "minimum": 0,
            "maximum": 400,
            "type": "integer",
            "description": "Keep only dates within this many days from today. 14 by default. Set 0 for every date Klook has on sale. Not used when From date or To date is set.",
            "default": 14
          },
          "dateLevel": {
            "title": "Date-level product",
            "type": "boolean",
            "description": "For passes with no real time slots. Reports one row per date with an empty time.",
            "default": false
          },
          "maxDates": {
            "title": "Max dates per package",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only the first N dates. 0 means no limit.",
            "default": 0
          },
          "onlyAvailable": {
            "title": "Only bookable slots",
            "type": "boolean",
            "description": "Drop sold-out rows. Filtered rows are free.",
            "default": false
          },
          "includePerSkuStock": {
            "title": "Per-sku stock",
            "type": "boolean",
            "description": "On options that sell more than one ticket type, add a second lookup so each type gets its own remaining stock. Turn off to halve the requests.",
            "default": true
          },
          "includeTicketTypePrices": {
            "title": "Exact price per ticket type",
            "type": "boolean",
            "description": "On packages that sell several ticket types (Adult, Child, Senior…), look up each type's price for every date returned, so each row carries the price that ticket type costs on that day. Prices of many attractions change by date, so without this the per-type price is left empty and only the slot price is given. Adds one lookup per date on multi-type packages.",
            "default": true
          },
          "includePriceBeforePromotion": {
            "title": "Price before promotion",
            "type": "boolean",
            "description": "Every price is the one Klook shows a buyer, with any current promotion applied. Turn this on to add, beside it, the price before the promotion for each time slot and ticket type (priceBeforePromotion, unitPriceBeforePromotion) and an isPromotion flag. Adds one lookup per option, so the run takes longer.",
            "default": false
          },
          "includeBookingRules": {
            "title": "Booking rules",
            "type": "boolean",
            "description": "Add each package's booking rules to its rows: whether the ticket is for a fixed date or flexible, the minimum and maximum quantity per booking, eligibility notes such as free entry for young children, the package's usage validity and booking terms (on tours, its cancellation rule), and for timed tickets each ticket type's age band and booking terms (cancellation, confirmation). Sale status, combo flags and per-ticket-type quantity limits are included either way. Adds two lookups per package.",
            "default": false
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "description": "ISO currency code. Prices come back quoted in it. Default USD.",
            "default": "USD"
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Klook locale code, such as en_GB, en_US or ja_JP. Package and ticket names come back in English whichever you pick.",
            "default": "en_GB"
          },
          "priceStoreName": {
            "title": "Price memory store",
            "type": "string",
            "description": "Name a key-value store and each run remembers the last price per slot, so rows carry the change since the previous run.",
            "default": ""
          },
          "onlyNewOrChanged": {
            "title": "Only new or changed",
            "type": "boolean",
            "description": "Return only slots whose price moved since the last run. Needs a price memory store.",
            "default": false
          },
          "skipEmptyPackages": {
            "title": "Skip packages with no stock",
            "type": "boolean",
            "description": "When an activity is expanded, drop the packages that have nothing bookable in your date window before pricing them. Saves requests on large activities.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Parallel requests",
            "minimum": 1,
            "maximum": 64,
            "type": "integer",
            "description": "How many requests run at once across the whole run. The default is the fastest level measured clean; lower it only if a run reports refusals or errors.",
            "default": 64
          },
          "delayMs": {
            "title": "Delay between requests (ms)",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "Optional pause before each call, in milliseconds. 0 (the default) runs as fast as the parallel limit allows.",
            "default": 0
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}