{
  "openapi": "3.0.1",
  "info": {
    "title": "Traveloka Hotel Scraper - SEA Hotel Prices & Ratings",
    "description": "Scrape Traveloka hotels across Singapore, Malaysia, Indonesia, Thailand, Vietnam and the Philippines: nightly prices, star ratings, guest scores, coordinates and photos by city. Paste search or hotel links, and monitor price changes with recurring updates.",
    "version": "0.1",
    "x-build-id": "yEItJxMaHdMLaNruW"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~traveloka-com-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-traveloka-com-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/abotapi~traveloka-com-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-traveloka-com-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/abotapi~traveloka-com-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-traveloka-com-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": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Search walks hotel results for the locations below. URL mode pastes Traveloka hotel-search links (with spec=) or hotel detail links; search filters are ignored in URL mode.",
            "default": "search"
          },
          "market": {
            "title": "Market (site locale)",
            "enum": [
              "en-sg",
              "en-my",
              "en-id",
              "en-th",
              "en-vn",
              "en-ph",
              "en-au"
            ],
            "type": "string",
            "description": "Which Traveloka storefront to read. Sets the language and the currency prices are returned in.",
            "default": "en-sg"
          },
          "locations": {
            "title": "Cities or areas",
            "type": "array",
            "description": "City or area names as you would type them into Traveloka's hotel search box (e.g. Singapore, Bangkok, Kuta). Each location is resolved to Traveloka's internal region id, then its results are walked. Multiple locations are split evenly across your result budget.",
            "items": {
              "type": "string"
            }
          },
          "checkInDate": {
            "title": "Check-in date",
            "type": "string",
            "description": "Check-in date (YYYY-MM-DD). Leave empty to default to tomorrow (site time)."
          },
          "checkOutDate": {
            "title": "Check-out date",
            "type": "string",
            "description": "Check-out date (YYYY-MM-DD). Leave empty to default to the day after check-in."
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Number of adult guests per search.",
            "default": 2
          },
          "rooms": {
            "title": "Rooms",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Number of rooms per search.",
            "default": 1
          },
          "sortBy": {
            "title": "Sort results by",
            "enum": [
              "popularity",
              "price-asc",
              "price-desc"
            ],
            "type": "string",
            "description": "Search-mode sort order requested from the site. Popularity is Traveloka's own default order.",
            "default": "popularity"
          },
          "minPrice": {
            "title": "Min nightly price",
            "minimum": 0,
            "type": "integer",
            "description": "Drop hotels whose nightly price is below this. Applied to returned results (client side), in the market's currency."
          },
          "maxPrice": {
            "title": "Max nightly price",
            "minimum": 0,
            "type": "integer",
            "description": "Drop hotels whose nightly price is above this. Applied to returned results (client side), in the market's currency."
          },
          "minStarRating": {
            "title": "Min star rating",
            "type": "integer",
            "description": "Drop hotels below this star rating (0 = keep all). Applied to returned results (client side).",
            "default": 0
          },
          "minGuestRating": {
            "title": "Min guest score (0-10)",
            "minimum": 0,
            "maximum": 10,
            "type": "number",
            "description": "Drop hotels whose guest review score is below this (Traveloka scores out of 10). Applied to returned results (client side); hotels without a score are kept."
          },
          "urls": {
            "title": "Traveloka links",
            "type": "array",
            "description": "Multi-URL supported. Paste hotel-search links that contain spec= (from a browser search) and/or hotel detail links. Filter-mode fields are ignored; a search link walks forward from its own dates and occupancy.",
            "items": {
              "type": "string"
            }
          },
          "fetchDetails": {
            "title": "Enrich each hotel (facilities, features, images, ratings)",
            "type": "boolean",
            "description": "Merges the static-content feed into each row: facility codes + labels, feature highlights, extra images and UGC ratings. Each enriched row bills the detail-enrichment surcharge event once; unenriched rows push the base listing and bill nothing extra. URL-pasted hotel pages are still read as documents.",
            "default": false
          },
          "fetchReviews": {
            "title": "Read guest reviews per hotel",
            "type": "boolean",
            "description": "Adds a reviews array (author, rating, date, text) from the review JSON lane, up to maxReviews per hotel. Rows with fetched reviews bill the detail-enrichment surcharge like other enrichment (1 unit per 10 reviews). Works with fetchDetails on or off.",
            "default": false
          },
          "maxReviews": {
            "title": "Max reviews per hotel",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on review rows per hotel when fetchReviews is on. Billing scales with volume: the enrichment surcharge bills 1 unit per row plus 1 unit per started block of 10 reviews (10 reviews = 1 unit, 25 = 3, 1000 = 100) — heavy review pulls bill their transfer.",
            "default": 10
          },
          "maxItems": {
            "title": "Max results",
            "minimum": 0,
            "type": "integer",
            "description": "The one real cap: maximum hotel records to return per run, across all locations. 0 means unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per location",
            "minimum": 0,
            "type": "integer",
            "description": "Safety cap on result pages walked per location. 0 (default) means no page cap: the walk follows Max results and the site's own result count.",
            "default": 0
          },
          "resumeFromRunId": {
            "title": "Resume from run ID",
            "type": "string",
            "description": "ID of an interrupted run of this Actor to continue, skipping hotels already saved by that run. Leave empty for a fresh run. Conflicts with Incremental mode (pick one)."
          },
          "incrementalMode": {
            "title": "Incremental mode",
            "type": "boolean",
            "description": "Recurring monitoring: the Actor remembers hotels it saw on the previous run of the same scope and only emits new or changed ones. Rows carry changeType/changedFields. Unchanged rows are suppressed (set emitUnchanged to also emit and bill them). Conflicts with Resume from run ID.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Name for the storage the incremental baseline is kept under. Leave empty to derive it from your scope (mode, market, locations, dates, occupancy and filters), so different setups never share a baseline."
          },
          "emitUnchanged": {
            "title": "Emit unchanged rows",
            "type": "boolean",
            "description": "With Incremental mode: also emit (and bill) rows whose fingerprint did not change, marked changeType UNCHANGED.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired rows",
            "type": "boolean",
            "description": "With Incremental mode: also emit (and bill) rows that were tracked before but no longer appeared in a complete walk, marked changeType EXPIRED. Never fires when the walk was capped, truncated or refused part-way.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Premium lane: browses through Apify RESIDENTIAL with a multi-country pool (SG/ID/MY/TH/VN/PH, a fresh exit per attempt) and automatic failover when every pool exit is refused. Runs without the RESIDENTIAL group (datacenter) are refused by the site and fail over only to the operator's datacenter lane when configured. Free plans: remove the group and bring your own proxy.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify → Settings → API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip (never changes the dataset output). Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}