# Dollar Tree Scraper - Product Prices, Case Packs & Stock (USA) (`superslowsloth/dollartree-products`) Actor

Dollar Tree scraper: search terms or categories to one row per product with USD price, case pack size and case price, stock flag, UPC, brand, categories, clearance flag, rating and link. For Dollar Tree price and assortment watching.

- **URL**: https://apify.com/superslowsloth/dollartree-products.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** E-commerce, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Dollar Tree scraper: product prices, case packs and stock (USA)

This Dollar Tree scraper reads [dollartree.com](https://www.dollartree.com) (the US
dollar-store chain's online shop: food, candy, drinks, cleaning, party, craft, kitchen and
seasonal goods) by **search term or category** and returns **one row per product**: the
**USD price**, the **case pack size and the case price** (Dollar Tree sells online by the
case), the minimum order quantity, the stock flag, UPC, brand, every category the product is
filed under, the clearance flag, the sale and list price, rating, link and photo. Run it on a
schedule and diff the datasets to get a **Dollar Tree price and assortment watch** for the
terms and categories you follow.

No account, no API key, no login, no browser. It calls the JSON search service the website's
own search box and category pages call, 24 products per request.

### Input

| Field | Notes |
|---|---|
| `searchTerms` | What to search for, one term per line, as typed in the website's search box (`paper towels`, `candy`). Each term is read page by page until it runs out. A product found by two terms is written once. |
| `categories` | Categories to read in full, one per line, named by their labels from the department down and joined with `>`: `Food, Candy & Drinks` for a department, `Food, Candy & Drinks > Candy & Gum > Chocolate Candy` for a group inside it. The labels are looked up on dollartree.com when the run starts; a label that does not exist fails that category with the list of the ones that do. A category's number (`1669243216`) is also accepted. Categories are read after the search terms. |
| `maxItems` | Stop after writing this many products (default 100, up to 50,000), across all terms and categories. |
| `proxyConfiguration` | Apify's automatic datacenter proxy by default; dollartree.com answered datacenter addresses when this actor was built. |

Give at least one search term or category. Example input:

```json
{
  "searchTerms": ["paper towels", "candy"],
  "categories": ["Food, Candy & Drinks > Candy & Gum"],
  "maxItems": 30
}
```

### Output

One row per product. Prices are numbers in US dollars. `product_id` is the unique key of a row;
`scraped_at` is when it was read, so keep the datasets of scheduled runs and compare them to see a
price move, a markdown or a product going out of stock.

| Field | Notes |
|---|---|
| `product_id` | Dollar Tree's product id, a string (`423153`). |
| `name`, `brand` | The product name as the store shows it, and the brand (`Mike And Ike`). `brand` is null on the products that carry none (about half). |
| `category`, `categories` | The main category (`Gummy & Chewy Candy`) and every category the product is filed under, in the order sent. `categories` is an empty list when there are none; seasonal products list dozens. Of 353 products read on 2026-11-05 (paper towels, candy, LED lights and the first pages of the Department list), 121 were filed only under the store's internal `Non-Navigable Sub Collection` bucket: `categories` shows it as sent, `category` skips it (null if nothing else). |
| `url`, `image_url` | The product page and its first photo, as absolute addresses. |
| `currency` | `USD` when the response's price range is in dollars; null otherwise. |
| `price` | The price of **one item** (`sku.activePrice`), as the store sends it. |
| `unit_price` | The store's unit price (`product.x_unitPriceNumeric`), as sent; null when absent (about 1 product in 8). **Read it with `price`**: on 13 of 507 products read on 2026-11-05 the two disagree, and a price of 0.01 occurs; both are written as the store holds them. |
| `list_price`, `sale_price` | The price before a markdown, and the marked-down price. `sale_price` is null unless the product is marked down. |
| `clearance`, `deals` | True when the store flags the product clearance, and its deal labels (`["Clearance"]`; an empty list when none). |
| `case_pack_size`, `case_price` | Items in one full case, and the price of the case (`price` times `case_pack_size` on the products measured). Null when absent, and when the store sends 0 (a product it has not set up). |
| `minimum_quantity` | The online minimum order, in items. Null when absent or 0. It can be smaller than the case: 4 of a 30-roll case of paper towels. |
| `split_case_multiple` | Items per split-case step: 0 when the product cannot be bought in part of a case, otherwise the multiple (4, 6, 12). Null when absent. |
| `in_stock`, `availability` | `availability` is the store's value as sent (`INSTOCK`, `OUTOFSTOCK`); `in_stock` is true for `INSTOCK`, false for `OUTOFSTOCK`, null for anything else. This is the online listing, not a store's shelf. |
| `in_store_only` | True when the store flags the product `smsb_availableInStoreOnly`; null when absent. |
| `upcs` | The product's barcodes as a list, each as sent (18 digits, zero-padded); the store sends them as one comma-separated string. An empty list for the products without one. |
| `snap_eligible` | True when the store marks the product SNAP eligible; null when it says nothing. |
| `rating`, `review_count` | Average star rating as the store sends it (unrounded, `4.5516`) and the number of reviews it is from. **Both null where the product has no reviews**, never 0. |
| `description` | The product description as plain text; null where the store has none (about 4 products in 10). |
| `weight`, `length`, `width`, `height` | The package dimensions as the store spells them (`6 oz`, `1 in`); each null when absent. |
| `search_term`, `search_category` | What found the row: the search term, or the category as you named it. The other is null. |
| `scraped_at` | When the row was read, UTC, ISO 8601. |

Example row (a real row, 2026-11-05):

```json
{
  "product_id": "423153",
  "name": "Mike And Ike Ice Cream Truck Candy Mix, Assorted flavors, 1-ct.",
  "brand": "Mike And Ike",
  "category": "Gummy & Chewy Candy",
  "categories": [
    "Gummy & Chewy Candy"
  ],
  "url": "https://www.dollartree.com/mike-and-ike-ice-cream-truck-candy-mix-assorted-flavors-1-ct/423153",
  "image_url": "https://www.dollartree.com/ccstore/v1/images/?source=/file/v3031719448600512668/products/423153.jpg",
  "currency": "USD",
  "price": 1.25,
  "unit_price": 1.25,
  "list_price": 1.25,
  "sale_price": null,
  "clearance": false,
  "deals": [],
  "case_pack_size": 12,
  "case_price": 15.0,
  "minimum_quantity": 12,
  "split_case_multiple": 0,
  "in_stock": true,
  "availability": "INSTOCK",
  "in_store_only": false,
  "upcs": [
    "000000070970475306"
  ],
  "snap_eligible": true,
  "rating": 5.0,
  "review_count": 1,
  "description": "The delicious Mike and Ike Ice Cream Truck Candy Mix is a perfect addition to your candy supplies. The yummy, gluten-free, fat-free candy pack is a perfect treat for both kids and adults. Each pack of candy features assorted flavors that add a nostalgic touch to your evenings. You can also distribute the candies to guests at parties, family gatherings, and other fun events. Satisfy your candy cravings with the delicious pack of ice cream truck candy mix. Get the yummy Mike And Ike Ice Cream Truck Candy Mix for your candy supplies inventory. The candies contain bioengineered food ingredients.",
  "weight": "4.25 oz",
  "length": "0.75 in",
  "width": "5.37 in",
  "height": "3 in",
  "search_term": "candy",
  "search_category": null,
  "scraped_at": "2026-11-05T09:15:42Z"
}
```

#### Honest nulls

A value the response did not carry is `null` (or an empty list for `categories`, `deals` and `upcs`),
never `0` or `""`.

- **No store inventory.** `in_stock` is the online listing; it says nothing about a store's shelf.
- **No price history.** One run is one reading. Schedule it and keep the datasets.
- **Non-products are skipped.** The search index also holds blog posts and a "Handling Fee Product"
  with a price of 0; they are not written and not charged.

### Pricing

Pay per event:

- **$0.002** per run (`actor-start`), charged only after your input is validated, so a run that
  fails on bad input costs nothing.
- **$0.0028** per product written (`product-scraped`)

That is $2.80 per 1,000 products, 30% under the cheapest comparable Dollar Tree actor on the
Apify Store ($0.004 per item) when this one was built. A row is charged only after it is written.
A product found twice, a record that is not a product, and a category that does not exist are not
written and not charged.

### How it fetches

It calls `GET /ccstoreui/v1/search` on dollartree.com (an Oracle Commerce Cloud store on an
Endeca index) with `Ntt` (the term), `Nrpp=24` (records per page), `No` (the offset) and, for a
category, `N` (the category's number, looked up from the service's own category menu when the run
starts). The website's `/search` address answers 404 and the page its search box opens (`/searchresults`) holds no products in its HTML; this is the call the page draws its lists from.
Measured from the Apify platform on a probe run of 10 requests per proxy group (2026-11-05: **datacenter answered the full product list 10 of 10 times and residential 8 of 10**), which is why the
default is the automatic datacenter proxy. A refusal (403, 429, 5xx), a 200 that is not a search
answer, or a dropped connection is treated as the address being blocked: the actor retries from a
fresh exit address **and a different browser fingerprint** (four are tried in turn, one attempt
each).

Things worth knowing, all measured on 2026-11-05:

- **At most 10,024 results of one search.** The service clamps any offset past 10,000 to the page
  starting at record 10,001, so a search or category that matches more is read to that point and
  the run log says how many it matches. Use a narrower term or a sub-category (the department
  `Food, Candy & Drinks` has 2,148 products; the whole `Department` has 11,457).
- **Categories are a tree, looked up live.** `Food, Candy & Drinks` has seven groups (`Candy & Gum`,
  `Drinks`, `Food`, `Snacks`...), `Candy & Gum` has seven more (`Chocolate Candy`, `Gum & Mints`...).
  A label that does not exist at its level fails that category with the labels that do.
- **A search can match more than products.** The index holds blog posts next to products; they are
  skipped and counted in the run log.
- **Order is the store's relevance order.** The same search read twice moves only as the store's
  ranking does.

If dollartree.com changes the service, the run fails with a message instead of returning empty rows.

# Actor input Schema

## `searchTerms` (type: `array`):

What to search dollartree.com for, one term per line, as you would type it in the website's search box: 'paper towels', 'candy', 'birthday balloons'. Each term is read page by page (24 products a page) until it runs out or the max below is reached. A product found by two terms is written once. The website serves at most 10,024 results of one search, so use a narrower term or a category for a bigger list.

## `categories` (type: `array`):

Dollar Tree categories to read in full, one per line, named by their labels from the department down, joined with '>': 'Food, Candy & Drinks' for a whole department or 'Food, Candy & Drinks > Candy & Gum > Chocolate Candy' for a group inside it. The labels are looked up on dollartree.com when the run starts; one that does not exist fails with the list of those that do, and costs nothing. A category's number (for example 1669243216) is also accepted. Categories are read after the search terms.

## `maxItems` (type: `integer`):

Stop after writing this many product rows, across all search terms and categories. A product found twice is written and charged once. Up to 50,000 are accepted.

## `proxyConfiguration` (type: `object`):

Use Apify's automatic datacenter proxy (the default). dollartree.com answered Apify datacenter addresses with the full product list when this actor was built; the residential group was not needed. A refused request is retried from a fresh address and a different browser fingerprint.

## Actor input object example

```json
{
  "searchTerms": [
    "paper towels",
    "candy"
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "paper towels",
        "candy"
    ],
    "maxItems": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/dollartree-products").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": [
        "paper towels",
        "candy",
    ],
    "maxItems": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/dollartree-products").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "paper towels",
    "candy"
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/dollartree-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/dollartree-products"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5rtY51hqkHREP7O8i/builds/fkyFZyhLgmezo3n4Z/openapi.json
