{
  "openapi": "3.0.1",
  "info": {
    "title": "Bol.com Scraper - Prices, Price History & AI Analysis",
    "description": "Only Bol.com scraper with cross-run price-tier history — tracks standard, Select & refurbished prices across scheduled runs, flags drops >=5%. Playwright-based, auto-routes to BE mirror for near-zero 403s, bypasses WAF via Retailer API. 5 LLM providers for AI market briefs.",
    "version": "1.8",
    "x-build-id": "la2IX1IzHafuVoaaj"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/harvestlab~bol-com-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-harvestlab-bol-com-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/harvestlab~bol-com-scraper/runs": {
      "post": {
        "operationId": "runs-sync-harvestlab-bol-com-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/harvestlab~bol-com-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-harvestlab-bol-com-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",
        "properties": {
          "bolClientId": {
            "title": "Bol.com API Client ID",
            "type": "string",
            "description": "Optional: Client ID from Bol.com Retailer API. If provided with Client Secret, uses the official API instead of browser scraping (faster, more reliable)."
          },
          "bolClientSecret": {
            "title": "Bol.com API Client Secret",
            "type": "string",
            "description": "Optional: Client Secret from Bol.com Retailer API. Required together with Client ID."
          },
          "mode": {
            "title": "Scraping Mode",
            "enum": [
              "search",
              "product_url",
              "bestsellers"
            ],
            "type": "string",
            "description": "How to discover products: 'Search by Keyword' (uses the searchQuery field, e.g. 'PlayStation 5'), 'Scrape Product URLs' (pass direct /p/ URLs via productUrls), or 'Bestsellers' (scrape Bol.com's top-sellers list, optionally scoped via category slug). Pick 'search' for keyword discovery, 'product_url' when you already have ASINs/URLs, 'bestsellers' for catalog-wide trending data.",
            "default": "search"
          },
          "searchQuery": {
            "title": "Search Query",
            "type": "string",
            "description": "Product keywords to search on Bol.com (e.g. 'PlayStation 5', 'Lego Technic', 'Philips airfryer', 'yoga mat'). Only used in 'Search by Keyword' mode — ignored for 'product_url' and 'bestsellers' modes. Supports Dutch or English terms; Bol.com localizes matching.",
            "default": "PlayStation 5"
          },
          "query": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "q": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "productUrls": {
            "title": "Product URLs",
            "type": "array",
            "description": "List of Bol.com product URLs to scrape (e.g. https://www.bol.com/nl/nl/p/...). Used in 'Scrape Product URLs' mode.",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Bestseller Category",
            "type": "string",
            "description": "Optional Bol.com category slug for bestsellers (e.g. 'elektronica' = electronics, 'boeken' = books, 'speelgoed' = toys, 'wonen-en-keuken' = home & kitchen, 'sport-en-outdoor'). Leave empty for overall bestsellers. Only used in 'Bestsellers' mode."
          },
          "maxProducts": {
            "title": "Max Products",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Maximum number of products to scrape. Bol.com shows ~24 per search page. Start with 10-25 to test — PDP mode occasionally throttles; list-mode (fetchDetails=false) is more reliable.",
            "default": 25
          },
          "sortBy": {
            "title": "Sort Order",
            "enum": [
              "relevance",
              "popularity",
              "price_asc",
              "price_desc",
              "rating",
              "newest"
            ],
            "type": "string",
            "description": "How Bol.com should sort the search results. Only used in 'Search by Keyword' mode; ignored for 'product_url' and 'bestsellers'. 'Relevance' is the Bol.com default; 'Price low-to-high' and 'Price high-to-low' are great for price monitoring; 'Rating' surfaces top-rated products first; 'Newest' prioritises recently released products.",
            "default": "relevance"
          },
          "maxItems": {
            "title": "Max Items (CLI alias)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "CLI alias for maxProducts. Hidden from Console form."
          },
          "fetchDetails": {
            "title": "Fetch Product Details (slower, may fail)",
            "type": "boolean",
            "description": "If enabled, fetches each product's detail page to enrich results with EAN, description, specifications, extra images, AND the full price-tier matrix (Bol.com Select member price + refurbished / tweedehands price when offered). Throughput is ~20 seconds per PDP due to polite delays and retries. Leave OFF to get fast, reliable card data (title, price, rating, seller, image, availability, Select/refurbished badges) from the search results page only. Recommended ON when you need alternative_prices populated with Select / refurbished amounts — OFF for fast price monitoring and catalog discovery.",
            "default": false
          },
          "country": {
            "title": "Country",
            "enum": [
              "nl",
              "be"
            ],
            "type": "string",
            "description": "Choose the Bol.com country store to scrape. DEFAULT: 'be' (Belgium mirror). As of Cycle 71 (April 2026), bol.com/nl blocks both list-mode and PDP requests with ~100% 403s even via residential proxy, while bol.com/be serves the same unified catalog with a much weaker WAF. The actor auto-routes everything to 'be' unless you explicitly pick 'nl' here. Only choose 'nl' if you specifically need NL-exclusive pricing/inventory (rare — most SKUs are shared)."
          },
          "watchMode": {
            "title": "Enable Price-Tier History (watch mode)",
            "type": "boolean",
            "description": "Track prices across runs using a named key-value store (`bol-com-price-history`). Each product gets a `price_tier_trend` field comparing current standard/Select/refurbished prices to the prior snapshot — `standard_delta_pct`, `select_delta_pct`, `refurb_delta_pct`, `standard_direction` (up/down/flat), `first_seen_at`, `history_sample_count`. 90-snapshot FIFO per product. Designed for scheduled runs (daily/hourly): seed on the first run, get deltas on every subsequent run. Enables the `price-drop-detected` event ($0.005) — billed only when the standard price falls by 5% or more AND prior history exists. No extra HTTP calls, no extra charges on the first run. Leave OFF for one-shot snapshot scrapes.",
            "default": false
          },
          "enableAiAnalysis": {
            "title": "Enable AI Analysis",
            "type": "boolean",
            "description": "Generate AI-powered price and market analysis from the scraped products. Requires an API key for your chosen LLM provider.",
            "default": false
          },
          "llmProvider": {
            "title": "LLM Provider",
            "enum": [
              "openrouter",
              "anthropic",
              "google",
              "openai",
              "ollama"
            ],
            "type": "string",
            "description": "AI backend for price/market analysis. 'OpenRouter' (default) is cheapest — Gemini Flash via OpenRouter runs ~$0.001 per analysis. 'Anthropic' uses Claude direct, 'Google AI' uses Gemini direct, 'OpenAI' uses GPT-4o mini, 'Ollama' runs on your own server (no API cost). Each provider needs its own API key field below.",
            "default": "openrouter"
          },
          "llmModel": {
            "title": "LLM Model",
            "type": "string",
            "description": "Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama)."
          },
          "openrouterApiKey": {
            "title": "OpenRouter API Key",
            "type": "string",
            "description": "Your OpenRouter API key. Get one at openrouter.ai/keys"
          },
          "anthropicApiKey": {
            "title": "Anthropic API Key",
            "type": "string",
            "description": "Your Anthropic API key. Get one at console.anthropic.com"
          },
          "googleApiKey": {
            "title": "Google AI API Key",
            "type": "string",
            "description": "API key for Google AI (Gemini). Get one at https://aistudio.google.com/app/apikey"
          },
          "openaiApiKey": {
            "title": "OpenAI API Key",
            "type": "string",
            "description": "API key from platform.openai.com (required if using OpenAI provider)"
          },
          "ollamaBaseUrl": {
            "title": "Ollama Base URL",
            "type": "string",
            "description": "Base URL for Ollama API. Default: http://localhost:11434"
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Proxy settings. Bol.com aggressively blocks datacenter exits with 403 — RESIDENTIAL (default) is strongly recommended. Datacenter proxy users will see near-100% 403s even in list mode. You may override the default, but expect failures on non-residential groups."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}