# IKEA API scraper — every ikea.com country store (50 countries): search and browse products with the regular price, the IKEA Family price and new-lower-price or clearance was-prices kept apart, read the full product record (measurements, packages, materials, assembly documents), store stock with quantities and restock dates, reviews, the category tree, stores and autocomplete. No account, no browser.

> Search an IKEA country store by keyword. Each product comes with its item number, price and currency, the IKEA Family price separately, the previous price of a new-lower-price, limited-time or clearance offer with its validity, in-store-only offers, rating, colours, category path and whether it can be bought online. Sort by price, rating, newest or size; filter with IKEA's own filters (colour, price band, size, material, series, subcategory) or new, last-chance and best-seller flags.
> ReefAPI engine `ikea` · 8 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/ikea/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /ikea/v1/search — 1 credit
Search an IKEA country store by keyword. Each product comes with its item number, price and currency, the IKEA Family price separately, the previous price of a new-lower-price, limited-time or clearance offer with its validity, in-store-only offers, rating, colours, category path and whether it can be bought online. Sort by price, rating, newest or size; filter with IKEA's own filters (colour, price band, size, material, series, subcategory) or new, last-chance and best-seller flags.

**Parameters:**
- `query` (string, required) — What to look for, as a shopper types it in the store's language ('sofa', 'Kleiderschrank', 'ソファ'). Product names (BILLY) and item numbers work too.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `page` (integer, optional, default 1) — Result page, 1-based.
- `page_size` (integer, optional, default 24) — Products per page (1-48, default 24).
- `sort` (enum, optional, default "relevance") — Result order. A listing's `sort_options` says which orders that listing supports (the all-products category has no `newest`). [one of: relevance, price_asc, price_desc, newest, rating, most_popular, name, width, height, depth]
- `filters` (object, optional) — IKEA's own filters, keyed by `filters_available[].parameter` with value ids from `filters_available[].values[].id`: colour (f-colors), price band (f-price-buckets), size band (f-measurement-buckets), material, series, subcategory (f-subcategories), rating (f-ratings) … Several values of one filter are OR-ed, different filters AND-ed. A filter the listing does not have is reported in `filters_not_applied`.
- `new_only` (boolean, optional, default false) — true: only products IKEA marks as new.
- `last_chance_only` (boolean, optional, default false) — true: only 'last chance' products (being phased out).
- `top_seller_only` (boolean, optional, default false) — true: only IKEA best sellers.
- `business_only` (boolean, optional, default false) — true: only products IKEA marks as suitable for business use.
- `include_variants` (boolean, optional, default false) — true: each row also lists up to 12 colour/size variants with their own id, price and image (the page gets about three times larger). `variant_count` is always returned.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** results[]{product_id ('s39399112' for combinations), item_no (8 digits), item_no_global, item_type ('ART' article | 'SPR' combination), title, name, type_name, design, measure, url, image, contextual_image, price (what a shopper without IKEA Family pays online; null on an IKEA Family price with no published regular price), currency, price_type ('regular' | 'new_lower_price' | 'time_restricted_offer' | 'discontinued' | 'family_price' | 'lower_price_in_store'), original_price (the previous price of a new-lower-price, limited-time or clearance price), discount_percent, member_price (IKEA Family price), member_program, member_discount_percent, lowest_previous_price (EU: lowest price in the 30 days before the reduction), price_valid_from, price_valid_to, price_disclaimer, price_basis ('per_item' | 'per_pack' — the price is for pack_quantity pieces, e.g. 4 chairs | 'per_quantity' — the price is for a pack holding `quantity` `unit`, e.g. 0.5 kg of jam), pack_quantity, quantity, unit, price_unit (IKEA's own text, e.g. '4 szt.', '0,5 kg'), in_store_offer{text, members_only, valid_from, valid_to} (a price valid only in the store, never the online price), low_price_item, online_sellable, last_chance, is_new, top_seller, rating, rating_count (all markets), rating_scale, colours[]{id, name, hex}, category_path[]{key, name}, product_area, home_furnishing_business, variant_count, min_order_quantity, energy_class, variants[] (include_variants=true)}, count, total_results, page, page_size, page_count, filters_available[]{parameter, name, kind, selected, values[]{id, name, group, count, selected}}, sort_options[], sort_applied, filters_applied{}, filters_not_applied[], country, language, currency, query

**Example request body:**
```json
{
  "query": "sofa"
}
```

### POST /ikea/v1/category — 1 credit
Every product in one IKEA category (e.g. Sofas, Table lamps), paged, with the same rows, sorting and filters as search.

**Parameters:**
- `category_id` (string, required) — IKEA category key ('fu003' = Sofas, '10732' = Table lamps) from `categories`, a row's `category_path`, `suggest`, or the end of a category URL (/cat/sofas-fu003/).
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `page` (integer, optional, default 1) — Result page, 1-based.
- `page_size` (integer, optional, default 24) — Products per page (1-48, default 24).
- `sort` (enum, optional, default "relevance") — Result order. A listing's `sort_options` says which orders that listing supports (the all-products category has no `newest`). [one of: relevance, price_asc, price_desc, newest, rating, most_popular, name, width, height, depth]
- `filters` (object, optional) — IKEA's own filters, keyed by `filters_available[].parameter` with value ids from `filters_available[].values[].id`: colour (f-colors), price band (f-price-buckets), size band (f-measurement-buckets), material, series, subcategory (f-subcategories), rating (f-ratings) … Several values of one filter are OR-ed, different filters AND-ed. A filter the listing does not have is reported in `filters_not_applied`.
- `new_only` (boolean, optional, default false) — true: only products IKEA marks as new.
- `last_chance_only` (boolean, optional, default false) — true: only 'last chance' products (being phased out).
- `top_seller_only` (boolean, optional, default false) — true: only IKEA best sellers.
- `business_only` (boolean, optional, default false) — true: only products IKEA marks as suitable for business use.
- `include_variants` (boolean, optional, default false) — true: each row also lists up to 12 colour/size variants with their own id, price and image (the page gets about three times larger). `variant_count` is always returned.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** results[]{product_id ('s39399112' for combinations), item_no (8 digits), item_no_global, item_type ('ART' article | 'SPR' combination), title, name, type_name, design, measure, url, image, contextual_image, price (what a shopper without IKEA Family pays online; null on an IKEA Family price with no published regular price), currency, price_type ('regular' | 'new_lower_price' | 'time_restricted_offer' | 'discontinued' | 'family_price' | 'lower_price_in_store'), original_price (the previous price of a new-lower-price, limited-time or clearance price), discount_percent, member_price (IKEA Family price), member_program, member_discount_percent, lowest_previous_price (EU: lowest price in the 30 days before the reduction), price_valid_from, price_valid_to, price_disclaimer, price_basis ('per_item' | 'per_pack' — the price is for pack_quantity pieces, e.g. 4 chairs | 'per_quantity' — the price is for a pack holding `quantity` `unit`, e.g. 0.5 kg of jam), pack_quantity, quantity, unit, price_unit (IKEA's own text, e.g. '4 szt.', '0,5 kg'), in_store_offer{text, members_only, valid_from, valid_to} (a price valid only in the store, never the online price), low_price_item, online_sellable, last_chance, is_new, top_seller, rating, rating_count (all markets), rating_scale, colours[]{id, name, hex}, category_path[]{key, name}, product_area, home_furnishing_business, variant_count, min_order_quantity, energy_class, variants[] (include_variants=true)}, count, total_results, page, page_size, page_count, filters_available[]{parameter, name, kind, selected, values[]{id, name, group, count, selected}}, sort_options[], sort_applied, filters_applied{}, filters_not_applied[], country, language, currency, category_id

### POST /ikea/v1/categories — 1 credit
IKEA's category tree, one level at a time: a category with its product count and its child categories (key, name, product count). Start at the root for the top-level departments.

**Parameters:**
- `category_id` (string, optional) — Category key to open. Default: the root ('products'), whose children are the top-level departments.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** category{key, name, url, image, product_count}, children[]{key, name, product_count}, count, country, language

### POST /ikea/v1/product/detail — 2 credits
The full IKEA product record by item number or URL: every price kept apart (regular, IKEA Family, previous, lowest 30-day, in-store-only), description, designer, key facts, measurements, every package with its dimensions and weight, the articles a combination consists of, materials and care instructions, safety notes, assembly instructions and manuals, energy labels, guarantee, return period, series, breadcrumb, colour/size options, images and rating.

**Parameters:**
- `product_id` (string, required) — IKEA item number (8 digits, with or without dots: 205.220.46; combinations may carry an 's' prefix: s39399112) or an ikea.com product URL, which also sets country and language.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** product{product_id, item_no, visible_item_no, item_no_global, item_type, title, name, type_name, design, measure, url, brand, price (what a shopper without IKEA Family pays online; null on an IKEA Family price with no published regular price), currency, price_type ('regular' | 'new_lower_price' | 'time_restricted_offer' | 'discontinued' | 'family_price' | 'lower_price_in_store'), original_price (the previous price of a new-lower-price, limited-time or clearance price), discount_percent, member_price (IKEA Family price), member_program, member_discount_percent, lowest_previous_price (EU: lowest price in the 30 days before the reduction), price_valid_from, price_valid_to, price_disclaimer, price_basis ('per_item' | 'per_pack' — the price is for pack_quantity pieces, e.g. 4 chairs | 'per_quantity' — the price is for a pack holding `quantity` `unit`, e.g. 0.5 kg of jam), pack_quantity, quantity, unit, price_unit (IKEA's own text, e.g. '4 szt.', '0,5 kg'), in_store_offer{text, members_only, valid_from, valid_to} (a price valid only in the store, never the online price), low_price_item, online_sellable, last_chance, is_new, top_seller, coming_soon, is_food, is_mattress, min_order_quantity, rating, rating_count, rating_scale, secondary_ratings{}, short_description, description[], designer, key_facts[]{type, label, value}, measurements[]{name, value, type}, number_of_packages, packaging[]{item_no, article_number, name, type_name, quantity, packages[]{width|height|length|weight|volume: {text, value, unit}}}, sub_products[]{item_no, item_type, name, type_name, quantity, url}, materials[]{product_type, parts[]{part, material}}, care_instructions[], good_to_know[]{name, text}, safety_and_compliance[]{name, text}, documents[]{kind, label, item, url}, energy_labels[], guarantee_years, guarantee, return_days, series{name, url}, breadcrumb[]{name, url}, category_path[], colours[], variant_count, style_options[]{code, title, selected, options[]{title, product_id, url, selected}}, images[]{url, type, alt}, videos[], product_area}, country, language

**Example request body:**
```json
{
  "product_id": "20522046"
}
```

### POST /ikea/v1/product/availability — 1 credit
Stock of up to 10 IKEA products in every store of a country (or one store): quantity in the store where IKEA publishes it, stock status, expected restock dates and quantities, the aisle and bin to pick it from, click & collect, and whether home delivery is available.

**Parameters:**
- `product_id` (string, optional) — IKEA item number (8 digits, with or without dots: 205.220.46; combinations may carry an 's' prefix: s39399112) or an ikea.com product URL, which also sets country and language.
- `product_ids` (array, optional) — Up to 10 item numbers in one call (alternative to `product_id`).
- `store_id` (string, optional) — Only this store (the id from `stores`, e.g. '211'). Default: every store in the country.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** items[]{item_no, item_type, online{home_delivery_available, click_collect_available, home_delivery_status, parcel, max_order_quantity, updated_at}, stores[]{store_id, store_name, in_range, cash_carry_available, click_collect_available, quantity, status ('high_in_stock' | 'low_in_stock' | 'out_of_stock' | null), restocks[]{earliest_date, latest_date, quantity, reliability}, pickup[], sales_locations[]{type, division, aisle, bin}, updated_at}, store_count, in_stock_store_count}, not_found[], count, country

**Example request body:**
```json
{
  "product_id": "20522046"
}
```

### POST /ikea/v1/product/reviews — 1 credit
Customer reviews of one IKEA product, paged: title, text, star rating, sub-ratings (quality, value for money, assembly …), recommendation, verified purchase, helpful votes, IKEA's public reply and photos, plus the rating summary and distribution. Filter by star rating, verified purchases or reviews from other countries.

**Parameters:**
- `product_id` (string, required) — IKEA item number (8 digits, with or without dots: 205.220.46; combinations may carry an 's' prefix: s39399112) or an ikea.com product URL, which also sets country and language.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `page` (integer, optional, default 1) — Review page, 1-based.
- `page_size` (integer, optional, default 20) — Reviews per page (1-50, default 20).
- `sort` (enum, optional, default "newest") — Review order. [one of: newest, oldest, highest_rating, lowest_rating, most_helpful]
- `ratings` (array, optional) — Only reviews with these star ratings (1-5).
- `scope` (enum, optional, default "local") — IKEA shares reviews between countries. `local` = written in this country (default); `other_markets` = everywhere else. [one of: local, other_markets]
- `verified_only` (boolean, optional, default false) — true: only reviews from verified purchases.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** item_no, summary{rating, rating_scale, total_reviews_all_markets, total_ratings_all_markets, recommended_count, not_recommended_count, rating_distribution{1..5}, secondary_ratings{}, first_review_at, last_review_at}, reviews[]{review_id, title, text, rating, rating_scale, secondary_ratings{}, recommended, verified_purchase, author, submitted_at, updated_at, source_country, source_language, reviewed_item_no, helpful_count, unhelpful_count, ikea_response{text, by, at}, media[]}, count, page, page_size, has_more, sort_applied, scope, country, language

**Example request body:**
```json
{
  "product_id": "20522046"
}
```

### POST /ikea/v1/stores — 1 credit
Every IKEA store in a country with its store id (used by product/availability), name, coordinates, type and opening date.

**Parameters:**
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** stores[]{store_id, name, display_name, lat, lng, type, opening_date}, count, country

### POST /ikea/v1/suggest — 1 credit
IKEA's search autocomplete for what a shopper has typed: suggested searches, matching categories and products.

**Parameters:**
- `query` (string, required) — What the shopper has typed so far.
- `country` (enum, optional, default "us") — Which IKEA country store. Prices come back in its currency and texts in its language. Item numbers are mostly global but not every product is sold everywhere, and some products carry a different item number per market. [one of: ae, at, au, be, bh, ca, ch, cl, co, cz, de, dk, ee, eg, es, fi, fr, gb, hr, hu, ie, il, in, it, jo, jp, kr, kw, lt, lv, ma, mx, my, nl, no, nz, om, ph, pl, pt, qa, ro, rs, sa, se, sg, si, sk, th, us]
- `language` (enum, optional) — Language of names, descriptions and filter labels, for countries IKEA publishes in several languages (ca: en/fr, ch: de/fr/it/en, be: nl/fr/en, es: es/ca/eu/gl/en …). Default: the country's first language (de for Germany, ja for Japan, ar for the Gulf stores). A language the country does not publish is rejected. [one of: ar, ca, cs, da, de, en, es, et, eu, fi, fr, gl, he, hr, hu, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sr, sv, th]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-6, default 3).

**Returns:** completions[], categories[]{key, name, url}, products[]{product_id, title, url, image, online_sellable, rating, rating_count}, query, country, language

**Example request body:**
```json
{
  "query": "sofa"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=ikea
- Human docs page: https://reefapi.com/docs/ikea
- Overview page: https://reefapi.com/ikea-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
