{
  "openapi": "3.0.1",
  "info": {
    "title": "PcComponentes Scraper - Prices, Discounts, Variants & Reviews",
    "description": "Scrape PcComponentes (pccomponentes.com) products: current price plus strike-through reference-price discount, configuration variants with price and availability, brand, category, and reviews with rating. Search by keyword/category or paste product and listing links.",
    "version": "1.0",
    "x-build-id": "eupsqpfyavuKHRGmY"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~pccomponentes-com-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-pccomponentes-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/abotapi~pccomponentes-com-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-pccomponentes-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/abotapi~pccomponentes-com-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-pccomponentes-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "'search' finds products by keyword and/or a real pccomponentes.com category (e.g. 'portatiles', 'placas-base'), with real site filters and sort. 'url' scrapes any product or category listing page URL you paste, walking pagination forward automatically.",
            "default": "search"
          },
          "searchTerm": {
            "title": "Search keyword",
            "type": "string",
            "description": "Free-text keyword, e.g. 'portatil gaming' or 'monitor 27 pulgadas'. Uses the site's own product search. Leave empty and use Category below to browse a category instead. With no keyword, no More search keywords and no Category, a search-mode run searches the example keyword portatil instead of returning nothing."
          },
          "queries": {
            "title": "More search keywords (optional)",
            "uniqueItems": true,
            "type": "array",
            "description": "Several keywords in one run, e.g. 'portatil', 'monitor 27', 'tarjeta grafica'. Each is searched with the site's own product search, in order, together with Search keyword above. Max products total caps the whole run; a product matched by two keywords is returned once.",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Category (used only when Search keyword is empty)",
            "type": "string",
            "description": "A real pccomponentes.com category path exactly as it appears in the site's own URLs, e.g. 'portatiles', 'monitores', 'placas-base'. Ignored when Search keyword is set (keyword search and category browsing are two different site features)."
          },
          "brands": {
            "title": "Brands",
            "uniqueItems": true,
            "type": "array",
            "description": "Only return products from these brands, e.g. 'Lenovo', 'HP', 'Asus'. Match the exact brand name as shown on the site. Leave empty for all brands.",
            "items": {
              "type": "string"
            }
          },
          "minPrice": {
            "title": "Minimum price (EUR)",
            "type": "number",
            "description": "Only return products priced at or above this amount, in euros."
          },
          "maxPrice": {
            "title": "Maximum price (EUR)",
            "type": "number",
            "description": "Only return products priced at or below this amount, in euros."
          },
          "specialsOnly": {
            "title": "Discounted items only",
            "type": "boolean",
            "description": "Only return products currently showing a genuine strike-through discount against the site's own reference price (verified live against real price data -- never a guess). Combines with the keyword/category above.",
            "default": false
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "RELEVANCE",
              "PRICE_ASC",
              "PRICE_DESC",
              "DISCOUNT",
              "TOP_RATED",
              "NEWEST"
            ],
            "type": "string",
            "description": "Sort order. Category browsing uses the site's own server-side sort. The site's keyword search has no sort option, so for a keyword search the matching products (up to Max pages per search) are collected first and sorted by this actor before the first Max products total are returned; Relevance keeps the site's own ranking. In URL mode this input is only a fallback: a pasted category URL's own sort parameter, if present, always wins.",
            "default": "RELEVANCE"
          },
          "urls": {
            "title": "URLs to scrape",
            "uniqueItems": true,
            "type": "array",
            "description": "Paste one or more pccomponentes.com product pages, category listing pages (/categorias/<slug>, optionally with ?sort= or ?page=) or keyword search links (/buscar/?query=). Pagination continues forward automatically from any ?page= already in the URL. Filter fields above are ignored in this mode. An empty list stops the run with an input message.",
            "default": [
              "https://www.pccomponentes.com/categorias/portatiles",
              "https://www.pccomponentes.com/categorias/portatiles?sort=price_asc",
              "https://www.pccomponentes.com/buscar/?query=portatil"
            ],
            "items": {
              "type": "string"
            }
          },
          "fetchDetails": {
            "title": "Fetch full product detail",
            "type": "boolean",
            "description": "Adds full description, EAN/reference, category breadcrumb, complete image gallery, and every configuration variant (each with its own price and availability) from the product page. Current price, was-price/discount, rating and card image are already included without this toggle. Billing: a row whose product page loaded and yielded these details carries one detail-and-review enrichment charge (also charged for Fetch reviews, never twice per product).",
            "default": false
          },
          "fetchReviews": {
            "title": "Fetch reviews",
            "type": "boolean",
            "description": "Fetch the product's own reviews (not a third-party vendor): overall rating, total rating count, and the page's most recent individual written reviews (rating, body, author, date) -- pccomponentes.com itself only ever surfaces up to its 15 most recent written reviews per product; the rating and counts reflect the full history. Products with no reviews simply return an empty list. Billing: when on, each returned full row whose product page loaded carries one detail-and-review enrichment charge, including a product with no written reviews; a page that could not be loaded is not charged.",
            "default": true
          },
          "maxReviewsPerProduct": {
            "title": "Max reviews per product",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on written reviews fetched per product when 'Fetch reviews' is on, up to the site's own per-page limit.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many result pages per search/category/URL entry. Leave empty for no explicit limit: the run stops at Max products total or at an internal hard cap of 200 pages per entry."
          },
          "maxItems": {
            "title": "Max products total",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on total products returned across every search/category/URL entry. 0 = unlimited (still bounded by the internal 200-page hard cap per entry).",
            "default": 20
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "This site challenges ordinary datacenter connections; residential connections are served more reliably. If the selected connection is refused, the actor continues on a backup connection when one is available.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large pull without returning or charging for products already collected there. Use this after an interrupted run. For recurring monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs return only NEW, UPDATED and REAPPEARED products. By default any change to the product record counts as UPDATED (price, reference price, discount, availability, name, rating, rating count, variants, details), while the review texts, the image addresses and the scrape time never do; choose Price and availability only below to react to price and stock moves alone. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, filter and detail setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search, filters and detail settings, so different searches never mix state with each other. With Incremental changes on and your own State key, search mode needs a keyword, More search keywords or a Category; otherwise the run stops with an input message."
          },
          "emitUnchanged": {
            "title": "Emit unchanged products (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired products (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return products that were found in earlier runs but are no longer in the tracked listing, marked EXPIRED. This means the listing no longer shows them, not that they are out of stock or delisted; use the availability fields for stock. Only produced once a run has read the whole tracked listing, so never when Max products, Max pages or a failed page cut it short, when a pasted link starts at page 2 or later, or when Resume was used. This returns, and bills, extra rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "changeScope": {
            "title": "What counts as a change (incremental mode only)",
            "enum": [
              "all",
              "priceAndStock"
            ],
            "type": "string",
            "description": "All fields (default): any change to the product record, except the always-ignored review texts, image addresses and scrape time, returns an UPDATED row. Price and availability only: only price, reference price, discount, on-sale flag and availability changes (including each variant's price and availability) return an UPDATED row; changes to names, ratings, descriptions, images or other details never do.",
            "default": "all"
          },
          "compactUpdates": {
            "title": "Compact update rows (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Works with Price and availability only. When on, UPDATED and EXPIRED rows are short: product id, url, name, current price and availability, plus priceChanges and variantChanges showing the old and new value of each moved field. NEW rows always carry the complete product record. Compact rows carry no details or reviews, so the detail and review enrichment is not billed for them.",
            "default": false
          },
          "expireAfterMissedScans": {
            "title": "Expire after N missed full scans (incremental mode only)",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Only used with Emit expired products. A product is marked EXPIRED only after it has been missing from this many complete scans in a row (default 1). Raise it (for example 3) so a product that briefly drops out of a listing is not reported as gone. A product that comes back resets the count.",
            "default": 1
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Incremental mode only. Fields whose changes do not count as an update: a change in them alone leaves the product UNCHANGED and they are not listed in changedFields. They are still returned in every row. Use a dotted path for a nested field, for example variants.name. The review texts, the image fields (image, images), the search label (query) and the scrape time (scraped_at) are always ignored; a new review still shows through reviewCount and rating. Add more field names here to ignore them as well, for example rating.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify -> Settings -> Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}