# IKEA Product Search Scraper (`cirkit/ikea-product-search-scraper`) Actor

Scrape IKEA's full product catalog by keyword across 30+ markets. Returns name, price, ratings, images, category path, online availability per result; optional per-product detail + per-store stock enrichment via IKEA's public APIs.

- **URL**: https://apify.com/cirkit/ikea-product-search-scraper.md
- **Developed by:** [Crikit](https://apify.com/cirkit) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## IKEA Product Search Scraper

A fast, cheap Apify actor that scrapes IKEA's product catalog by keyword across 30+ markets. Hits IKEA's public search API directly (no headless browser, no Akamai games), returns structured product data with prices, ratings, images, category paths, and online availability per result. Optional enrichment pulls full product details and per-store stock from IKEA's product APIs.

Pay per item. No actor-start fee. **$0.0008 per product**, which is 20% under the cheapest competitor and 60% under the most-used one.

### What it does

For every search query you pass in, the IKEA Product Search Scraper:

1. Hits IKEA's SIK ("Search In Kontext") search API at `sik.search.blue.cdtapps.com/{country}/{lang}/search` with the keyword you provide.
2. Walks the paginated result set up to your per-query cap (or until IKEA runs out of hits).
3. Optionally enriches each product with the full "communications" record (child SKUs, assembly instructions, care instructions, package dimensions) and a per-store stock summary.
4. Writes one row per product to the dataset.

No login. No cookies. No proxy required (datacenter IPs work). The actor refreshes IKEA's public client keys from a product page once per run so it stays resilient to silent key rotation.

### Inputs

| Field | Type | Default | Notes |
|---|---|---|---|
| `queries` | array of strings | required | One or more keyword queries. Each runs independently. |
| `country` | string | `us` | Two-letter IKEA market code: `us`, `gb`, `de`, `fr`, `se`, `ca`, `au`, `it`, `nl`, `jp`, `kr`, and so on. |
| `language` | string | `en` | Two-letter language matching the market. |
| `maxItemsPerQuery` | integer | `0` (no cap) | Per-query cap. IKEA returns up to ~1000 hits per query depending on category. |
| `maxItems` | integer | `0` (no cap) | Global cap across every query. |
| `includeProductDetails` | boolean | `false` | Adds the full communications record per product (child items, assembly steps, care, compliance, packaging). Roughly one extra HTTP call per 50 products. |
| `includeAvailability` | boolean | `false` | Adds a stock summary per product (cash-and-carry quantity, message type, stores with stock). Roughly one extra HTTP call per 50 products. |
| `proxyConfiguration` | object | Apify proxy AUTO | Datacenter IPs are sufficient. Residential is supported but not required for IKEA's data APIs. |

### Output

Each row is one product. **Guaranteed** fields are present on every record returned by IKEA's search. **Optional** fields appear only when the corresponding enrichment flag is set.

#### Guaranteed

- `id` - IKEA item number (sometimes prefixed `s` for SPR-style products; treat as a string key).
- `itemNoGlobal` - Cross-market product identifier.
- `itemType` - `SPR` (sales product) or `ART` (article / component).
- `name` - Product name as shown on IKEA (e.g. `MORABO`, `KALLAX`).
- `typeName` - Product type label (e.g. `Sofa`, `Bookcase`, `Table and 4 chairs`).
- `url` - Direct link to the product page.
- `price` - `{currency, currentPrice, formattedPrice, previousPrice, formattedPreviousPrice, discount, formattedDiscountAmount, isBreathTaking}`.
- `rating` - `{average, count}`.
- `images` - `{main, contextual, all: [{type, url}]}` with IKEA's image role typing (`MAIN_PRODUCT_IMAGE`, `CONTEXT_PRODUCT_IMAGE`, `QUALITY_PRODUCT_IMAGE`, etc.).
- `details` - `{designText, isOnlineSellable, badge, lastChance, colors, measurementText, gprDescription, quickFacts}`.
- `categoryPath` - Array of `{name, key}` from the top-level category to the leaf.
- `businessStructure` - IKEA's internal home-furnishing-business / product-area hierarchy.
- `availability` - Summary string embedded in the SIK result.
- `query`, `country`, `language` - Echoed back per row.

#### Optional (when `includeProductDetails: true`)

- `productDetails` - Full IKEA communications record: child items, assembly time and instruction PDF URLs, care instructions, compliance information, package dimensions, design materials.

#### Optional (when `includeAvailability: true`)

- `stock` - `{availableForCashCarry, availableForClickCollect, homeDeliveryInRange, cashCarryQuantity, cashCarryMessageType, cashCarryUpdateDateTime, storesWithStock}`.

### Pricing

| Event | Price |
|---|---|
| Product result (one row in the dataset) | $0.0008 |

No actor-start fee. No tier ladder. Flat $0.0008 per product.

**Worked examples:**

- 100 products: $0.08
- 1,000 products: $0.80
- 10,000 products: $8.00
- 100,000 products: $80.00

For reference, the cheapest current IKEA scraper on Apify charges $0.001 per result plus a per-run fee, and the most-used one charges $0.002 per result plus a per-run fee. This actor is cheaper than both and skips the per-run charge entirely.

### How it works

The actor talks to three IKEA API endpoints, all public:

1. `POST sik.search.blue.cdtapps.com/{country}/{lang}/search` - full search-result payload with prices, ratings, images, and filters.
2. `GET api.ingka.ikea.com/salesitem/communications/ru/{country}` - per-product detail (used only when `includeProductDetails` is on).
3. `GET api.salesitem.ingka.com/availabilities/ru/{country}` - per-store stock (used only when `includeAvailability` is on).

The two enrichment endpoints want a public client key in the `X-Client-Id` / `X-Client-ID` header. Those keys ship in plain HTML on every IKEA product page. The actor refreshes them at the start of every run from `https://www.ikea.com/{country}/{language}/p/...`, so silent key rotations do not break it.

### Limits

- IKEA's search caps each result page at about 120 items regardless of what you ask for. The actor pages with offsets and stops automatically at the total hit count.
- Single-query result counts vary from ~50 to ~1000 depending on the category. There is no public way to push beyond IKEA's own ceiling.
- The `gb`/`de`/`fr` and other non-US markets work the same way. Make sure the `country` and `language` codes match a real IKEA market.

### FAQ

**Why is this cheaper than the other IKEA scrapers?**
It hits IKEA's data APIs directly with bare HTTP. No headless Chrome, no residential proxies, no parsing HTML. That makes both the per-result compute cost and the dev-time investment a fraction of a browser-based approach, and the savings are passed through.

**Do I need an Apify proxy?**
No. The IKEA endpoints have no anti-bot on the data plane. Datacenter Apify proxy (the default) is fine. Residential is supported if you want to be cautious.

**Will this work for non-US markets?**
Yes. Pass `country` and `language` (e.g. `de`/`de`, `gb`/`en`, `fr`/`fr`, `se`/`sv`). The same APIs serve every IKEA market.

**Can I just dump every IKEA product?**
Pass a list of broad queries (`furniture`, `kitchen`, `lighting`, ...) and a large `maxItems`. For a cleaner enumeration use IKEA's category pages; a future version of the actor may take category keys directly.

**Does it return real-time data?**
Search results and prices are near-real-time. Stock with `includeAvailability` returns per-store snapshot data with an `updateDateTime` per store; trust that field over local caching.

### Changelog

- `0.1` - Initial release. SIK search + optional communications + optional availabilities enrichment.

# Actor input Schema

## `queries` (type: `array`):

One or more keyword queries to search IKEA for. Each query is processed independently.
## `country` (type: `string`):

Two-letter IKEA market code (e.g. us, gb, de, fr, se, ca, au, it, nl, jp, kr).
## `language` (type: `string`):

Two-letter language code matching the market (e.g. en for us/gb/au, de for de, fr for fr).
## `maxItemsPerQuery` (type: `integer`):

Cap on the number of products returned per query. 0 = no cap. IKEA caps total hits per query at ~700-1000 depending on category.
## `maxItems` (type: `integer`):

Hard global cap across all queries combined. 0 = no cap.
## `includeProductDetails` (type: `boolean`):

Enrich each product with the full communications record: child items, assembly instructions, care instructions, compliance info, package dimensions. Adds ~1 extra HTTP call per 50 products.
## `includeAvailability` (type: `boolean`):

Adds a stock summary per product (cash-and-carry quantity, message type, stores with stock). Adds ~1 extra HTTP call per 50 products.
## `proxyConfiguration` (type: `object`):

Apify proxy is enabled by default. Datacenter IPs are sufficient; residential is not required for the IKEA APIs. Pick any group your plan supports, or disable proxy entirely.

## Actor input object example

```json
{
  "queries": [
    "sofa",
    "kallax",
    "dining table"
  ],
  "country": "us",
  "language": "en",
  "maxItemsPerQuery": 100,
  "maxItems": 0,
  "includeProductDetails": false,
  "includeAvailability": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
````

# Actor output Schema

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

All products from the latest run.

## `itemsJson` (type: `string`):

All products in JSON format.

## `itemsCsv` (type: `string`):

All products in CSV format.

## `consoleRun` (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 = {
    "queries": [
        "sofa"
    ],
    "country": "us",
    "language": "en",
    "maxItemsPerQuery": 100,
    "includeProductDetails": false,
    "includeAvailability": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/ikea-product-search-scraper").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 = {
    "queries": ["sofa"],
    "country": "us",
    "language": "en",
    "maxItemsPerQuery": 100,
    "includeProductDetails": False,
    "includeAvailability": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/ikea-product-search-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "sofa"
  ],
  "country": "us",
  "language": "en",
  "maxItemsPerQuery": 100,
  "includeProductDetails": false,
  "includeAvailability": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call cirkit/ikea-product-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=cirkit/ikea-product-search-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "IKEA Product Search Scraper",
        "description": "Scrape IKEA's full product catalog by keyword across 30+ markets. Returns name, price, ratings, images, category path, online availability per result; optional per-product detail + per-store stock enrichment via IKEA's public APIs.",
        "version": "0.1",
        "x-build-id": "uG55dQt5QvjRS1sXA"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/cirkit~ikea-product-search-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-cirkit-ikea-product-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/cirkit~ikea-product-search-scraper/runs": {
            "post": {
                "operationId": "runs-sync-cirkit-ikea-product-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/cirkit~ikea-product-search-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-cirkit-ikea-product-search-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "queries"
                ],
                "properties": {
                    "queries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "One or more keyword queries to search IKEA for. Each query is processed independently.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Country code",
                        "pattern": "^[a-z]{2}$",
                        "type": "string",
                        "description": "Two-letter IKEA market code (e.g. us, gb, de, fr, se, ca, au, it, nl, jp, kr).",
                        "default": "us"
                    },
                    "language": {
                        "title": "Language code",
                        "pattern": "^[a-z]{2}$",
                        "type": "string",
                        "description": "Two-letter language code matching the market (e.g. en for us/gb/au, de for de, fr for fr).",
                        "default": "en"
                    },
                    "maxItemsPerQuery": {
                        "title": "Max items per query",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on the number of products returned per query. 0 = no cap. IKEA caps total hits per query at ~700-1000 depending on category.",
                        "default": 0
                    },
                    "maxItems": {
                        "title": "Max items total",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard global cap across all queries combined. 0 = no cap.",
                        "default": 0
                    },
                    "includeProductDetails": {
                        "title": "Include product details (slower)",
                        "type": "boolean",
                        "description": "Enrich each product with the full communications record: child items, assembly instructions, care instructions, compliance info, package dimensions. Adds ~1 extra HTTP call per 50 products.",
                        "default": false
                    },
                    "includeAvailability": {
                        "title": "Include per-store stock",
                        "type": "boolean",
                        "description": "Adds a stock summary per product (cash-and-carry quantity, message type, stores with stock). Adds ~1 extra HTTP call per 50 products.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy is enabled by default. Datacenter IPs are sufficient; residential is not required for the IKEA APIs. Pick any group your plan supports, or disable proxy entirely.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
