IKEA Scraper - Products, Prices, Reviews & Availability avatar

IKEA Scraper - Products, Prices, Reviews & Availability

Pricing

from $1.00 / 1,000 product results

Go to Apify Store
IKEA Scraper - Products, Prices, Reviews & Availability

IKEA Scraper - Products, Prices, Reviews & Availability

Scrape IKEA products across 50+ markets. Extract names, prices, currencies, ratings, full reviews, colours, dimensions, images, categories, variants, badges and store availability. Supports search, category, item-number and URL inputs with filters and sorting.

Pricing

from $1.00 / 1,000 product results

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

6

Total users

3

Monthly active users

17 hours ago

Last modified

Share

IKEA Scraper: Products, Prices, Availability and Reviews

IKEA Scraper turns any of IKEA's country storefronts into structured product data. Search by keyword, list a category, look up exact item numbers, or paste product, category, search or room/department links, and get back one flat record per product with pricing, ratings, colours, measurements, images, category path, variants and markdown status. Turn on detail enrichment for the full marketing description and individual customer reviews, and turn on availability for national and per-store stock, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

Why This Scraper?

  • Four ways to find products. Search by keyword, list a category, look up exact item numbers, or paste product, category, search and room/department links.
  • 50+ country storefronts. One Market and language field picks the country, currency and product range; a pasted link in URL mode carries its own market instead.
  • Specials and pricing built in. Every product already carries its markdown info, was-price, savings amount, discount percent and IKEA's own specials label, at no extra request cost.
  • Room and department links just work. A collection page like a living room hub is expanded into the real categories it lists, and each one is scraped, so you don't have to hand-build category links.
  • Detail enrichment on demand. Attach the full description and individual customer reviews (author, date, title, text, rating) per product, and pay only for the products it actually lands on.
  • Availability on demand. Attach national and per-store stock, click and collect and home delivery status per product.
  • Built for monitoring. Incremental mode returns only new and changed products on recurring runs, and a fully blocked search, category, or listing/room link fails loudly instead of returning an empty dataset. A blocked item-number lookup or a blocked pasted product link is not detected this way; see the FAQ below.

Use Cases

  • Price and markdown tracking: monitor a category or a list of item numbers for price drops, IKEA Family price markdowns and last-chance clearance.
  • Catalogue and range building: pull a full category or room sweep into your own product database or marketplace feed.
  • Review and ratings research: collect individual review text and ratings for sentiment analysis or competitor benchmarking.
  • Stock and fulfilment checks: confirm national and per-store availability, click and collect and home delivery status before promoting a product.
  • Cross-market comparison: compare price, currency and range differences for the same item numbers across several country storefronts.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
kind"product"
id / itemNo"00099999"
name / typeName"SAMPLE" / "Shelving unit"
url"https://www.ikea.com/us/en/p/sample-shelving-unit-white-00099999/"
price / currency / priceFormatted148.0 / "USD" / "$148.00"
onSale / isOnSpecialtrue / true
wasPrice / discountPercent / specialsLabel179.0 / 17.3 / "IKEA Family price" (null when the product carries no markdown)
ratingValue / ratingCount4.4 / 812
color / colors"slate gray" / [{ "name": "slate gray", "id": "90512", "hex": "5b6470" }]
width / depth / height / measurementUnit27.5 / 9.75 / 70.25 / "in"
material"Particleboard, foil, plastic edging"
categoryPath["Storage & organization", "Shelving units"]
ancestorCategories[{ "name": "Storage & organization", "key": "st001", "url": "https://www.ikea.com/us/en/cat/storage-organization-st001/" }], outermost first. key is IKEA's category id (usable in Category ids mode); the link opens that category.
badge / isBestseller"Best seller" / true
lastChance / onlineSellablefalse / true
mainImage / mainImageAlt / imagesproduct photo URL(s) on ikea.com, and the photo's alt text
contextualImageUrl / contextualImageAltthe in-room photo and its alt text (null when IKEA shows none)
tag / tagText / featuresIKEA's listing tag and its label, e.g. "FAMILY_PRICE" / "IKEA Family price", and the feature list when the listing carries one (null when none)
numberOfVariants / variants3 / sibling colour or finish options, each with its own price and image
market / language"us" / "en"
descriptionfull marketing copy (when detail enrichment is on)
reviewsCollected / reviews1 / each review's author, date, title, body and rating (when detail enrichment is on). Switch the dataset's Reviews view (next to Overview) to see one row per review instead of a nested array.
availabilitynational and per-store stock, click and collect, home delivery (when availability is on)
changeType / changedFields"UPDATED" / ["price"] (incremental mode only)

There is only one dataset record kind: a product. Reviews and availability are nested arrays/objects under it rather than separate rows, and firstSeenAt / lastSeenAt are added alongside changeType when incremental mode is on.

Each search or category walked in a run also leaves one AVAILABLE_FILTERS record in the run's key-value store (linked from the run's Output tab). It is not a dataset row and is never billed. It holds one entry per walked search or category: the scope (type, value, market, sort and the facets that were applied), the walked category (name, key, link, picture), totalAvailable (how many products IKEA lists there) and availableFilters, the listing's own filter panel as flat rows of facet, facetParam, valueId, title, count and acceptedByFiltersInput (true when that facet can be passed in the Facet filters input). It is read from the page the walk already fetched, so it costs no extra request.

How to Use

  1. Pick a mode: search (keywords), productIds (exact item numbers), url (paste product, category, search or room/department links, or a bare letter-prefixed category id), or category (legacy category-only mode, superseded by url).
  2. Choose your Market and language (ignored in URL mode, since each link carries its own market).
  3. Fill in the fields for that mode, apply any filters, and switch on detail enrichment or availability if you need them.
  4. In url mode, leaving URLs untouched scrapes the built-in sample: eleven links that each mean something different (a product in two markets, a numeric and a letter-prefixed category, a filtered and sorted category, both search link forms with and without a sort, a room, a department hub, a bare category id, and an offers hub that is logged and skipped). Replace them with your own links for a real run.
  5. Set Max products to control run size and cost, then click Start.

Search for a category of products:

{
"mode": "search",
"market": "us/en",
"searchTerms": ["bookcase"],
"sortBy": "PRICE_LOW_TO_HIGH",
"maxItems": 50,
"fetchDetails": true,
"maxReviews": 10,
"includeAvailability": true
}

List a category, no detail enrichment (cheaper, faster):

{
"mode": "category",
"market": "us/en",
"categories": ["https://www.ikea.com/us/en/cat/bookcases-10382/"],
"maxItems": 100,
"fetchDetails": false
}

Look up exact item numbers:

{
"mode": "productIds",
"market": "us/en",
"productIds": ["20522046"],
"fetchDetails": true,
"includeAvailability": true
}

Monitor a search link for changes on a schedule:

{
"mode": "url",
"urls": ["https://www.ikea.com/us/en/search/products/?q=bookcase"],
"incrementalMode": true,
"emitExpired": true,
"maxItems": 100
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/ikea-scraper").call(run_input={
"mode": "search", "market": "us/en", "searchTerms": ["bookcase"],
})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
print(product["name"], product["price"], product["currency"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/ikea-scraper').call({
mode: 'search', market: 'us/en', searchTerms: ['bookcase'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Markets, and mixing them in one run

Search, category and productIds modes all use one Market and language value for the whole run. In URL mode, each pasted link is read on its own: a link whose path starts with a valid two-letter country and two-letter language (for example us/en or de/de) uses that market instead of the field above, so one URL-mode run can genuinely mix several country storefronts. Keep in mind that filters like Min price and Max price compare against each record's own local currency number, so the same numeric threshold means a different real amount in a run that mixes, say, US dollars and Japanese yen.

A collection page such as a "rooms" or department hub is not itself a category, so the actor reads the category list that page publishes and scrapes each one. The run log names every category it walked, so you can see exactly what was covered. Products that a room page only features without listing a category for it are not included, so this is a broad sweep of the room rather than a pixel-perfect copy of the page. A page that publishes no category at all (an offers, new-arrivals or campaigns hub, or the bare room index) is reported in the log and skipped instead of being guessed as a keyword search.

A search or category link pasted in URL mode keeps the filters= and sort= it carries, for example .../cat/bookcases-10382/?filters=f-colors%3A10156&sort=PRICE_LOW_TO_HIGH. Facets that match a Facet filters key (colors, materials, type, price, category) and any supported sort apply to that link only. When the same facet or the sort is also set in the input, the link wins for that link; facets the link does not mention still come from the input, and a link with no filters or sort simply uses the input's. Facets IKEA offers beyond those five keys are not applied and are named in the log. A page number in a link (?page=2) is not used: every link is walked from its first page and Max products sets how far.

Filters, sort and specials scope

The optional Facet filters object (filters) takes the site's own facet ids for colors, materials, type, price (e.g. PRICE_0_10000) and category, comma-separated, in search and category listings only; unknown keys are ignored. Min price, Max price, Min rating, In stock only, Contains keyword and the Specials facet all apply in search mode, category mode, and to a search or category link pasted in URL mode, exactly the same way. They are not applied to Product item numbers mode, or to a single product link pasted in URL mode: those always return that exact item, unfiltered.

Resume and incremental mode

  • Resume (resumeFromRunId) skips product ids already collected by a previous run or dataset. For a fixed list of item numbers or pasted URLs, each id resolves on its own, so this always works cleanly. For a repeated category or search walk, the walk pages past the already-collected products as well as collecting the new ones you asked for, up to the site's own 400-product listing ceiling. Products ranked beyond that ceiling are not reachable by any run; narrow the search or change Sort by to reach them.
  • Incremental mode (incrementalMode) is for running the same search, category, item-number list or URL set again and again (daily, weekly) and getting only the differences. Each product is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED or EXPIRED. For search, category and listing/room links, a product is only ever marked absent, and can only ever come back as REAPPEARED later, after a run that had emitExpired on and completed a full, uncapped, non-Resume scan with no page refused or unreadable. The same holds for productIds mode and pasted single product links: a lookup that was refused or never answered counts as an unreadable scan, so those products are never marked EXPIRED (nor billed as such) on that run. stateKey names or shares one monitoring campaign's stored state; leave it empty to let the actor derive one from the market, mode and filters automatically. If another field in your setup turns out to be noisy (changes between runs without the product itself really changing; IKEA's isBreathTaking hot-deal flag or priceValidFrom/priceValidTo are candidates), list it in ignoreFieldsForChanges to exclude it from triggering UPDATED. Fields added to the record in later versions (such as ancestorCategories or contextualImageUrl) never count as a change on their own: a product saved by an earlier version stays UNCHANGED when only those fields are new, and its saved copy is brought up to date once. EXPIRED rows count toward Max products: once the run's remaining budget is used, the rest stay tracked as present and are returned on the next complete run (Max products 0 means no cap). A saved url-mode campaign whose links carry filters= or sort= starts a fresh baseline once, because those links are now scraped filtered and sorted as the page shows them. With incremental mode off, output is exactly one row per product, with no changeType field at all.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each product, not the full JSON. Each product becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify โ†’ Settings โ†’ Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where products should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch, category, productIds, or url.
marketstringus/enThe IKEA market and language. Ignored per link in URL mode.
searchTermsarrayprefill ["bookcase"]Keywords to search (search mode).
sortBystringRELEVANCEOrder of results in a listing (search, category, or a listing link in URL mode). Includes Name Z-A and Customer rating.
filtersobject{}Facet ids per key: colors, materials, type, price, category.
categoriesarrayprefill sample category linkCategory listing URLs or bare ids (category mode, legacy; url mode now covers this too).
productIdsarrayprefill sample item numberExact IKEA item numbers (productIds mode).
urlsarrayone example of every supported link shape (11 links)Product, category or search links from ikea.com, or a bare letter-prefixed category id (url mode). A search or category link keeps its own filters and sort.
minPriceinteger(none)Only keep products at or above this price.
maxPriceinteger(none)Only keep products at or below this price.
minRatinginteger(none)Only keep products with an average rating at or above this value (1-5).
inStockOnlybooleanfalseKeep only products currently sellable online.
containsKeywordstring(none)Only keep products whose name, type or description contains this text.
specialsCategorystringnoneNarrow a listing to family_price (IKEA Family price) or last_chance.
fetchDetailsbooleantrueAttach the full description and individual customer reviews.
maxReviewsinteger10Cap on individual reviews captured per product (0 disables review text), at most 100000. The default stays at 10 so existing incremental campaigns keep their saved state. Reviews are covered by the detail-enrichment charge, so the number you set never changes the price. The actual limit is however many reviews IKEA includes on the product page.
includeAvailabilitybooleanfalseAttach national and per-store stock per product.
maxItemsinteger20Total products to return across all inputs (the run cap).
maxPagesinteger0Optional safety cap on result pages walked per search or category (0 = no limit).
proxyobject{ "useApifyProxy": true }Connection settings.
mcpConnectorsarray(none)Optional: send a summary of each product to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which products are created.
maxNotifyListingsinteger50Cap on products written to each connector per run.
resumeFromRunIdstring(none)Continue one interrupted run without re-collecting or re-charging what it already has.
incrementalModebooleanfalseReturn only new and changed products on recurring runs.
stateKeystring(none)Name or share one monitoring campaign's incremental-mode state.
ignoreFieldsForChangesarray[]Extra field names excluded from UPDATED change detection, on top of the built-in handling (a description/review/availability fetch that simply didn't land never counts as a change).
emitUnchangedbooleanfalseAlso return (and bill) unchanged products, marked UNCHANGED.
emitExpiredbooleanfalseAlso return (and bill) products no longer found, marked EXPIRED, once a run has fully scanned the tracked scope. EXPIRED rows count toward Max products; the rest stay tracked and come out on the next complete run (0 = no cap).

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"kind": "product",
"id": "00099999",
"itemNo": "00099999",
"itemType": "ART",
"name": "SAMPLE",
"typeName": "Shelving unit",
"description": "A simple sample shelving unit with adjustable shelves.",
"url": "https://www.ikea.com/us/en/p/sample-shelving-unit-white-00099999/",
"price": 148.0,
"currency": "USD",
"priceFormatted": "$148.00",
"onSale": true,
"isOnSpecial": true,
"wasPrice": 179.0,
"wasPriceFormatted": "$179.00",
"savingsAmount": 31.0,
"discountPercent": 17.3,
"specialsLabel": "IKEA Family price",
"ratingValue": 4.4,
"ratingCount": 812,
"averageRating": 4.4,
"reviewCount": 812,
"color": "slate gray",
"colors": [{ "name": "slate gray", "id": "90512", "hex": "5b6470" }],
"measurementText": "27 1/2x9 3/4x70 1/4 \"",
"width": 27.5,
"depth": 9.75,
"height": 70.25,
"measurementUnit": "in",
"material": "Particleboard, foil, plastic edging",
"categoryPath": ["Storage & organization", "Shelving units"],
"ancestorCategories": [
{ "name": "Storage & organization", "key": "st001", "url": "https://www.ikea.com/us/en/cat/storage-organization-st001/" },
{ "name": "Shelving units", "key": "st002", "url": "https://www.ikea.com/us/en/cat/shelving-units-st002/" }
],
"badge": "Best seller",
"isBestseller": true,
"onlineSellable": true,
"mainImage": "https://www.ikea.com/us/en/images/products/sample__0000001.jpg",
"mainImageAlt": "SAMPLE Shelving unit, slate gray",
"contextualImageUrl": "https://www.ikea.com/us/en/images/products/sample__0000002.jpg",
"contextualImageAlt": "Living room with the SAMPLE shelving unit",
"tag": "FAMILY_PRICE",
"tagText": "IKEA Family price",
"images": ["https://www.ikea.com/us/en/images/products/sample__0000001.jpg"],
"numberOfVariants": 3,
"variants": [
{ "id": "00099998", "name": "SAMPLE", "color": "black", "price": 158.0, "currency": "USD" }
],
"market": "us",
"language": "en",
"reviewsCollected": 1,
"reviews": [
{
"author": "Jordan R.",
"date": "2026-07-14",
"title": "Sturdy and easy to build",
"body": "Took about an hour to assemble and looks great in the living room.",
"rating": 5
}
],
"availability": {
"national": { "country": "US", "homeDelivery": true, "clickCollect": true, "stockStatus": "HIGH_IN_STOCK" },
"storesWithStock": 37,
"stores": [
{ "code": "512", "cashCarry": true, "quantity": 48, "stockStatus": "HIGH_IN_STOCK" }
]
}
}

Plan Requirement

IKEA's product and listing web pages sit behind an edge filter that refuses datacenter connections (HTTP 403 "Attention Required" page), while the same pages load normally over a residential connection. Search, category and availability data are read from lighter data endpoints first, and the run automatically retries with a different connection when one is refused, including a backup connection when the primary one is exhausted. Detail enrichment (the full description and individual review text) needs a residential connection and is skipped without one, so on a plan without residential proxy access expect results without descriptions or reviews. Pasted product links and pages that only load in full over residential are also affected. Choose a residential proxy group in the proxy settings for full coverage.

FAQ

How much does it cost?

You pay per product returned in the dataset, plus a one-time run start fee, plus a detail-enrichment charge for each product where the full description and the individual reviews (up to the Max reviews per product cap) were actually attached this run (never merely because the toggle is on, and never for a product suppressed by incremental mode). Reviews carry no separate charge: they are included in the detail-enrichment charge. Fetch full details and reviews defaults to on, so most runs will see the enrichment charge on most products unless you turn it off. The Pricing tab shows the current rates. Use Max products to cap the cost of any run.

This actor collects only publicly available product data. You are responsible for how you use it: follow IKEA's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, images and marketing descriptions may be subject to IKEA's own rights.

Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated products, and unchanged ones are not billed unless you also turn on Emit unchanged.

Why did my run fail instead of returning an empty dataset?

For search, category and listing/room links, if every page this run tried to read was refused or never answered, the run stops with a clear error instead of finishing with 0 products, so "nothing found" is never confused with "nothing could be read". A genuinely empty listing, or a category id IKEA does not recognise, still finishes normally with 0 products and a status message explaining which case it was. For productIds mode and pasted single product links, a fully blocked run is not currently distinguished from a genuinely empty result: it finishes normally with 0 products and a generic "no products found" message, so treat a surprising empty result from a lookup as worth retrying before assuming the item numbers themselves are wrong.

Why is Resume returning nothing new against a category I've already collected a lot from?

Resume skips ids you already have and pages past them, but IKEA caps any listing at 400 products. Once you hold that many, narrow the search or change Sort by.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more e-commerce data?

Pair this actor with these related scrapers from the same team:

๐Ÿ›’ Target AU Scraper
Scrape products and customer reviews from Target.com.au. Search by keyword or use...
๐Ÿ›’ MUJI Scraper
Scrape MUJI products from the United States, Canada and Australia storefronts. Search by...
๐Ÿ›’ Kmart Scraper
Scrape products and customer reviews from Kmart.com.au. Search by keyword or use...
๐Ÿ›’ Myer Scraper
Scrape Myer (myer.com.au) department-store products: name, brand, price, was-price...
๐Ÿ›’ Harvey Norman Scraper
Scrape Harvey Norman Australia products: name, brand, price, was-price / discount...
๐Ÿ›’ Costco AU Scraper
Scrape Costco.com.au products by keyword or product, search and category URLs. Extract...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.