{
  "openapi": "3.0.1",
  "info": {
    "title": "Chope Scraper - Singapore & Asia Restaurant Leads",
    "description": "Scrape Chope restaurants across Singapore and Asia: name, phone, full address, area, cuisine, price band, ratings, geo, menus, photos and reviews. Turn dining venues into B2B leads. Export to JSON, CSV or Excel. Independent tool, not affiliated with Chope.",
    "version": "0.1",
    "x-build-id": "Oeq8x7o8aWzO1hjvW"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapesage~chope-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapesage-chope-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/scrapesage~chope-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapesage-chope-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/scrapesage~chope-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapesage-chope-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",
        "properties": {
          "countries": {
            "title": "Markets (countries / cities)",
            "type": "array",
            "description": "Chope markets to scrape every restaurant in. Pick one or more: singapore, kuala-lumpur, bali, jakarta, bandung, surabaya, bangkok, phuket. Singapore is the flagship market with the deepest coverage. One per row.",
            "items": {
              "type": "string",
              "enum": [
                "singapore",
                "kuala-lumpur",
                "bali",
                "jakarta",
                "bandung",
                "surabaya",
                "bangkok",
                "phuket"
              ],
              "enumTitles": [
                "Singapore",
                "Kuala Lumpur (Malaysia)",
                "Bali (Indonesia)",
                "Jakarta (Indonesia)",
                "Bandung (Indonesia)",
                "Surabaya (Indonesia)",
                "Bangkok (Thailand)",
                "Phuket (Thailand)"
              ]
            },
            "default": [
              "singapore"
            ]
          },
          "searchQueries": {
            "title": "Search terms (optional)",
            "type": "array",
            "description": "Keep only restaurants whose name or cuisine matches one of these (case-insensitive), e.g. \"italian\", \"steakhouse\", \"omakase\", \"Marriott\". Each term is matched against every restaurant in the selected markets. Leave empty to get every restaurant. One per row.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Chope restaurant URLs (optional)",
            "type": "array",
            "description": "Direct Chope restaurant URLs to scrape, e.g. https://www.chope.co/singapore-restaurants/restaurant/10-scotts . Scraped in addition to any selected markets. One per row.",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Max results (restaurants)",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Cap on restaurant records across the whole run.",
            "default": 100
          },
          "includeDetails": {
            "title": "Enrich with full details (phone, address, geo, rating, menus, photos)",
            "type": "boolean",
            "description": "Open each restaurant's Chope profile for the complete lead record: phone, full street address, area/neighbourhood, geo-coordinates, price band, rating + review count, menus and photos. One fast extra request per restaurant. Off = a quick, cheap directory pass (name, cuisine, market, profile URL only).",
            "default": true
          },
          "includeReviews": {
            "title": "Include diner reviews",
            "type": "boolean",
            "description": "Also extract the visible diner reviews on each profile (author, star rating, date and full review text). Requires 'Enrich with full details'. No extra request — parsed from the same profile page.",
            "default": false
          },
          "maxReviews": {
            "title": "Max reviews per restaurant",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Upper bound on reviews captured per restaurant when 'Include diner reviews' is on.",
            "default": 20
          },
          "cuisines": {
            "title": "Cuisine filter (optional)",
            "type": "array",
            "description": "Keep only restaurants whose cuisine matches one of these (case-insensitive substring, e.g. \"japanese\", \"seafood\", \"bar\"). Leave empty for all cuisines.",
            "items": {
              "type": "string"
            }
          },
          "priceTiers": {
            "title": "Price bands",
            "type": "array",
            "description": "Keep only restaurants in these price bands: 1 = $, 2 = $$, 3 = $$$, 4 = $$$$. Requires 'Enrich with full details'. Leave empty for all.",
            "items": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "4"
              ],
              "enumTitles": [
                "$",
                "$$",
                "$$$",
                "$$$$"
              ]
            },
            "default": []
          },
          "areaFilter": {
            "title": "Area / neighbourhood filter (optional)",
            "type": "array",
            "description": "Keep only restaurants in these areas (case-insensitive substring on Chope's area label, e.g. \"orchard\", \"chinatown\", \"tanjong pagar\"). Requires 'Enrich with full details'. Leave empty for all areas.",
            "items": {
              "type": "string"
            }
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only restaurants with a Chope rating at or above this value (1–5). Requires 'Enrich with full details'. 0 = no filter.",
            "default": 0
          },
          "deduplicate": {
            "title": "Deduplicate restaurants",
            "type": "boolean",
            "description": "Skip a restaurant already emitted earlier in the same run (common when scraping several markets at once).",
            "default": true
          },
          "monitorMode": {
            "title": "Monitoring mode — only new restaurants",
            "type": "boolean",
            "description": "Remember which restaurants were already returned and emit ONLY restaurants not seen in previous runs. Pairs with Apify Schedules to track new restaurant openings in a market over time (it does not conflict with Schedules — Schedules decide when to run, this decides what is new).",
            "default": false
          },
          "monitorStoreName": {
            "title": "Monitor store name",
            "type": "string",
            "description": "Named key-value store that holds the 'already seen' restaurant ids for monitoring mode. Use a different name per tracked market to keep histories separate.",
            "default": "chope-scraper-monitor"
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum parallel requests. Lower it if you see transient blocks; raise it for speed.",
            "default": 10
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxy settings. Chope's public pages are read over standard Apify Proxy with automatic IP rotation; the default works well. Blocked requests retry automatically on a fresh IP.",
            "default": {
              "useApifyProxy": true
            }
          },
          "urlsFromFile": {
            "title": "Import URLs from a file",
            "type": "string",
            "description": "Paste a list of URLs (one per line), OR one link to a .txt/.csv file, Google Sheet or Google Drive file containing them. Lets you import many Start URLs at once instead of typing each. Google Sheet/Drive share links are handled automatically."
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}