{
  "openapi": "3.0.1",
  "info": {
    "title": "DoorDash Scraper - Menus, Prices, Reviews & Ratings",
    "description": "Extract structured doordash.com data at scale. Search by keyword or paste store URLs to get store details, ratings, price tier, location, full menus, contact info, opening hours, review insights, star-rating breakdowns, and Google rating data.",
    "version": "1.1",
    "x-build-id": "Dg4NXprgijjb820ga"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~doordash-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-doordash-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~doordash-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-doordash-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~doordash-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-doordash-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 discover stores. 'search' runs keyword searches; 'url' takes store links or IDs directly.",
            "default": "search"
          },
          "search": {
            "title": "Search queries",
            "type": "array",
            "description": "Keywords to search on DoorDash (e.g. \"pizza\", \"sushi\", \"McDonald's\"). One search runs per term. Only used when mode = search.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location (optional)",
            "type": "string",
            "description": "City or address to localize search results, e.g. \"Brooklyn, NY\". If empty, a major city in your proxy country is used (US: New York, CA: Toronto, AU: Sydney, NZ: Auckland; DoorDash lists no stores elsewhere, so other proxy countries use New York and log a warning). If DoorDash cannot place the location, the run stops with a message saying so (it never guesses another place). Only used when mode = search."
          },
          "storeType": {
            "title": "Store type",
            "enum": [
              "any",
              "restaurant",
              "grocery",
              "retail"
            ],
            "type": "string",
            "description": "Limit search to a store category. 'restaurant' excludes convenience/grocery stores. Only used when mode = search.",
            "default": "any"
          },
          "ratedOnly": {
            "title": "Well-rated only",
            "type": "boolean",
            "description": "Only return stores that have a customer rating (drops unrated / very low rated stores). Only used when mode = search.",
            "default": false
          },
          "dealsOnly": {
            "title": "Deals only",
            "type": "boolean",
            "description": "Only return stores currently offering deals/offers. Only used when mode = search.",
            "default": false
          },
          "minRating": {
            "title": "Minimum rating (search mode only)",
            "enum": [
              "any",
              "4",
              "4.5",
              "4.6",
              "4.7",
              "4.8",
              "4.9"
            ],
            "type": "string",
            "description": "Only return stores rated at least this many stars using DoorDash's rating filter. When set, this overrides the 'Well-rated only' filter. Search mode only.",
            "default": "any"
          },
          "fastDeliveryOnly": {
            "title": "Fast delivery only (search mode only)",
            "type": "boolean",
            "description": "Only return stores with delivery estimates of 30 minutes or less for your location, using DoorDash's 'Under 30 min' filter. Search mode only.",
            "default": false
          },
          "urls": {
            "title": "Store URLs or IDs",
            "type": "array",
            "description": "DoorDash store links or bare numeric store IDs. Supported link shapes: the canonical page (with or without a name slug, with any query string), a specific menu (/store/<name>-<id>/<menuId>/), /convenience/store/<id>/, the store's reviews page (/reviews/store/<id>/), and any locale-prefixed variant (/en-CA/, /fr-CA/, /es-US/, /en/, ...) of those. Links copied from page source with &amp; or &#x27; escapes are decoded. Multiple supported. A business/chain page (/business/<name>-<id>/ or /b/<city>/<brand>-<id>/), a category, dish, city or search-results page, a drd.sh short link or a non-DoorDash link has no single store id and is skipped with a warning in the log -- open an individual store link instead. If you leave this untouched in URL mode, the example links shown here are scraped. Only used when mode = url.",
            "default": [
              "https://www.doordash.com/store/juniors-restaurant-new-york-704090/",
              "https://www.doordash.com/store/673363/?pickup=true",
              "https://www.doordash.com/store/2691971/1531826/",
              "https://www.doordash.com/convenience/store/370903/",
              "https://www.doordash.com/reviews/store/2691971/",
              "https://www.doordash.com/en-CA/store/673363/",
              "25943279"
            ],
            "items": {
              "type": "string"
            }
          },
          "includeMenu": {
            "title": "Include menu",
            "type": "boolean",
            "description": "Fetch the full menu (categories + items with price, image, dietary tags). Requires a store-detail fetch per store.",
            "default": true
          },
          "includeBusiness": {
            "title": "Include contact & hours",
            "type": "boolean",
            "description": "Fetch phone number, website and opening hours by day.",
            "default": true
          },
          "includeReviews": {
            "title": "Include reviews",
            "type": "boolean",
            "description": "Fetch reviews preview (up to ~5 recent public reviews), the full 1-5 star histogram, theme highlights and Google rating aggregate.",
            "default": true
          },
          "maxReviews": {
            "title": "Max reviews per store",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum written reviews kept in reviews.items for each store when 'Include reviews' is on. DoorDash itself serves at most about 5 recent public reviews per store to a logged-out visitor, so the default of 20 keeps everything it serves; lower it to keep fewer. 0 = no written reviews (the star histogram, review counts, themes and Google rating are still included). Never adds a charge: reviews ride on the store's single detail fetch.",
            "default": 20
          },
          "maxStores": {
            "title": "Max stores",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of stores to return across all searches/URLs. 0 = no limit.",
            "default": 20
          },
          "maxPages": {
            "title": "Max search pages",
            "minimum": 0,
            "type": "integer",
            "description": "Optional bound on result pages walked per search query (50 stores per page). Leave empty to walk every result page -- the run already stops at the Max stores cap, so this only matters if you also want to limit page depth. Only used when mode = search."
          },
          "proxy": {
            "title": "Proxy",
            "type": "object",
            "description": "Apify Residential proxy is required for a clean IP. Pick the country your searches should be localized to. On a block the connection automatically rotates to a fresh residential IP, then to a neighbouring country; a plan without Residential proxy access falls back to a backup connection (results may be reduced).",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ],
              "apifyProxyCountry": "US"
            }
          },
          "resumeFromRunId": {
            "title": "Resume from run ID",
            "type": "string",
            "description": "Optional: paste a previous run ID (or dataset ID) from this actor. Stores already collected there are skipped, so this run only returns new ones."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns all matching stores as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED stores. Turn on \"Emit unchanged\" or \"Emit expired\" below to also see stores that did not change or that disappeared.",
            "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 search/URLs and filters you set (Max stores/Max pages do not affect this key)."
          },
          "emitUnchanged": {
            "title": "Emit unchanged stores (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return stores 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 need the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired stores (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return stores that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max stores/Max pages capped the run, and not on a Resume run.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Optional. Field names to exclude from UPDATED change detection (in addition to the fields that never count: nextOpenTime/nextCloseTime/asapAvailable/searchEtaMinutes and the currently-served menuId/menuName/menuHours tick with the clock or live load rather than reflecting a real store change, and reviews.items.reviewerDescription describes the reviewer, not the store). Accepts a top-level field name (e.g. \"rating\") or a dotted path into a nested field (e.g. \"reviews.items\"). Use this if a field in your setup turns out to be noisy.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}