Dutchie Dispensary Menu Scraper
Pricing
from $3.00 / 1,000 menu variants
Dutchie Dispensary Menu Scraper
Scrape Dutchie dispensary menus into one row per size. Get brand, category, strain, THC and CBD, recreational and medical prices, and live specials. HTTP menu export for price checks and assortment research.
Pricing
from $3.00 / 1,000 menu variants
Rating
0.0
(0)
Developer
Andrej Kiva
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Disclaimer: Unofficial tool — not affiliated with, sponsored by, or endorsed by Dutchie, Inc. or its affiliates. Data is read from publicly accessible dispensary menus only. No login. You are responsible for complying with applicable law and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.
Dutchie dispensary menus as one row per size: brand, category, strain, THC and CBD, recreational and medical prices, and live specials.
Paste a dispensary menu URL when you need the live shelf for pricing, assortment, or specials tracking. Each dataset row is one price variant. This is a Dutchie scraper and a Dutchie API alternative for Python, Node.js, and MCP. Export the dataset as JSON.
When to use
- Snapshot one dispensary menu, or several menus in one run
- Compare recreational and medical prices on the same size
- Keep mix-and-match and sale names next to the shelf price
- Limit the pull to one category, or to products that have a live special
Use a full menu (maxItems 0) for a catalog snapshot. Use a small maxItems when you only need a sample.
Key features
- Dispensary URL or slug, including embedded menu links
- One row per size, with recreational and medical prices
- Brand, category, subcategory, strain type
- THC and CBD potency with unit
- Sale and mix-and-match special names
- Specials-only mode and category filter
- HTTP fetch, 256 MB, no browser
Input
| Field | Required | Description |
|---|---|---|
startUrls | Yes | Dispensary menu URLs or a slug |
maxItems | No | Stop after this many variants. Default 40. 0 reads the full menu, capped at 5000 rows |
menuType | No | rec (default) or med. Both price columns are still saved |
categories | No | Flower, Pre-Rolls, Vaporizers, Concentrate, Edible, Tincture, Topicals, CBD, Seeds, Accessories, Apparel |
offersOnly | No | Keep products that have a live special |
Input example
{"startUrls": [{ "url": "https://dutchie.com/dispensary/pinnacle-cannabis-quincy" }],"maxItems": 40,"menuType": "rec","offersOnly": false}
Output
| Field | Description |
|---|---|
productName | Product name |
brand | Brand |
category | Menu category |
strainType | Strain type when the menu publishes one |
option | Size or weight |
price | Shelf price for the selected menu type |
specialPrice | Discounted price when published |
recPrice, medPrice | Recreational and medical prices |
currency | USD, or CAD for a Canadian province |
thc, cbd | Potency with unit |
specialsText | Live special names |
inStock | True when the product is on the active menu |
dispensaryName, city, state | Store |
productUrl | Product page |
Output example
{"source": "dutchie","dispensaryName": "Pinnacle Cannabis - Quincy","dispensarySlug": "pinnacle-cannabis-quincy","city": "Quincy","state": "MA","productName": "Example Flower","brand": "Example Brand","category": "Flower","strainType": "Hybrid","option": "3.5g","price": 45,"specialPrice": 40,"recPrice": 45,"medPrice": 40,"currency": "USD","thc": "22.5%","cbd": null,"specialsText": "Mix and match eighths","inStock": true,"menuType": "rec","productUrl": "https://dutchie.com/dispensary/pinnacle-cannabis-quincy/product/example-flower"}
Use cases
- Shelf check — export price, size, brand, and potency for one store
- Specials watch — turn on
offersOnlyand keep the special names - Assortment — filter to Flower or Edible and compare category mix across stores
- Rec vs med — read both price columns without a second run
Integration examples
Replace APIFY_TOKEN with your Apify token. The Actor name is crawloop/dutchie-menu-scraper.
Node.js
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor("crawloop/dutchie-menu-scraper").call({startUrls: [{ url: "https://dutchie.com/dispensary/pinnacle-cannabis-quincy" }],maxItems: 40,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("crawloop/dutchie-menu-scraper").call(run_input={"startUrls": [{"url": "https://dutchie.com/dispensary/pinnacle-cannabis-quincy"}],"maxItems": 40,})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
cURL
curl "https://api.apify.com/v2/acts/crawloop~dutchie-menu-scraper/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d "{\"startUrls\":[{\"url\":\"https://dutchie.com/dispensary/pinnacle-cannabis-quincy\"}],\"maxItems\":40}"
MCP and AI assistants
Use this Actor from AI tools via Apify MCP. Connect your Apify account, then call this Actor by its Store name.
Example prompts:
- "Run Dutchie Dispensary Menu Scraper for the Pinnacle Cannabis Quincy menu and return product, brand, size, price, and THC as JSON"
- "Scrape that Dutchie dispensary with offersOnly and list the special names next to the shelf price"
- "Pull the Flower category from two Dutchie dispensary URLs and compare eighth prices by brand"
FAQ
Does each product become one row?
A product with several sizes becomes one row per size. A single-size product is one row.
What if the dispensary URL does not resolve?
That store is skipped. If every URL misses, the run finishes with an empty dataset.
Does specials-only drop the rest of the menu?
Yes. offersOnly keeps products that currently have a sale or mix-and-match special.
Which price is price?
The shelf price for menuType (rec by default). recPrice and medPrice are always both present when the menu publishes them.