{
  "openapi": "3.0.1",
  "info": {
    "title": "🍽️ Ultimate Yelp Scraper",
    "description": "Ultimate Yelp Scraper extracts public business data including names, categories, ratings, reviews, addresses, phone numbers, websites, hours, and business URLs. Build structured datasets for local lead generation, market research, competitor analysis, and business discovery.",
    "version": "1.0",
    "x-build-id": "bSgw50rKBlYhd0BmF"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scraper-engine~ultimate-yelp-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scraper-engine-ultimate-yelp-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/scraper-engine~ultimate-yelp-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scraper-engine-ultimate-yelp-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/scraper-engine~ultimate-yelp-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scraper-engine-ultimate-yelp-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": {
          "startUrls": {
            "title": "🔗 Start URLs (bulk)",
            "type": "array",
            "description": "🌐 One or more Yelp URLs — bulk-friendly, one per line or upload a file. Mix and match freely: 🏪 direct business pages (<code>/biz/...</code>), 🔍 search/listing pages (<code>/search?...</code>), 🗂️ collections (<code>/collection/...</code>), and 🎫 events (<code>/events/...</code>). When this is non-empty it takes priority over <b>🔎 Search by Keyword</b> below.",
            "items": {
              "type": "string"
            }
          },
          "search": {
            "title": "🔎 Search Keyword",
            "type": "string",
            "description": "💡 What to search for on Yelp, e.g. <code>restaurants</code>, <code>plumber</code>, <code>max</code>. Used only when <b>🔗 Start URLs</b> above is empty."
          },
          "searchLocation": {
            "title": "📍 Search Location",
            "type": "string",
            "description": "🏙️ City/state (or ZIP) to search in, e.g. <code>Los Angeles, CA</code>. Used together with 🔎 Search Keyword."
          },
          "maxItems": {
            "title": "🎯 Maximum Results",
            "minimum": 1,
            "type": "integer",
            "description": "✂️ Stop after this many businesses/collections/events, combined across every Start URL / search. Leave empty for no limit (careful with big searches!)."
          },
          "endPage": {
            "title": "📄 Search Pages to Walk",
            "minimum": 1,
            "type": "integer",
            "description": "🔢 How many search-result pages to paginate through (10 businesses/page) before stopping. Leave empty to keep paging until 🎯 Maximum Results is hit or results run out."
          },
          "deepDetail": {
            "title": "🔬 Deep Detail Mode",
            "type": "boolean",
            "description": "🕵️ When ON, the Actor navigates to each business page and reads the rendered DOM to also capture 🎪 amenities, 📖 about/history, ❓ Q&A, ✨ highlights, ✅ claimed status and 📅 year established — richer data, but sequential (slower). Turn OFF for a fast, fully concurrent run that returns everything available from Yelp's GraphQL API alone.",
            "default": true
          },
          "includeReviews": {
            "title": "⭐ Include Reviews",
            "type": "boolean",
            "description": "💬 Paginate and collect the full review feed for every business (author, rating, text, date, reactions). When OFF, only the first page of reviews that ships with the business detail is kept.",
            "default": true
          },
          "reviewSort": {
            "title": "↕️ Review Sort Order",
            "enum": [
              "relevance_desc",
              "date_desc",
              "date_asc",
              "rating_desc",
              "rating_asc",
              "elites_desc"
            ],
            "type": "string",
            "description": "📊 Order reviews are fetched in.",
            "default": "relevance_desc"
          },
          "startPageForReviews": {
            "title": "▶️ Start Review Page",
            "minimum": 1,
            "type": "integer",
            "description": "🔢 Skip ahead to this review page (10 reviews/page) instead of starting from page 1."
          },
          "endPageForReviews": {
            "title": "⏹️ End Review Page",
            "minimum": 1,
            "type": "integer",
            "description": "🔢 Stop after this review page. Leave empty to fetch every available review — can be slow for businesses with thousands of reviews."
          },
          "includePhotos": {
            "title": "📸 Include Photos",
            "type": "boolean",
            "description": "🖼️ Collect original-resolution photo URLs for every business.",
            "default": true
          },
          "endPageForPhotos": {
            "title": "🔢 Max Photo Pages",
            "minimum": 1,
            "type": "integer",
            "description": "📄 Limit how many photo pages (~30 photos/page) to collect. Leave empty to collect every available photo."
          },
          "includeAmenities": {
            "title": "🎪 Include Amenities",
            "type": "boolean",
            "description": "🏷️ Extract amenities/attributes (parking, Wi-Fi, accepted payments, accessibility, etc). Best-effort — most reliable with 🔬 Deep Detail Mode ON.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "🛡️ Proxy Configuration",
            "type": "object",
            "description": "🌐 By default the Actor connects with <b>NO proxy</b> for maximum speed. If Yelp's DataDome challenge rejects a bootstrap attempt, it automatically escalates: ⚡ No proxy → 🏢 Datacenter proxy → 🏠 Residential proxy (retried at least 3×) — then <b>sticks with Residential for every remaining request</b> in the run. Every escalation is logged clearly in real time. You can also force a specific tier yourself here (e.g. start straight on Residential for the toughest targets)."
          },
          "concurrency": {
            "title": "⚡ Concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "🚦 How many businesses to process in parallel on the shared warmed browser session (used only when 🔬 Deep Detail Mode is OFF — Deep Detail Mode is always sequential, one page at a time). Higher is faster but heavier.",
            "default": 5
          },
          "maxRetries": {
            "title": "🔁 Max Retries per Request",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "🔄 How many times to retry a single GraphQL/API call on a network error or transient block before giving up on it.",
            "default": 3
          },
          "maxBootstrapAttempts": {
            "title": "🚀 Max Bootstrap Attempts",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "🎰 How many fresh browser/IP attempts to make while trying to pass Yelp's DataDome challenge before giving up the whole run. Each attempt may also trigger a 🛡️ proxy tier escalation (see above).",
            "default": 12
          },
          "reloadsPerAttempt": {
            "title": "🔃 Reloads per Attempt",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "♻️ How many times to reload the SAME page (same IP) before rotating to a fresh browser attempt.",
            "default": 3
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}