# bol.com NL Catalog Product Export (`automation-lab/bol-com-catalog-product-export`) Actor

Export public bol.com Netherlands keyword catalog cards with product IDs, titles, URLs, listed prices, stock labels, sellers and rating summaries. Create repeatable marketplace snapshots without fetching product details or reviews.

- **URL**: https://apify.com/automation-lab/bol-com-catalog-product-export.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (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 catalog product exporteds

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

## bol.com NL Catalog Product Export

Export **bol products** from public Netherlands keyword search cards into structured product-price snapshots. Collect product IDs, titles, URLs, listed EUR prices, exposed stock labels, sellers and rating summaries without fetching individual product pages.

Use the results for assortment research, marketplace comparisons and recurring spreadsheet snapshots. This is a catalog-card exporter, not a retailer API, stock-quantity feed or complete offers database.

### Why use this Actor?

- Search multiple keywords in a defined order.
- Export one row per unique product ID across the whole run.
- Keep query, page, position, sponsorship and extraction time with each row.
- Avoid extra detail-page requests when public card data is enough.
- Use managed Netherlands residential sessions; no proxy configuration is needed.

### Who is it for?

Marketplace analysts can compare listed prices across repeated snapshots. Catalog teams can identify public product URLs for further research. Brands can inspect search placement, including labeled sponsored cards. Analysts should retain run dates and compare identical query settings rather than treating search results as an exhaustive inventory.

### Getting started

1. Open the Input tab.
2. Enter a keyword such as `lego`.
3. Choose a global product limit and a per-query page cap.
4. Run the Actor and open the default dataset.
5. Export JSON, CSV or Excel through Apify's dataset controls.

```json
{"queries":["lego"],"maxItems":30,"maxPagesPerQuery":5}
```

### Inputs and search semantics

| Input | Default | Meaning |
| --- | --- | --- |
| `queries` | Required | 1–10 nonempty strings, each at most 200 characters after trimming |
| `maxItems` | 30 | Global unique-product limit, 1–500; Console prefill 20 |
| `maxPagesPerQuery` | 5 | Maximum search pages for each query, 1–20 |

Queries are trimmed; exact duplicates are removed, preserving order. Search relevance, fuzzy matching and suggestions are controlled by bol.com. There is no exact-phrase, whole-word or title-substring filtering. Sponsored placements are retained and labeled.

Earlier queries consume the global limit first. A product encountered under several queries appears once, with the first query and position. `rank` is one-based within its source page before deduplication; it is not a global search ranking. A repeated sponsored card may therefore cause gaps in exported positions.

Zero and unlimited values are unsupported. Page caps, catalog exhaustion, runtime or billing limits can return fewer than `maxItems`. The Actor follows exposed sequential next-page links, not every possible catalog result.

Unknown inputs are rejected instead of silently ignored. Product URLs, category URLs, Belgium, detail enrichment and review-body options are not supported.

### Extracted data

| Field | Meaning |
| --- | --- |
| `productId` | Public bol.com product identifier, not necessarily an EAN |
| `title`, `url` | Catalog title and canonical NL product link |
| `price`, `currency` | Listed card price and EUR currency |
| `availability` | `InStock`, `OutOfStock`, or null if not exposed |
| `seller` | Card seller name, or null |
| `rating`, `reviewCount` | Exposed aggregate rating out of five and review count, or null |
| `sponsored` | Whether the card is labeled sponsored |
| `marketplace` | Always `NL` |
| `query`, `page`, `rank` | First encountered query and source position |
| `scrapedAt` | UTC extraction timestamp |

Prices are the publicly listed card values, not guaranteed checkout totals. Shipping, service fees, member-specific discounts, delivery dates and complete seller-offer lists are not included. Availability is not a warehouse quantity. Missing values remain null rather than being guessed.

### Output example

This record illustrates actual catalog-card extraction. Prices and search order can change.

```json
{
  "productId":"9300000021924021",
  "title":"Sleutelhanger - Ninjago Legacy - Jay - Met licht",
  "url":"https://www.bol.com/nl/nl/p/sleutelhanger-ninjago-legacy-jay-met-licht/9300000021924021/",
  "price":19.95,
  "currency":"EUR",
  "availability":"InStock",
  "seller":"MYBA Trading",
  "rating":5,
  "reviewCount":1,
  "sponsored":true,
  "marketplace":"NL",
  "query":"lego",
  "page":1,
  "rank":1,
  "scrapedAt":"2026-10-25T21:07:03.408Z"
}
```

### Run summary and counters

The default dataset is the primary output. `SUMMARY` in the run's key-value store records page, attempt, retry, response-byte, scanned-card and saved-row counts with applied limits. Response bytes describe received document bodies, not a billing meter.

### How much does it cost to export bol.com catalog products?

A one-time **$0.01 start fee** applies per run, plus a charge for each unique product exported. On BRONZE, the product charge is **$0.002 per product**. Other subscription tiers have their own product rates; check the Pricing tab for the current tier.

BRONZE computed invoice examples:

| Unique products | Estimated total including start |
| --- | --- |
| 1 | $0.012 |
| 10 | $0.03 |
| 100 | $0.21 |

These totals include the start fee and product events. There is no separate review, seller or page event. Duplicate or rejected cards are not charged as additional products. A valid empty search can still incur the start fee.

### Reliability and failure behavior

The Actor uses one browser at a time with a sticky Netherlands residential identity. Only search documents are downloaded; media, scripts and other subresources are blocked. Healthy sessions and cookies are reused across pages.

A failed or challenged page gets at most three total attempts, with a fresh browser/proxy identity after a failure and bounded backoff. Exhaustion fails the run rather than reporting an empty success. An explicitly recognized no-results page is a normal empty outcome. Unexpected page layouts also fail honestly.

If a later query or page fails, rows already saved remain partial results. Inspect run status before treating an export as complete. Do not automatically start repeated runs to work around a persistent source outage.

### Integrations and recurring snapshots

Schedule this Actor in Apify to produce dated snapshots; the Actor itself does not store price history, compute changes or send alerts. Save complete datasets externally and join by `productId` plus run date in a spreadsheet, warehouse or reporting tool.

Use Apify dataset export, webhooks, Make, Zapier or an API client to move results into your own pipeline. Retain `query`, `page` and `sponsored` when comparing search placement, because source ranking and advertising change.

### API usage

Keep your token in an environment variable, never in shared source.

```bash
curl -X POST -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"queries":["lego"],"maxItems":30}' \
  'https://api.apify.com/v2/acts/automation-lab~bol-com-catalog-product-export/runs'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/bol-com-catalog-product-export')
    .call({ queries: ['lego'], maxItems: 30 });
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 30 });
```

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/bol-com-catalog-product-export').call(
    run_input={'queries': ['lego'], 'maxItems': 30})
items = client.dataset(run['defaultDatasetId']).list_items(limit=30).items
```

### Use with hosted MCP

Select this Actor's stable tool subset:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/bol-com-catalog-product-export'
```

Equivalent configuration for **Claude Desktop**, **Cursor**, and **VS Code** clients supporting remote HTTP MCP:

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/bol-com-catalog-product-export"}}}
```

Discover actual tool names and argument schemas with scoped `tools/list`. Actor selection also exposes run/data helpers; it does not expose exactly one tool. Example request: “Export up to 20 Netherlands bol.com catalog cards for lego, then show product IDs, titles and listed prices.” Execution requires your authorization.

#### Example prompts

- "Run bol.com NL Catalog Product Export for lego with maxItems 20, then retrieve only IDs, titles and prices."
- "Export Netherlands catalog cards for philips tandenborstel; report missing seller and rating values without guessing."

Start once and retain the returned run ID and storage IDs: they are metadata, not rows. `call-actor` waits at most 45 seconds. If still running, check that same run using `get-actor-run`, for example with 2/4/8-second backoff capped at 10 seconds and a 120-second total deadline. Set client timeouts above the chosen server wait plus transport margin. Recover a known run after client timeout; do not restart just to poll. At deadline, report pending with its ID.

After success, retrieve bounded data using `get-dataset-items` and the returned dataset ID. Example consumer budget: pages of 20 source rows, at most 100 rows or 64 KiB of serialized UTF-8 content admitted to model context, whichever comes first. Apply byte limits host-side; disclose omitted oversized rows. If the client cannot intercept oversized responses, do not claim a hard byte guarantee. Track source offsets, report continuation offset and truncation, and keep full downloads outside model context. Failed-run rows are partial. Discovery/caching behavior depends on the client; no token-saving guarantee is made.

### Legality, responsible use and privacy

No AI model processes inputs or produces runtime output. Apify hosts run storage, logs, compute and managed proxy traffic; these infrastructure costs are included in Actor pricing, not a separate account requirement.

Run datasets and summaries remain in Apify storage under your account's retention settings until deleted. Delete unneeded runs and storage from Console/API. Browser cookies are ephemeral and are discarded when the browser closes; no persistent user profile or cross-run price-history database is created. Contact us through the Actor's Issues tab for normal support.

Use public information responsibly and comply with applicable law, source terms and your own obligations. Do not collect private account information or use this Actor to bypass authentication. This independent tool is not affiliated with bol.com.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days.

### FAQ and troubleshooting

**Why are some products not literal keyword matches?** bol.com can return fuzzy matches, suggestions and sponsored cards. This Actor exports the source search cards without inventing a stricter filter.

**Why are seller or ratings missing?** Fields remain null if the card does not expose them. The Actor does not fetch details to fill gaps.

**Can I get reviews, EANs or every offer?** No. This product covers NL catalog cards only. Review counts are summaries, not review records.

**Why did I receive fewer products than requested?** The global limit is a ceiling, not a guarantee. Source exhaustion, page caps, duplicates or a failed run can reduce output; check `SUMMARY` and run status.

**What should I do after a challenge failure?** The run already attempted bounded identity rotation. Review the error and try later rather than launching a tight retry loop.

### Related workflows

This is a standalone bol.com catalog export. Other marketplace exports are independent sources, not substitutes for bol.com coverage. See the [automation-lab Actor collection](https://apify.com/automation-lab) for additional source-specific tools.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/bol-com-catalog-product-export/changelog.md

# Actor input Schema

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

1–10 nonempty keyword queries, trimmed and processed in order. Exact duplicate queries are removed. bol.com applies its own relevance, fuzzy matching and sponsored placements; this is not a title substring or exact-phrase filter. Results are deduplicated globally by product ID; first occurrence wins.

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

Global limit across all queries after product-ID deduplication, 1–500 (default 30). Earlier queries consume the limit first. Zero/unlimited is unsupported. Page caps or source exhaustion may return fewer products.

## `maxPagesPerQuery` (type: `integer`):

Fetch at most 1–20 catalog pages for each query (default 5), stopping sooner at the global product limit or when the source exposes no next page. Includes sponsored cards. A page can be retried up to three total fresh-identity attempts; no promise of exhaustive catalog coverage.

## Actor input object example

```json
{
  "queries": [
    "lego"
  ],
  "maxItems": 20,
  "maxPagesPerQuery": 5
}
```

# Actor output Schema

## `overview` (type: `string`):

Exported catalog products with listed prices, seller names and exposed rating summaries.

# 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": [
        "lego"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/bol-com-catalog-product-export").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": ["lego"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/bol-com-catalog-product-export").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 '{
  "queries": [
    "lego"
  ],
  "maxItems": 20
}' |
apify call automation-lab/bol-com-catalog-product-export --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/bol-com-catalog-product-export"
        }
    }
}
```

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/K3Ix1vYNNR7hQLIwD/builds/1GxFPbmHVlyvn9Pfq/openapi.json
