# Target Deal & Clearance Tracker (`famous_iron/target-deal-tracker`) Actor

Track Target.com clearance, sale and weekly-ad markdowns. Filter by deal type or minimum discount, rank by biggest price drop, and export the results.

- **URL**: https://apify.com/famous\_iron/target-deal-tracker.md
- **Developed by:** [J P](https://apify.com/famous_iron) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Target Deal & Clearance Tracker

**Find what's marked down at Target — with the discount already calculated.**

Search any keyword, and get back the products that are actually on sale: current price, original price, how much you save, and a direct link to buy. Filter to clearance only, set a minimum discount, or rank by the biggest price drops.

*An independent tool. Not affiliated with, endorsed by, or sponsored by Target Brands, Inc.*

Works across all of Target — apparel, home, electronics, tools, groceries, toys and beauty. Search by product type (`headphones`, `bedding`, `lego`) rather than department name; there's a lookup table below.

### What you get back

A real run — `womens tops`, clearance filter, ranked by biggest markdown:

| Discount | Now | Was | You save | Product |
| --- | --- | --- | --- | --- |
| **50%** | $7.50 | $15.00 | $7.50 | Women's Short Sleeve Ribbed T-Shirt |
| **50%** | $2.50 | $5.00 | $2.50 | Women's Fitted Pullover Tank Top |
| **50%** | $9.00 | $18.00 | $9.00 | Champion Iconic Essentials Raglan |
| **50%** | $15.00 | $30.00 | $15.00 | Solid & Striped Smocked Linen Blouse |

Each row also carries the brand, rating, review count, stock status, category, image URLs and a direct product link — up to 36 fields. Rows carry 33–36 depending on what Target publishes for that product; the deal columns are always present.

### What you can use it for

- **Deal and coupon sites** — a daily feed of genuine markdowns, already sorted by discount
- **Price monitoring** — track how a product's price moves between runs
- **Resale sourcing** — find clearance inventory worth flipping
- **Competitor and assortment research** — see what's discounted, by brand and category
- **Market research** — pull a full category with prices, ratings and availability

### Three ways to run it

**Find clearance deals**

```json
{
    "keyword": "womens tops",
    "deal_type": "clearance",
    "results_wanted": 50
}
```

**Only deep discounts, best first**

```json
{
    "keyword": "headphones",
    "min_discount_percent": 40,
    "rank_by_discount": true,
    "results_wanted": 25,
    "max_pages": 10
}
```

**Plain product search — no deal filter**

```json
{
    "keyword": "4k tv",
    "results_wanted": 100
}
```

You can also paste a Target **search** URL into `startUrl` instead of a keyword, and the Actor reads the search term and sort order from it:

```
https://www.target.com/s?searchTerm=womens+tops&sortBy=newest
```

Category pages (`/c/...`) and product pages (`/p/...`) are not supported — this Actor collects search results. Use the category name as a keyword instead: `"keyword": "shoes"` covers Target's shoes category.

### Tracking changes between runs

Running the same search twice returns the same products — Target's ranking is stable, and prices don't move in five minutes. Switch on **`track_changes`** and repeat runs become useful instead:

```json
{
    "keyword": "womens tops",
    "deal_type": "clearance",
    "track_changes": true,
    "results_wanted": 50
}
```

- **First run** saves a baseline and returns everything.
- **Later runs** return only what moved — and **nothing at all if nothing did**.

That second point catches people out: run the same tracked search twice in a row and the second run correctly returns zero products, because prices don't move in five minutes. Leave `track_changes` off unless you're running on a schedule.

Each record then carries a `change_type` plus what it was before:

| `change_type` | Meaning |
| --- | --- |
| `price_drop` | Cheaper than last run — includes `previous_price`, `price_change_amount`, `price_change_percent` |
| `new` | Not present in the previous run |
| `back_in_stock` | Shipping went from unavailable to available |
| `price_increase` | More expensive than last run |
| `out_of_stock` | Shipping went from available to unavailable |

Price drops are listed first, deepest first — so the top of the dataset is what a deal feed would publish.

**Pair it with a schedule.** A daily tracked run gives you a clean feed of the day's markdowns instead of the same catalogue every morning. Set `include_unchanged` if you also want the products that stayed put.

Each tracked search keeps its own history, keyed by keyword, deal type, sort, store and filters — so tracking `clearance bedding` never compares against `headphones`.

**One deliberate omission:** products that were in the previous run but not this one are *not* reported as gone. Target's ranking shifts between runs, so a product dropping out of the top results usually means it moved down the list, not that it disappeared. Reporting those would fill the feed with false alarms.

### Searching a whole category

Target's search works on **product types**, not department names. Typing `electronics`, `toys` or `grocery` returns nothing — on target.com those words open a category page instead of running a search, so there are no search results to collect. The Actor tells you this and suggests working alternatives if you try one.

To cover a category, run one keyword per product type:

| You want | Use these keywords |
| --- | --- |
| Electronics | `tv`, `laptop`, `headphones`, `bluetooth speaker` |
| Toys | `kids toys`, `lego`, `board games`, `dolls` |
| Home | `home decor`, `bedding`, `kitchen`, `storage` |
| Clothing | `womens clothing`, `mens clothing`, `kids clothing` |
| Furniture | `sofa`, `desk`, `dining table`, `bookshelf` |
| Beauty | `makeup`, `skincare`, `shampoo` |
| Grocery | `coffee`, `snacks`, `cereal` |
| Baby | `diapers`, `baby clothes`, `stroller` |
| Pets | `dog food`, `cat food`, `dog toys` |
| Sports | `fitness equipment`, `bike`, `yoga mat` |

Two-word terms usually work where the single word doesn't — `kids toys` returns 37,000 matches while `toys` returns none.

**The same applies to a few big brands.** `apple`, `disney` and `pokemon` open Target brand pages rather than searching, so they return nothing on their own. Add a product word and they work: `apple watch`, `disney toys`, `pokemon cards`. Most brands are fine as-is — `nike`, `samsung`, `lego`, `sony` and `barbie` all search normally.

**Example — electronics clearance:** run the Actor once per keyword (`tv`, `laptop`, `headphones`) with `deal_type: "clearance"`, and combine the datasets. Scheduling the same keyword daily is how you track prices over time.

### Filtering out accessories

Target's relevance ranking mixes accessories in with products. A search for `iphone` returns 16 phone cases and 8 phones; `iphone 16` returns **23 cases and 1 phone**. Two settings fix that:

```json
{
    "keyword": "apple iphone",
    "item_type": "cell phones"
}
```

- **`item_type`** — keep only these product types, comma separated
- **`exclude_item_type`** — drop these, e.g. `case, charger, screen protector`

Matching is a case-insensitive substring, so `phone` matches `Cell Phones`. Every record carries its `item_type`, so run once without a filter to see what's available. If a filter removes everything, the log lists the types that were actually returned.

**One caveat on configurable products.** Phones, TVs and anything sold in multiple storage sizes or colours show `Price Varies` instead of a figure, and Target publishes no comparison price for them — so they can never appear as discounted. Those rows are flagged with `price_is_range: true` and still carry a usable numeric `current_retail`. If you're hunting markdowns, they're not it; if you're tracking prices, they still work.

### How the deal filters work

Two filters work together, and you can use either or both.

**`deal_type`** applies Target's own filter — Clearance, Sale, Weekly Ad, BOGO, Target Circle Deals and more. This narrows the search at the source: clearance on *womens tops* returns about 180 products instead of 77,000.

**`min_discount_percent`** keeps only products marked down by at least that much, worked out from the current and regular price.

The second one matters because **Target doesn't offer every deal filter for every keyword.** *Womens tops* has a Clearance filter; *4k tv* doesn't; *organic coffee* offers "New Lower Price" and "Circle Deals" instead. The Actor checks which filters Target actually offers for your keyword, uses the one you asked for when it exists, and otherwise falls back to the discount threshold — and tells you so in the log. A deal run never quietly returns unfiltered results.

Turn on **`rank_by_discount`** to scan every allowed page first and save only the deepest markdowns, rather than the first ones found.

### Input

| Setting | Type | Default | What it does |
| --- | --- | --- | --- |
| `keyword` | string | — | What to search for. Provide this or `startUrl`. |
| `item_type` | string | — | Keep only these product types, comma separated (`cell phones`) |
| `exclude_item_type` | string | — | Drop these product types (`case, charger`) |
| `startUrl` | string | — | A Target search URL. Search term and sort are read from it. |
| `deal_type` | select | `any` | `clearance`, `sale`, `weekly_ad`, `bogo`, `circle_deals`, `new_lower_price`, `buy_and_save`, `value_bundles`, `gift_card`, `all_deals` |
| `min_discount_percent` | integer | `0` | Keep only products at least this far below regular price |
| `rank_by_discount` | boolean | `false` | Scan everything, then save the biggest markdowns first |
| `track_changes` | boolean | `false` | Only save what changed since the last run for this search |
| `include_unchanged` | boolean | `false` | When tracking, also keep products that did not move |
| `sort_by` | select | `relevance` | `newest`, `bestselling`, `PriceLow`, `PriceHigh`, `RatingHigh`, `Featured` |
| `results_wanted` | integer | `20` | How many products to save |
| `max_pages` | integer | `10` | Page limit, as a guardrail on run size |
| `include_sponsored` | boolean | `true` | Include sponsored placements |
| `storeId` / `zipCode` | string | `1771` / `10001` | Location for pricing and delivery availability |
| `proxyConfiguration` | object | off | Optional Apify Proxy |

### Output

One row per product.

The deal columns — `on_sale`, `discount_percent`, `discount_amount`, `formatted_comparison_price` — appear on **every** row, showing `0` and a blank when a product isn't discounted. That keeps the table and any CSV export aligned. Other fields Target doesn't publish for a product are left out rather than returned empty.

**Deal** — `on_sale`, `discount_percent`, `discount_amount`, `formatted_current_price`, `formatted_comparison_price`, `current_retail`, `reg_retail`, `price_is_range`

**Product** — `title`, `brand`, `tcin`, `parent_tcin`, `item_type`, `department_id`, `category_id`, `parent_category_id`, `vendor_name`, `is_marketplace`, `is_sponsored`

**Ratings** — `rating_average`, `rating_count`, `review_overall_sentiment`

**Availability** — `shipping_availability`, `scheduled_delivery_availability`, `sold_out`

**Links and media** — `buy_url`, `primary_image_url`, `alternate_image_urls`, `promotions`

**Run context** — `search_keyword`, `sort_by`, `position`, `page`, `current_page`, `total_pages`, `total_results`, `result_offset`, `scraped_at`

Images come from Target's image server, so you can resize them by adding parameters to the URL — `?wid=400&hei=400&fmt=jpeg` gives you a thumbnail without downloading the full image.

### Does location matter?

**Prices don't vary by location.** Verified across four stores in three states — identical prices everywhere. These are Target.com's online prices, so for price monitoring and deal tracking the default `storeId` and `zipCode` are fine.

Three things do vary:

| | Varies by location? |
| --- | --- |
| Prices and discounts | **No** — identical nationwide |
| Shipping availability | No — shipping is national |
| **Scheduled (same-day) delivery** | **Yes, a lot** — 7 of 24 products available in New York, 0 of 24 in Los Angeles |
| Clearance product mix | Mildly — totals match, but about a quarter of the products differ |

So set `storeId` and `zipCode` to a real nearby store if you care about same-day delivery availability, or want clearance matched to a region. Otherwise leave them.

**One limitation worth stating plainly:** this collects Target.com's **online** clearance, not the in-store clearance that resellers hunt with a price scanner. Store-level markdown inventory lives in a different Target system that this endpoint does not expose.

### Export and integrations

Download as **JSON, CSV, Excel or XML**, or connect the dataset to the **Apify API**, a **webhook**, **Google Sheets**, **Airtable**, **Make** or **Zapier**. Schedule it to run hourly, daily or weekly to track prices over time.

### Good to know

**Target caps a single search at 1,200 products.** It reports far more matches than that — a search saying "8,126 results" still only serves 1,200 — and refuses to go deeper. The Actor stops cleanly at that ceiling, so asking for more returns everything available rather than failing. To collect more, split the work across narrower keywords.

**Where the deals actually are.** Home goods and clothing get discounted hardest — often 17 to 19 of 24 products on a page, up to 55% off. Groceries, beauty and pet food rarely move. Worth knowing when picking keywords.

**If Target blocks a run, it fails rather than returning partial data.** Target signals throttling with a success status and no results, which is easy to mistake for "no more products". The Actor retries five times, then fails with a message saying how many products it had collected. A truncated price snapshot that looks complete is worse than a run that visibly failed.

**Getting zero results?** The most common cause is a `min_discount_percent` set higher than anything currently on sale. The run log tells you the deepest markdown it actually found, so you can adjust. Clothing and home goods carry the deepest discounts; groceries and beauty rarely exceed 15%.

**Sponsored duplicates are removed.** A sponsored placement is often the same product that also ranks organically, so a page can yield slightly fewer records than Target displays.

**Target's own paging repeats a few products.** Roughly 2% of listings reappear on a later page. The Actor removes them by product ID, so the dataset never contains duplicates — but it means a full 50-page sweep returns about 1,170 unique products rather than exactly 1,200. The run log reports how many duplicates were skipped.

### FAQ

**Does it work for categories other than clothing?**
Yes — verified across electronics, home, tools, grocery, toys, beauty, baby and pets. Any Target search keyword works.

**Why did my clearance search fall back to the discount filter?**
Target only offers a given deal filter for keywords where it has matching products. When the one you asked for isn't available, the log says so and the run uses `min_discount_percent` instead, which works everywhere. Broader keywords expose more deal filters than narrow ones.

**Do I need a proxy?**
Usually not. Enable Apify Proxy if runs start returning empty.

**Why is a field missing from a product?**
Target doesn't publish every attribute for every listing, and marketplace items in particular expose fewer fields. Missing means "not published" rather than "empty".

**Is this an official Target tool?**
No. This is an independent Actor with no affiliation to, endorsement by, or sponsorship from Target Brands, Inc. "Target" is their trademark and is used here only to describe which website the Actor reads. It collects publicly visible listing data — no accounts, no logins, no personal data.

**Is it legal to collect Target data?**
You are responsible for complying with Target's terms of use, applicable laws and privacy requirements. Use this for legitimate research, price monitoring and business workflows.

### Related

**Target Reviews Scraper** — customer reviews and ratings from product pages
**Shopify Product Scraper** — product and variant data from Shopify stores
**Trendyol Product Scraper** — products, prices and ratings from Trendyol

# Actor input Schema

## `startUrl` (type: `string`):

Optional. Paste a Target search URL instead of a keyword — the search term and sort order are read from it. Clear the Search keyword field when using this, otherwise the keyword takes precedence.

## `keyword` (type: `string`):

Search term used to collect products, for example "womens tops". Used instead of Start URL. If both are filled in, this wins.

## `item_type` (type: `string`):

Keep only products of these types, comma separated — for example "cell phones" to exclude cases and chargers from a phone search. Matching is a case-insensitive substring, so "phone" matches "Cell Phones". Leave blank to keep everything.

## `exclude_item_type` (type: `string`):

Drop products of these types, comma separated — for example "case, screen protector, charger" to strip accessories out of an electronics search.

## `deal_type` (type: `string`):

Filter to Target's own deal categories. Target does not offer every deal filter for every keyword — when the chosen one is unavailable the run falls back to the minimum discount setting and says so in the log.

## `min_discount_percent` (type: `integer`):

Only save products marked down by at least this much, calculated from the current and regular price. Works for every keyword, including those with no deal filter. Leave at 0 to keep everything.

## `rank_by_discount` (type: `boolean`):

Scan every allowed page first, then save only the deepest markdowns. Slower, because it reads the full page budget before writing, but it surfaces the best deals rather than the first ones found.

## `track_changes` (type: `boolean`):

⚠️ Leave this OFF for normal searches. When on, the run compares against the previous run of the same search and saves ONLY price drops, new arrivals and items back in stock — so a second run minutes later correctly returns zero products. That is the feature working, not a failure. Built for scheduled daily runs; the first run saves a baseline and returns everything.

## `include_unchanged` (type: `boolean`):

Only applies when the setting above is on. Keeps products whose price and availability held steady, turning a change feed back into a full listing. Useful if you want every product but still want the change\_type labels.

## `sort_by` (type: `string`):

Order of the search results. "relevance" and "newest" are the primary options; the remaining values mirror the sort choices offered on target.com.

## `results_wanted` (type: `integer`):

Maximum number of products to save to the dataset. Target serves at most 1,200 products per search regardless of how many matches it reports, so very large values return everything available rather than failing.

## `max_pages` (type: `integer`):

Safety cap on how many listing pages are requested. The run stops at whichever limit is reached first — this one or the number of results.

## `include_sponsored` (type: `boolean`):

Include sponsored placements in the dataset. Turn this off to collect organic search results only.

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

Optional Apify Proxy settings. Target tolerates datacenter traffic in most cases; enable residential proxies if a run starts returning empty pages.

## `storeId` (type: `string`):

Store used for pricing and pickup context. Availability fields are only populated when a valid store is supplied. Leave the default unless you need a specific store's data.

## `zipCode` (type: `string`):

ZIP code used for shipping and scheduled delivery estimates.

## Actor input object example

```json
{
  "keyword": "womens tops",
  "item_type": "cell phones",
  "exclude_item_type": "case, charger",
  "deal_type": "any",
  "min_discount_percent": 0,
  "rank_by_discount": false,
  "track_changes": false,
  "include_unchanged": false,
  "sort_by": "relevance",
  "results_wanted": 20,
  "max_pages": 10,
  "include_sponsored": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "storeId": "1771",
  "zipCode": "10001"
}
```

# Actor output Schema

## `products` (type: `string`):

Every collected product — price, discount, ratings, availability, images and a direct Target link.

## `productsCsv` (type: `string`):

The same products as a spreadsheet-ready CSV.

## `datasetInConsole` (type: `string`):

Open the dataset in the Console to sort and filter by discount.

# 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 = {
    "keyword": "womens tops"
};

// Run the Actor and wait for it to finish
const run = await client.actor("famous_iron/target-deal-tracker").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 = { "keyword": "womens tops" }

# Run the Actor and wait for it to finish
run = client.actor("famous_iron/target-deal-tracker").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 '{
  "keyword": "womens tops"
}' |
apify call famous_iron/target-deal-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,famous_iron/target-deal-tracker"
        }
    }
}
```

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/jX9u8joW0tZjmlSxx/builds/n5gsX11cmF0y4230w/openapi.json
