{
  "openapi": "3.0.1",
  "info": {
    "title": "Wego Scraper - MENA Hotel Deals, Rates & Reviews",
    "description": "Scrape Wego hotels by city or search URL. Get rates, providers, booking links, coordinates, scores, images and property details. Optionally fetch guest review text, ratings, dates and public author details.",
    "version": "1.0",
    "x-build-id": "3EdmvztkEKXZ1YZ9i"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~wego-com-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-wego-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~wego-com-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-wego-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~wego-com-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-wego-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": "How to start the scrape. 'search' runs the site's own hotel metasearch for the cities and stay window you set. 'url' processes the Wego hotels search URLs you paste: each URL's own path decides the city and dates, so the search-mode fields below do not apply there.",
            "default": "search"
          },
          "locations": {
            "title": "Cities",
            "type": "array",
            "description": "One or more city names, for example 'Dubai', 'Makkah', 'Cairo', 'Doha', 'Abu Dhabi'. Each name is matched against the site's own place search; a name with no match is skipped with a warning, never invented. Search mode only: in URL mode the pasted URL decides its own scope.",
            "default": [
              "Dubai"
            ],
            "items": {
              "type": "string"
            }
          },
          "checkIn": {
            "title": "Check-in date",
            "type": "string",
            "description": "Stay window start, YYYY-MM-DD. Defaults to about a week from today when left empty. Search mode only."
          },
          "checkOut": {
            "title": "Check-out date",
            "type": "string",
            "description": "Stay window end, YYYY-MM-DD. Must be after the check-in date; defaults to two nights after check-in when left empty. Search mode only."
          },
          "rooms": {
            "title": "Rooms",
            "minimum": 1,
            "maximum": 4,
            "type": "integer",
            "description": "Number of rooms to price, 1 to 4. Rates are quoted per room for the whole stay. Search mode only.",
            "default": 1
          },
          "adults": {
            "title": "Adults per room",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "Adult guests per room, 1 to 8. Search mode only.",
            "default": 2
          },
          "currency": {
            "title": "Currency",
            "enum": [
              "USD",
              "AED",
              "SAR",
              "EGP",
              "KWD",
              "QAR",
              "BHD",
              "OMR",
              "JOD",
              "TRY",
              "INR",
              "EUR",
              "GBP"
            ],
            "type": "string",
            "description": "Currency the rates are quoted in. The USD-converted price is always included on every row, so currency only changes the display values. Search mode only.",
            "default": "USD"
          },
          "urls": {
            "title": "Wego hotels URLs",
            "type": "array",
            "description": "Paste Wego hotels links: a search page like https://www.wego.com/en/hotels/searches/dxb/2026-12-01/2026-12-03?guests=2 (a search page with past dates is moved to the next upcoming week, with a warning), a city page, a hotel page, or a bare hotel id link. City and hotel links use the default stay window. Sort and order query parameters in a pasted link are not applied; use the sort input. Multi-URL supported; each is walked independently.",
            "default": [
              "https://www.wego.com/hotels/united-arab-emirates/dubai",
              "https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184",
              "https://www.wego.com/en/hotels/770060",
              "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
              "https://www.wego.com/en/hotels/searches/dubai/2026-11-20/2026-11-22?guests=2",
              "https://www.wego.com/ar/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
              "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22/690184?guests=2"
            ],
            "items": {
              "type": "string"
            }
          },
          "starRatings": {
            "title": "Star ratings",
            "type": "array",
            "description": "Keep only hotels of these star classes. Empty means every class. Applied to the rows this run reads. Applies in BOTH modes.",
            "items": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "4",
                "5"
              ],
              "enumTitles": [
                "1 star",
                "2 stars",
                "3 stars",
                "4 stars",
                "5 stars"
              ]
            }
          },
          "minPriceUsd": {
            "title": "Minimum total price (USD)",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep rows whose rate is at least this many US dollars for the whole stay. Applied to the rows this run reads. Applies in BOTH modes."
          },
          "maxPriceUsd": {
            "title": "Maximum total price (USD)",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep rows whose rate is at most this many US dollars for the whole stay. Applied to the rows this run reads. Applies in BOTH modes."
          },
          "freeCancellationOnly": {
            "title": "Free cancellation only",
            "type": "boolean",
            "description": "Keep only rows whose quoted rate carries a free-cancellation window in the source's own terms. Applied to the rows this run reads. Applies in BOTH modes.",
            "default": false
          },
          "sortBy": {
            "title": "Order the returned rows by",
            "enum": [
              "popularity",
              "price_asc",
              "price_desc",
              "stars_desc",
              "rating_desc"
            ],
            "type": "string",
            "description": "Arranges the rows this run collected, after they are read. 'As the site streamed them' keeps the source's own display order for your stay window. This is a local tidy up of one run's output, not a catalogue-wide ordering. Applies in BOTH modes.",
            "default": "popularity"
          },
          "fetchDetails": {
            "title": "Fetch hotel details",
            "type": "boolean",
            "description": "Read each hotel's own profile for the complete record: address, phone, email, website, description, named amenities, check-in and check-out times, room and floor counts, payment options and review highlights. The feed row already carries name, star class, coordinates, review score, cheapest rate, provider, room type, board basis and free-cancellation terms. Turning this on adds the Hotel detail enrichment charge per record actually enriched this run.",
            "default": true
          },
          "fetchReviews": {
            "title": "Fetch guest reviews",
            "type": "boolean",
            "description": "Optionally read the latest guest reviews for each hotel. Off by default. The existing Hotel detail enrichment event adds one unit per started block of 10 reviews returned on a committed hotel row. Works with Fetch hotel details on or off; no review charge for zero reviews, failed reads or suppressed incremental rows.",
            "default": false
          },
          "maxReviewsPerHotel": {
            "title": "Max reviews per hotel",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum guest reviews to collect for each hotel when Fetch guest reviews is on. Reviews are read 10 at a time; 1-10 reviews add one enrichment unit, 11-20 add two, and so on. Set 0 to skip review reads.",
            "default": 20
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "type": "integer",
            "description": "The single cap on this run: stop after collecting this many records across all cities and URLs. Set 0 for unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "Max feed polls per city",
            "minimum": 0,
            "type": "integer",
            "description": "Safety bound on how many times to re-poll the streaming results feed per city while it fills in. Leave empty (0) to use the built-in ceiling: a hard cap of 30 polls per city always applies, so the run stops when the feed reports it is done, at Max items, or after 30 polls, whichever comes first.",
            "default": 0
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Leave the default. Every read route on this source answers plain JSON to the standard shared pool, so the cheapest connection already works.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for records already collected there. Use this after an interrupted or capped run. For recurring monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or weekly recurring monitoring of the same scope, for example a city rate watch. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. What is compared: every output field of the hotel, including the cheapest rate (price, tax, currency, free cancellation, rooms left), so a rate move IS reported as UPDATED. What is excluded: the booking deep link and the scrape timestamp (they change on every run), plus any field you list in Ignore fields when detecting changes. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately per city, URL and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the cities, URLs and filters, so two different scopes never mix state."
          },
          "emitUnchanged": {
            "title": "Emit unchanged records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want a full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked scope: not when Max items capped it, not when Resume was used, and not when the run was refused. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "changeScope": {
            "title": "Change scope (incremental mode only)",
            "enum": [
              "all",
              "priceAndStock"
            ],
            "type": "string",
            "description": "All fields (default) compares the whole hotel record. Price and availability only compares just the rate fields (price, tax, currency, free cancellation, rooms left), so descriptions, photos and review counts never create an UPDATED row. Changing the scope changes the automatic state key unless you set State key.",
            "default": "all"
          },
          "compactUpdates": {
            "title": "Compact updates (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to return UPDATED and EXPIRED rows as short rows: ids, current price, priceChanges with old and new values, and per-rate changes. NEW rows stay complete. Compact rows carry no reviews, so they add no review charge.",
            "default": false
          },
          "expireAfterMissedScans": {
            "title": "Expire after missed scans (incremental mode only)",
            "minimum": 1,
            "type": "integer",
            "description": "With Emit expired on, a hotel is marked EXPIRED only after it was missing from this many consecutive complete scans. Default 1 expires at once. EXPIRED means the hotel dropped out of the results, which can be a listing change or a real removal; use the price and availability fields to judge availability.",
            "default": 1
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Field names that never make a row UPDATED and never appear in changedFields (the fields stay in the output). Use a top-level name such as reviewCount, or a dotted path such as images.url to ignore one key inside every element of a nested list. Applies to incremental mode only.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "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 page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, not the full record; the complete record always stays in the dataset. Leave empty to skip; this 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 record 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 records 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}