# KICKS Scraper - Nordic Beauty Prices and EAN (`studio-amba/kicks-scraper`) Actor

Scrape product data from KICKS (kicks.se, kicks.no, kicks.fi), the Nordic beauty retailer. Get price, price before campaign, EAN, brand, size, category, rating, review count and stock status for every variant in SEK, NOK or EUR.

- **URL**: https://apify.com/studio-amba/kicks-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## KICKS Scraper

Pull product data from KICKS, the Nordic beauty retailer, in Sweden (kicks.se), Norway (kicks.no) and Finland (kicks.fi). The actor returns one row per product variant with the EAN barcode, the selling price in SEK, NOK or EUR, the price before campaign, the discount, category, rating, review count and stock status.

KICKS sells make-up, skincare, fragrance, hair care and personal care from several thousand brands. If you track Nordic beauty prices or match Nordic products against shops in other countries by EAN, this actor gives you a repeatable feed.

### How to scrape KICKS data

There are three ways to tell the actor which products to read. First choose the storefront in `country`: `se`, `no` or `fi`.

1. Paste product pages into `productUrls`, for example `https://www.kicks.se/givenchy-gentleman-reserve-privee-edp-100-ml`.
2. Leave `productUrls` empty and fill `urlKeywords` with brand names or words from the product address, for example `givenchy` or `la-roche-posay`. The actor reads the matching products from the public product sitemap.
3. Leave both empty. The actor reads the first products from the sitemap.

The actor stops at `maxResults`. If you leave everything empty, it reads the first 50 rows.

Every address on KICKS is one variant, which is one size or one shade. Each variant has its own EAN and price, so each address becomes one row.

Search result pages are not read. The actor requests product pages and sitemaps, and it stays away from the paths that robots.txt excludes. Requests are spaced out.

### Input

| Field | Type | Description |
|---|---|---|
| `country` | text | Storefront: `se` for Sweden, `no` for Norway, `fi` for Finland. Default `se`. |
| `productUrls` | list of text | Product pages from the chosen storefront. Up to 100. |
| `urlKeywords` | list of text | Brand names or address words. Used when `productUrls` is empty. |
| `maxResults` | number | Maximum number of rows. Default 50. |
| `proxyConfiguration` | object | Proxy for the requests. Default is Apify Proxy. |

Example input:

```json
{
    "country": "no",
    "urlKeywords": ["givenchy"],
    "maxResults": 100
}
```

### Output

Each row is one variant. Example:

```json
{
    "productId": "774168",
    "ean": "3474636976027",
    "name": "L'Oréal Professionnel Série Expert Blondifier Masque 250 ml",
    "size": "250 ml",
    "brand": "L'Oréal Professionnel",
    "category": "Hårinpackning",
    "price": 332,
    "originalPrice": 415,
    "discountPercent": 20,
    "currency": "SEK",
    "unitQuantity": "250 MLT",
    "rating": null,
    "reviewCount": 0,
    "inStock": true,
    "availability": "InStock",
    "imageUrl": "https://images.matas.dk/Assets_v3/700001-800000/709001-710000/709201-709300/709273/product_v1_x2.jpg",
    "url": "https://www.kicks.se/loreal-professionnel-serie-expert-blondifier-masque-250-ml",
    "scrapedAt": "2026-11-03T15:04:27.636Z",
    "country": "se",
    "language": "sv"
}
```

| Field | Description |
|---|---|
| `productId` | KICKS article number of the variant. |
| `ean` | EAN or GTIN barcode as published by the shop. |
| `name`, `size`, `brand`, `category` | Product name, size or shade, brand and product group in the language of the storefront. |
| `price` | Selling price in the storefront currency, VAT included. When a campaign is running, this is the campaign price. |
| `originalPrice`, `discountPercent` | Price without campaign and the percentage between the two. Empty when the selling price is not lower. |
| `currency` | SEK for Sweden, NOK for Norway, EUR for Finland. |
| `unitQuantity` | Quantity the shop uses for its unit price, for example 250 MLT. |
| `rating`, `reviewCount` | Average rating out of 5 and number of reviews. Rating is empty when there are no reviews. |
| `inStock`, `availability` | Stock status as published. |
| `imageUrl`, `url` | Image of the variant and product page. |
| `country`, `language` | Storefront country and language code. |

### What the data does not contain

Seller names, delivery times, store stock per shop and unit prices per 100 ml are not in the output. Member prices from the KICKS club are not in the output.

### Pricing

The actor is billed per result. You pay for each row that is returned, and a run that returns nothing costs only the Apify platform usage.

### Tips

- Use `urlKeywords` with a brand name to read one brand. The brand is part of most product addresses.
- Use the `ean` field to match products against other shops, in the Nordics or in other countries. Some EANs carry leading zeros, as the shop publishes them.
- Run the same keywords for `se`, `no` and `fi` to compare the three markets. The address of the same product can differ per country, so match on `ean`.
- Schedule the actor daily or weekly to build a price history and to see when campaigns start and end through `originalPrice`.
- Pages that carry no structured product data are skipped without a row and counted in the run log.
- The cost of a run settles after the run SUCCEEDED, so the usage figure on a running job is not final.
- A keyword that matches no product ends the run with a message saying no products matched.

### Is it legal to scrape KICKS?

The actor reads public product pages that anyone can open without logging in. It collects product information only, no personal data. Check your own use of the data against the site terms and the laws that apply to you.

### FAQ

**Does it need a login?** No.

**How many products does the site have?** The product sitemap lists between 40,000 and 44,000 addresses per country. Each address is one variant.

**Which currencies are used?** Swedish krona on kicks.se, Norwegian krone on kicks.no and euro on kicks.fi.

**Which fields are always filled?** Name, price, currency, URL, product ID, brand, availability and EAN.

**What is the difference between price and originalPrice?** `price` is the selling price. `originalPrice` is the price without campaign, filled when it is higher.

**Can I get a whole brand?** Yes. Set `urlKeywords` to the brand and `maxResults` to a high number. The run reads one page per variant.

**Does it work for kicks.dk?** No. The Danish site is not part of this actor.

### Support

Open an issue on the actor page if a field is missing or a variant is read wrong.

# Actor input Schema

## `country` (type: `string`):

KICKS storefront to read. Sweden prices are in SEK, Norway in NOK, Finland in EUR.

## `productUrls` (type: `array`):

Product pages from the chosen storefront, for example https://www.kicks.se/givenchy-gentleman-reserve-privee-edp-100-ml. Each address is one variant and becomes one row.

## `urlKeywords` (type: `array`):

Used when no product URLs are given. The actor reads the shop sitemap and keeps products whose address contains one of these words, for example givenchy or la-roche-posay. Leave empty to read the first products in the sitemap.

## `maxResults` (type: `integer`):

Maximum number of rows (one row per product variant).

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

Proxy used for the requests. Default is Apify Proxy.

## Actor input object example

```json
{
  "country": "se",
  "urlKeywords": [
    "givenchy"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "urlKeywords": [
        "givenchy"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/kicks-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 = {
    "urlKeywords": ["givenchy"],
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/kicks-scraper").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 '{
  "urlKeywords": [
    "givenchy"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/kicks-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/kicks-scraper"
        }
    }
}
```

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/7vKm6cG3rOMDlxw1B/builds/dF1qu3sPm471JxO1g/openapi.json
