# Shrinkflation Detector for Grocery Price Data (`ultimatemc/shrinkflation-detector`) Actor

Find shrinkflation in grocery and retail product data: smaller packs at the same or higher price. Compare two runs of a supermarket scraper or your own snapshots and get size before and after, price, price per 100 g / ml / item and the hidden price rise per product. No AI.

- **URL**: https://apify.com/ultimatemc/shrinkflation-detector.md
- **Developed by:** [Ultimate Foresight Inc](https://apify.com/ultimatemc) (community)
- **Categories:** E-commerce, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

**Shrinkflation Detector** finds products that got **smaller at the same (or higher) price** in grocery and retail product data. Give it two runs of a supermarket scraper, or your own dated product rows, and it returns the **size before and after**, price, **price per 100 g / 100 ml / item**, and the **hidden price increase** for every pack-size change. Click **Start** with the prefilled example to see it work in a few seconds.

> Results are calculated from the data you supply. Pack sizes are parsed from text and can be wrong, and a smaller pack doesn't prove intent, so check the product before publishing a claim.

### What does Shrinkflation Detector do?

- ✅ Matches the same product across snapshots by product ID (id, sku, product_id, stockcode, EAN/GTIN, URL), and **by name when the barcode changed with the new size**
- ✅ Parses pack sizes from a size field or the product name: `200g`, `1.5 L`, `75cl`, `18 oz`, `1 lb 4 oz`, `12 x 12 fl oz`, `6x1,5 L`, `4 pk 250 ml each`, `42 ct`, `12 Mega Rolls`, `100 tablets`, `pack of 6`
- ✅ Converts everything to grams, millilitres or items, so `18 oz` and `510 g` count as the same size
- ✅ Ignores numbers that aren't pack sizes: `20g protein`, `160mg caffeine`, `1000mg` strength, `128GB`, `5G`, `Size 10`, `Ages 3+`, `2 for $5`
- ✅ Uses the **regular price** when the data also has a promo price (regularPrice, original_price, priceNormal, wasPrice ...)
- ✅ Labels each change: `shrinkflation`, `shrinkflation_partial_price_cut` (price dropped less than the size), `size_decrease_with_matching_price_cut`, `size_increase`, `unit_price_increase`, `price_increase`, `price_decrease`
- ✅ Returns sizeBefore, sizeAfter, priceBefore, priceAfter, unitPriceBefore, unitPriceAfter, sizeChangePct, priceChangePct, unitPriceChangePct, hiddenPriceIncreasePct, severity, matchedBy, notes and a timestamp per product
- ✅ Rule-based and deterministic: no AI, no scraping, no external APIs

### Who is it for?

- **Journalists and consumer groups** tracking shrinkflation at supermarkets
- **Price-intelligence and retail analysts** who already scrape grocery prices and want size-adjusted inflation
- **CPG brands and category managers** watching competitors' pack-size moves
- **Researchers** measuring hidden price increases across thousands of products

### How to detect shrinkflation

1. Click **Start** with the prefilled example (made-up products) to see the output.
2. Replace **Product snapshots** with your rows: `id`, `name`, `size` (optional if the name has it), `price`, `date`. Or pick an **Older dataset** and a **Newer dataset** from two runs of the same grocery scraper (Coles, Woolworths, ALDI, Lidl, Tesco, Walmart and similar).
3. Choose **What to report**: shrinkflation only, all size changes (default), size and price changes, or everything.
4. Run it, then download the table as CSV, Excel or JSON, or schedule it after each scraper run.

### Input example

The prefill (example data, not real products):

```json
{
  "products": [
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 200g",
      "price": 3.0,
      "date": "2026-01-15"
    },
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 180g",
      "price": 3.0,
      "date": "2026-04-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "12 x 12 fl oz",
      "price": 7.99,
      "date": "2026-01-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "10 x 12 fl oz",
      "price": 7.49,
      "date": "2026-04-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250g",
      "price": 3.5,
      "date": "2026-01-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250 g",
      "price": 3.5,
      "date": "2026-04-15"
    }
  ]
}
```

Comparing two scraper runs:

```json
{
  "beforeDatasetId": "YOUR_OLDER_DATASET_ID",
  "afterDatasetId": "YOUR_NEWER_DATASET_ID",
  "report": "shrinkflation"
}
```

If your data uses unusual field names, set **Product ID field**, **Size field**, **Price field** or **Date field**. For a size field that's a bare number (e.g. `500`), set **Unit for numeric sizes** (`g`, `ml`, `oz`), or include a unit field such as `unitMeasure`.

### Output example

Real output from running the prefill on 27 October 2026 (the `before` and `after` detail objects are trimmed here). Butter didn't change, so with the default setting it isn't saved:

```json
[
  {
    "productKey": "example-1",
    "name": "Example Chocolate Bar 180g",
    "eventType": "shrinkflation",
    "severity": "high",
    "sizeBefore": "200 g",
    "sizeAfter": "180 g",
    "priceBefore": 3,
    "priceAfter": 3,
    "unitPriceBefore": 1.5,
    "unitPriceAfter": 1.6667,
    "unitPriceBasis": "per 100 g",
    "sizeChangePct": -10,
    "priceChangePct": 0,
    "unitPriceChangePct": 11.11,
    "hiddenPriceIncreasePct": 11.11,
    "snapshotsSeen": 2,
    "matchedBy": "id",
    "notes": [],
    "checkedAt": "2026-10-27T18:20:06+00:00",
    "disclaimer": "Detected from the data you supplied: pack sizes and prices are parsed from text and may be wrong. A size change on its own does not prove intent. Check the product before publishing a claim."
  },
  {
    "productKey": "example-2",
    "name": "Example Cola",
    "eventType": "shrinkflation_partial_price_cut",
    "severity": "medium",
    "sizeBefore": "12 x 12 fl oz (4258.6 ml)",
    "sizeAfter": "10 x 12 fl oz (3548.8 ml)",
    "priceBefore": 7.99,
    "priceAfter": 7.49,
    "unitPriceBefore": 0.1876,
    "unitPriceAfter": 0.2111,
    "unitPriceBasis": "per 100 ml",
    "sizeChangePct": -16.67,
    "priceChangePct": -6.26,
    "unitPriceChangePct": 12.49,
    "hiddenPriceIncreasePct": 12.49,
    "snapshotsSeen": 2,
    "matchedBy": "id",
    "notes": [
      "Pack count changed from 12 to 10."
    ],
    "checkedAt": "2026-10-27T18:20:06+00:00",
    "disclaimer": "Detected from the data you supplied: pack sizes and prices are parsed from text and may be wrong. A size change on its own does not prove intent. Check the product before publishing a claim."
  }
]
```

**hiddenPriceIncreasePct** is how much more you now pay per 100 g, 100 ml or item.

### How it decides

- Size change = (new size − old size) / old size, after converting to g, ml or items. Changes within **1%** are treated as rounding (e.g. 32 oz vs 2 lb).
- **shrinkflation**: size down by more than 1% and price down by less than 0.5% (same or higher).
- **shrinkflation_partial_price_cut**: size down, price down too, but price per unit still up by at least the **Minimum unit-price rise** (default 2%).
- **size_decrease_with_matching_price_cut**: price fell as much as the size, so the unit price didn't rise.
- Severity: high = shrinkflation with a unit-price rise of 5% or more; medium = smaller shrinkflation, a partial price cut, or a bigger pack with a higher unit price; low = other size changes and price increases; info = price decreases and size cuts matched by a price cut.
- Sizes in different measures (e.g. `80 wipes` vs `500 g`) aren't compared; the row says so in `notes`.
- With 3+ snapshots, the latest size change is reported (or every step with **Report every change step**).

### How much does it cost?

Pay per result: **$0.002 per product row saved**, plus a **$0.00005** start fee and small platform usage paid by you (the prefill run used about $0.0001). Only changed products are saved by default, so unchanged products cost nothing. Examples: 100 flagged products ≈ $0.20; 1,000 ≈ $2.00, plus platform usage. You can cap spending with the maximum cost per run setting.

### Use it through the API, integrations or AI agents

- API (run and get results in one call): `https://api.apify.com/v2/acts/ultimatemc~shrinkflation-detector/run-sync-get-dataset-items`
- MCP for AI agents: `https://mcp.apify.com?tools=ultimatemc/shrinkflation-detector`
- Chain it after a grocery scraper with an Apify **webhook** or **schedule**: pass the previous and the latest dataset IDs, and send the results to Google Sheets, Slack or Make with Apify **integrations**.

### FAQ

#### Does it scrape supermarkets?

No. It only compares data you give it: your own rows or datasets from a scraper you ran.

#### Is it AI?

No. Sizes and prices are parsed with fixed rules, so the same input always gives the same output.

#### What if the barcode changed with the new size?

With **Match by name when the ID changes** on (default), a product seen only in the older data is joined to one seen only in the newer data when their names match once the size is removed, at the same retailer. `matchedBy` then says `name (id changed)`.

#### Does a flag prove shrinkflation?

No. It shows the size and price in your data changed. Check the product page or pack before publishing.

#### Which currencies work?

Any. Prices like `$3.99`, `3,99 €`, `£1.50` and `99c` are read; rows with different currencies aren't compared.

### Limitations

- Pack sizes are read from text; unusual formats may be missed (the row then has no size and isn't flagged).
- Weight `oz` and `fl oz` are different measures; a product listed as `16 oz` then `16 fl oz` isn't compared.
- It doesn't detect reformulation (cheaper ingredients) or fewer sheets per roll unless the size text says so.
- Promo prices are only separated when the data has a regular-price field.
- Name matching needs the same retailer and a near-identical name; renamed products won't be joined.

### Other tools by Ultimate Foresight

- [Ad Copy Policy Checker for Meta, Google & TikTok](https://apify.com/ultimatemc/ad-copy-policy-checker): checks ad text against Facebook, Instagram, Google Ads and TikTok ad policies before you submit.
- [H-1B Visa Sponsor Checker & Score for Job Listings](https://apify.com/ultimatemc/h1b-visa-sponsor-score): adds Department of Labor H-1B sponsorship history and a 0-100 score to company names or job listings.
- [Chain vs Independent Labeler for Google Maps Leads](https://apify.com/ultimatemc/chain-vs-independent-labeler): labels local businesses as chain, franchise or independent.
- [YouTube Monetization Checker for Scripts & Titles](https://apify.com/ultimatemc/youtube-script-monetization-checker): pre-checks titles, descriptions and scripts for wording that leads to limited or no ads.
- [Etsy & eBay Listing Policy & Banned Item Checker](https://apify.com/ultimatemc/etsy-ebay-listing-policy-checker): pre-checks marketplace listings for prohibited items, counterfeit wording and off-platform contact.
- [Job Scam Detector & Trust Score for Job Postings](https://apify.com/ultimatemc/job-posting-trust-score): scores job postings 0-100 for scam and ghost-job signals.
- [SAM.gov Amendment & Opportunity Change Tracker](https://apify.com/ultimatemc/sam-gov-opportunity-change-detector): shows what changed between versions of a SAM.gov notice: deadlines, set-asides, NAICS and attachments.
- [Product Recall Checker for Brands, UPCs & Products](https://apify.com/ultimatemc/product-recall-matcher): matches your brands, products, UPCs or model numbers against CPSC, FDA and NHTSA recalls.
- [App Store & Google Play Listing Policy Checker](https://apify.com/ultimatemc/app-store-listing-policy-checker): pre-checks app names, subtitles and descriptions against Apple and Google Play metadata rules.
- [Company Name Normalizer & Deduplicator for CRM](https://apify.com/ultimatemc/company-name-canonicalizer): cleans company names (Inc, LLC, d/b/a, aliases) and groups duplicates in CRM, lead or vendor lists.
- [Green Claims Checker: EU Greenwashing Ban & FTC](https://apify.com/ultimatemc/green-claims-checker): flags risky eco-friendly, carbon neutral and recyclable wording under EU, FTC and UK CMA rules.
- [Influencer #ad Disclosure Checker: FTC & ASA](https://apify.com/ultimatemc/influencer-ad-disclosure-checker): flags influencer posts with missing or unclear #ad labels under FTC, ASA/CAP and CMA rules.
- [Job Title to SOC Code Mapper with O\*NET Data](https://apify.com/ultimatemc/job-title-soc-code-mapper): maps job titles to SOC and O\*NET-SOC codes in bulk, with seniority and tech skills found in the posting.
- [FCC Covered List & Section 889 Bulk Screener](https://apify.com/ultimatemc/fcc-covered-list-screener): screens FCC IDs and brand names against the public FCC Covered List, with sources and timestamps (screening aid only).
- [Fair Housing Listing Checker for Real Estate Ads](https://apify.com/ultimatemc/fair-housing-listing-checker): flags rental and sale listing wording that may raise Fair Housing Act issues, with HUD sources and rewrite tips (screening aid only).
- [Job Ad Discrimination Checker for Job Posts (US)](https://apify.com/ultimatemc/job-ad-discrimination-checker): flags age, sex, national origin, citizenship and other discriminatory wording in job posts, with EEOC and DOJ sources (screening aid only).
- [Amazon Listing Policy Checker for Titles & Bullets](https://apify.com/ultimatemc/amazon-listing-policy-checker): flags pesticide, FDA and disease claims and Amazon title and bullet rule breaks in bulk, with policy links and fixes.
- [Walmart Listing Policy Checker for Titles & Copy](https://apify.com/ultimatemc/walmart-listing-policy-checker): flags promotional phrases, retailer names, URLs, long titles and pesticide or FDA claims in Walmart Marketplace listings, with policy links and fixes.
- [TikTok Shop Listing Policy Checker for Products](https://apify.com/ultimatemc/tiktok-shop-listing-policy-checker): flags off-platform links, dupe wording, weight-loss, disease and FDA claims and title rule breaks in TikTok Shop listings.
- [Supplement & Cosmetic Claims Checker: FDA & FTC](https://apify.com/ultimatemc/supplement-cosmetic-claims-checker): flags disease, drug and 'FDA approved' claims and missing supplement disclaimers in supplement and beauty product copy, with FDA and FTC sources (screening aid only).
- [Rental Listing Scam Checker for Craigslist & FB](https://apify.com/ultimatemc/rental-listing-scam-checker): scores rental listings 0-100 for FTC-listed scam signs like wire or gift card payment, deposit before viewing and rent far below similar listings.
- [GTIN, UPC & EAN Barcode Validator (Check Digit)](https://apify.com/ultimatemc/gtin-barcode-validator): checks UPC, EAN, GTIN-14 and ISBN codes for wrong check digits, lost leading zeros, scientific notation, restricted prefixes and duplicates before a feed upload.
- [Fake Review Checker: Incentivized & Duplicates](https://apify.com/ultimatemc/review-integrity-checker): screens scraped reviews for incentivized or insider wording, copied text, rating bursts and rating/text mismatches named in the FTC 2024 fake-review rule.
- [Facebook Marketplace Listing Policy Checker](https://apify.com/ultimatemc/facebook-marketplace-listing-policy-checker): flags Marketplace listings that may break Meta's Commerce Policies (weapons, vapes, Rx, animals, gift cards, services, counterfeits and more), with policy links.
- [Fake Discount Checker: EU 30-Day Prior Price](https://apify.com/ultimatemc/discount-claim-checker): checks 'was' and strikethrough prices against your own price history for 30-day prior-price, raise-then-discount and wrong-badge issues.
- [SMS Marketing Message Checker: STOP & 10DLC](https://apify.com/ultimatemc/sms-marketing-message-checker): pre-checks SMS marketing texts for segment count, STOP opt-out wording, URL shorteners, SHAFT content and quiet hours.
- [Hidden Fee Checker: Hotel, Rental & Ticket Prices](https://apify.com/ultimatemc/hidden-fee-price-checker): flags headline prices that leave out mandatory resort, service or booking fees under the FTC junk fees rule (16 CFR 464), with sources per finding.
- [EU GPSR Listing Checker for Amazon, eBay & Shops](https://apify.com/ultimatemc/gpsr-listing-checker): checks listings for the EU GPSR Article 19 online-sale details: manufacturer, EU responsible person, product identifier, picture and warnings.
- [Food Allergen Label Checker: US, EU & AU](https://apify.com/ultimatemc/food-allergen-label-checker): compares ingredient lists with the 'Contains' statement for US 9, EU/UK 14 and Australian PEAL allergens and flags gaps and conflicting free-from claims.
- [Toy Choking Hazard Warning Checker (CPSC)](https://apify.com/ultimatemc/toy-choking-warning-checker): flags toy listings missing the CPSC choking-hazard warnings for small parts, balloons, small balls and marbles, with age-grade checks.
- [Textile Fiber Label Checker: Bamboo & Origin](https://apify.com/ultimatemc/textile-fiber-label-checker): flags 'bamboo' claims that should say rayon, fiber percentages that don't add up, mismatched silk or cashmere titles and missing Made in USA/Imported.
- [Prop 65 Warning Checker for Product Listings](https://apify.com/ultimatemc/prop65-warning-checker): flags Prop 65 safe-harbor warnings missing 'WARNING', the P65Warnings.ca.gov link or a chemical name, old short forms, and listed chemicals mentioned with no warning.
- [Unit Price Checker for Grocery & Retail Listings](https://apify.com/ultimatemc/unit-price-checker): parses pack sizes, recomputes the price per kg, litre or item, and flags missing or wrong unit prices in grocery and retail data.
- [Made in USA Claim Checker for Product Listings](https://apify.com/ultimatemc/made-in-usa-claim-checker): flags unqualified 'Made in USA' claims next to imported or foreign-origin details under the FTC rule (16 CFR 323), with sources per finding.
- [Subscription Auto-Renewal Disclosure Checker](https://apify.com/ultimatemc/auto-renewal-disclosure-checker): checks subscription and free-trial offer text for missing renewal, price, billing period and cancellation disclosures under California law and FTC ROSCA.
- [Email CAN-SPAM Checker & Unsubscribe Header Test](https://apify.com/ultimatemc/email-can-spam-checker): pre-checks marketing emails for missing unsubscribe links or postal address, misleading subjects and Google/Yahoo one-click unsubscribe headers.

Missed a size change or found a false alarm? Open an issue on the **Issues** tab with the two rows, and we'll review the rule.

# Actor input Schema

## `products` (type: `array`):

One row per product per date, with "id", "name", "size" (optional if the name contains it, e.g. "200g" or "12 x 12 fl oz"), "price" and "date". The prefill is made-up example data showing one shrink; replace it with your own. To compare two runs of a grocery scraper, use the dataset fields below instead.

## `beforeDatasetId` (type: `string`):

Dataset from an earlier run of a grocery or e-commerce scraper (Coles, Woolworths, ALDI, Lidl, Tesco, Walmart and others). Product ID, name, size and regular price fields are detected automatically.

## `afterDatasetId` (type: `string`):

Dataset from a later run of the same scraper. Products are matched by ID, then by name without the size if the ID changed.

## `report` (type: `string`):

Only matching rows are saved, and you pay per saved row.

## `matchByName` (type: `boolean`):

Brands often give a smaller pack a new barcode. When on, a product seen only in the older snapshot is joined to one seen only in the newer snapshot if their names match once the size is removed (same retailer).

## `reportEveryStep` (type: `boolean`):

With 3 or more snapshots, report each step separately instead of only the latest size change (or first-to-last).

## `keyField` (type: `string`):

Field that identifies a product across snapshots, e.g. "sku" or "stockcode". Leave empty to detect it (id, sku, productId, product_id, ean, gtin, url ...).

## `nameField` (type: `string`):

Leave empty to detect (name, title, productName ...).

## `sizeField` (type: `string`):

Leave empty to detect (size, packSize, packaging, unitSize, netWeight ...). If no size field has a value, the size is read from the name.

## `sizeUnit` (type: `string`):

Only if the size field is a bare number, e.g. "g", "ml" or "oz".

## `priceField` (type: `string`):

Leave empty to use the regular (non-promotional) price when the data has one (regularPrice, original_price, priceNormal, wasPrice ...), else price.

## `dateField` (type: `string`):

Leave empty to detect (date, scrapedAt, scraped_at, timestamp ...).

## `minUnitPriceRisePct` (type: `integer`):

For a smaller pack with a lower price, flag it only if the price per 100 g / 100 ml / item rose at least this much.

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

Maximum rows read from each source.

## Actor input object example

```json
{
  "products": [
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 200g",
      "price": 3,
      "date": "2026-01-15"
    },
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 180g",
      "price": 3,
      "date": "2026-04-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "12 x 12 fl oz",
      "price": 7.99,
      "date": "2026-01-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "10 x 12 fl oz",
      "price": 7.49,
      "date": "2026-04-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250g",
      "price": 3.5,
      "date": "2026-01-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250 g",
      "price": 3.5,
      "date": "2026-04-15"
    }
  ],
  "report": "sizeChanges",
  "matchByName": true,
  "reportEveryStep": false,
  "minUnitPriceRisePct": 2,
  "maxItems": 50000
}
```

# Actor output Schema

## `results` (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 = {
    "products": [
        {
            "id": "example-1",
            "name": "Example Chocolate Bar 200g",
            "price": 3,
            "date": "2026-01-15"
        },
        {
            "id": "example-1",
            "name": "Example Chocolate Bar 180g",
            "price": 3,
            "date": "2026-04-15"
        },
        {
            "id": "example-2",
            "name": "Example Cola",
            "size": "12 x 12 fl oz",
            "price": 7.99,
            "date": "2026-01-15"
        },
        {
            "id": "example-2",
            "name": "Example Cola",
            "size": "10 x 12 fl oz",
            "price": 7.49,
            "date": "2026-04-15"
        },
        {
            "id": "example-3",
            "name": "Example Butter 250g",
            "price": 3.5,
            "date": "2026-01-15"
        },
        {
            "id": "example-3",
            "name": "Example Butter 250 g",
            "price": 3.5,
            "date": "2026-04-15"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ultimatemc/shrinkflation-detector").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 = { "products": [
        {
            "id": "example-1",
            "name": "Example Chocolate Bar 200g",
            "price": 3,
            "date": "2026-01-15",
        },
        {
            "id": "example-1",
            "name": "Example Chocolate Bar 180g",
            "price": 3,
            "date": "2026-04-15",
        },
        {
            "id": "example-2",
            "name": "Example Cola",
            "size": "12 x 12 fl oz",
            "price": 7.99,
            "date": "2026-01-15",
        },
        {
            "id": "example-2",
            "name": "Example Cola",
            "size": "10 x 12 fl oz",
            "price": 7.49,
            "date": "2026-04-15",
        },
        {
            "id": "example-3",
            "name": "Example Butter 250g",
            "price": 3.5,
            "date": "2026-01-15",
        },
        {
            "id": "example-3",
            "name": "Example Butter 250 g",
            "price": 3.5,
            "date": "2026-04-15",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ultimatemc/shrinkflation-detector").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 '{
  "products": [
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 200g",
      "price": 3,
      "date": "2026-01-15"
    },
    {
      "id": "example-1",
      "name": "Example Chocolate Bar 180g",
      "price": 3,
      "date": "2026-04-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "12 x 12 fl oz",
      "price": 7.99,
      "date": "2026-01-15"
    },
    {
      "id": "example-2",
      "name": "Example Cola",
      "size": "10 x 12 fl oz",
      "price": 7.49,
      "date": "2026-04-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250g",
      "price": 3.5,
      "date": "2026-01-15"
    },
    {
      "id": "example-3",
      "name": "Example Butter 250 g",
      "price": 3.5,
      "date": "2026-04-15"
    }
  ]
}' |
apify call ultimatemc/shrinkflation-detector --silent --output-dataset

```

## MCP server setup

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

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/CTkAXnPL14NJBOIO6/builds/bEkgMaBKSsZFyqx9s/openapi.json
