scrapeunblocker-mcp 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1005 -65
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { APIError, ScrapeUnblockerClient, errorForStatus } from "scrapeunblocker
10
10
  import { z } from "zod";
11
11
 
12
12
  // src/plugin-catalog.ts
13
- var CATEGORIES = ["Travel", "Google", "Search engines", "E-commerce", "Classifieds & Resale", "Groceries", "Real estate", "Vehicles", "Jobs", "Reviews & Companies", "Local & Maps", "Apps", "Video & Music", "SEO & Ads"];
13
+ var CATEGORIES = ["Travel", "Google", "AI", "Search engines", "E-commerce", "Classifieds & Resale", "Groceries", "Real estate", "Vehicles", "Jobs", "Reviews & Companies", "Local & Maps", "Apps", "Video & Music", "SEO & Ads"];
14
14
  var PLUGINS = [
15
15
  {
16
16
  "name": "skyscanner_flights",
@@ -24,96 +24,96 @@ var PLUGINS = [
24
24
  "name": "origin",
25
25
  "type": "string",
26
26
  "required": false,
27
- "description": ""
27
+ "description": "Origin airport or city name, e.g. London. Give this or `origin_entity`."
28
28
  },
29
29
  {
30
30
  "name": "dest",
31
31
  "type": "string",
32
32
  "required": false,
33
- "description": ""
33
+ "description": "Destination airport or city name. Give this or `dest_entity`."
34
34
  },
35
35
  {
36
36
  "name": "origin_entity",
37
37
  "type": "string",
38
38
  "required": false,
39
- "description": ""
39
+ "description": "Skyscanner entity ID of the origin; skips the name lookup and overrides `origin`."
40
40
  },
41
41
  {
42
42
  "name": "dest_entity",
43
43
  "type": "string",
44
44
  "required": false,
45
- "description": ""
45
+ "description": "Skyscanner entity ID of the destination; skips the name lookup and overrides `dest`."
46
46
  },
47
47
  {
48
48
  "name": "origin_iata",
49
49
  "type": "string",
50
50
  "required": false,
51
- "description": ""
51
+ "description": "Origin IATA code, e.g. LHR. Optional; resolved from the origin when omitted."
52
52
  },
53
53
  {
54
54
  "name": "dest_iata",
55
55
  "type": "string",
56
56
  "required": false,
57
- "description": ""
57
+ "description": "Destination IATA code. Optional; resolved from the destination when omitted."
58
58
  },
59
59
  {
60
60
  "name": "depart_date",
61
61
  "type": "string",
62
62
  "required": false,
63
- "description": ""
63
+ "description": "Departure date, YYYY-MM-DD. Required."
64
64
  },
65
65
  {
66
66
  "name": "return_date",
67
67
  "type": "string",
68
68
  "required": false,
69
- "description": ""
69
+ "description": "Return date, YYYY-MM-DD. Omit for a one-way search."
70
70
  },
71
71
  {
72
72
  "name": "adults",
73
73
  "type": "integer",
74
74
  "required": false,
75
- "description": "",
75
+ "description": "Passengers, 1-9.",
76
76
  "default": 1
77
77
  },
78
78
  {
79
79
  "name": "cabin",
80
80
  "type": "string",
81
81
  "required": false,
82
- "description": "",
82
+ "description": "Cabin class: economy, premium_economy, business or first.",
83
83
  "default": "economy"
84
84
  },
85
85
  {
86
86
  "name": "currency",
87
87
  "type": "string",
88
88
  "required": false,
89
- "description": "",
89
+ "description": "Price currency, e.g. GBP, EUR, USD.",
90
90
  "default": "GBP"
91
91
  },
92
92
  {
93
93
  "name": "market",
94
94
  "type": "string",
95
95
  "required": false,
96
- "description": "",
96
+ "description": "Skyscanner market (country code), e.g. UK, US, ES.",
97
97
  "default": "UK"
98
98
  },
99
99
  {
100
100
  "name": "locale",
101
101
  "type": "string",
102
102
  "required": false,
103
- "description": "",
103
+ "description": "Result language, e.g. en-GB, es-ES.",
104
104
  "default": "en-GB"
105
105
  },
106
106
  {
107
107
  "name": "proxy_country",
108
108
  "type": "string",
109
109
  "required": false,
110
- "description": ""
110
+ "description": "Two-letter ISO country code (e.g. `de`, `us`) of the exit IP, so the site serves that country's prices, language and content. Omit it and the country is picked for you. An unsupported code answers 400 with the list of available countries."
111
111
  },
112
112
  {
113
113
  "name": "max_polls",
114
114
  "type": "integer",
115
115
  "required": false,
116
- "description": "",
116
+ "description": "How many times to poll Skyscanner for more results before answering, 1-20. More polls give fuller results and a slower call.",
117
117
  "default": 8
118
118
  }
119
119
  ]
@@ -130,79 +130,79 @@ var PLUGINS = [
130
130
  "name": "destination",
131
131
  "type": "string",
132
132
  "required": false,
133
- "description": ""
133
+ "description": "City or place name, e.g. London. Give this or `destination_entity`."
134
134
  },
135
135
  {
136
136
  "name": "destination_entity",
137
137
  "type": "string",
138
138
  "required": false,
139
- "description": ""
139
+ "description": "Skyscanner entity ID of the destination; skips the name lookup and overrides `destination`."
140
140
  },
141
141
  {
142
142
  "name": "checkin",
143
143
  "type": "string",
144
144
  "required": false,
145
- "description": ""
145
+ "description": "Check-in date, YYYY-MM-DD. Required."
146
146
  },
147
147
  {
148
148
  "name": "checkout",
149
149
  "type": "string",
150
150
  "required": false,
151
- "description": ""
151
+ "description": "Check-out date, YYYY-MM-DD. Required."
152
152
  },
153
153
  {
154
154
  "name": "adults",
155
155
  "type": "integer",
156
156
  "required": false,
157
- "description": "",
157
+ "description": "Guests, 1-16.",
158
158
  "default": 2
159
159
  },
160
160
  {
161
161
  "name": "rooms",
162
162
  "type": "integer",
163
163
  "required": false,
164
- "description": "",
164
+ "description": "Rooms, 1-8.",
165
165
  "default": 1
166
166
  },
167
167
  {
168
168
  "name": "currency",
169
169
  "type": "string",
170
170
  "required": false,
171
- "description": "",
171
+ "description": "Price currency, e.g. GBP, EUR, USD.",
172
172
  "default": "GBP"
173
173
  },
174
174
  {
175
175
  "name": "market",
176
176
  "type": "string",
177
177
  "required": false,
178
- "description": "",
178
+ "description": "Skyscanner market (country code), e.g. UK, US, ES.",
179
179
  "default": "UK"
180
180
  },
181
181
  {
182
182
  "name": "locale",
183
183
  "type": "string",
184
184
  "required": false,
185
- "description": "",
185
+ "description": "Result language, e.g. en-GB, es-ES.",
186
186
  "default": "en-GB"
187
187
  },
188
188
  {
189
189
  "name": "proxy_country",
190
190
  "type": "string",
191
191
  "required": false,
192
- "description": ""
192
+ "description": "Two-letter ISO country code (e.g. `de`, `us`) of the exit IP, so the site serves that country's prices, language and content. Omit it and the country is picked for you. An unsupported code answers 400 with the list of available countries."
193
193
  },
194
194
  {
195
195
  "name": "max_polls",
196
196
  "type": "integer",
197
197
  "required": false,
198
- "description": "",
198
+ "description": "How many times to poll Skyscanner for more results before answering, 1-20. More polls give fuller results and a slower call.",
199
199
  "default": 8
200
200
  },
201
201
  {
202
202
  "name": "max_results",
203
203
  "type": "integer",
204
204
  "required": false,
205
- "description": "",
205
+ "description": "How many hotels to return, 1-300. Results come in pages of about 35, so more results take longer.",
206
206
  "default": 30
207
207
  }
208
208
  ]
@@ -225,7 +225,7 @@ var PLUGINS = [
225
225
  "name": "host",
226
226
  "type": "string",
227
227
  "required": false,
228
- "description": "",
228
+ "description": "Skyscanner site the search runs on, e.g. www.skyscanner.es. Ignored when `url` is given.",
229
229
  "default": "www.skyscanner.net"
230
230
  },
231
231
  {
@@ -266,7 +266,7 @@ var PLUGINS = [
266
266
  "name": "dropoff_entity",
267
267
  "type": "string",
268
268
  "required": false,
269
- "description": ""
269
+ "description": "Skyscanner dropoff entity ID; overrides `dropoff`. Defaults to the pickup location."
270
270
  },
271
271
  {
272
272
  "name": "pickup",
@@ -278,7 +278,7 @@ var PLUGINS = [
278
278
  "name": "dropoff",
279
279
  "type": "string",
280
280
  "required": false,
281
- "description": ""
281
+ "description": "Dropoff place name. Defaults to the pickup location."
282
282
  },
283
283
  {
284
284
  "name": "pickup_datetime",
@@ -296,33 +296,33 @@ var PLUGINS = [
296
296
  "name": "proxy_country",
297
297
  "type": "string",
298
298
  "required": false,
299
- "description": ""
299
+ "description": "Two-letter ISO country code (e.g. `de`, `us`) of the exit IP, so the site serves that country's prices, language and content. Omit it and the country is picked for you. An unsupported code answers 400 with the list of available countries."
300
300
  },
301
301
  {
302
302
  "name": "warmup_url",
303
303
  "type": "string",
304
304
  "required": false,
305
- "description": ""
305
+ "description": "Skyscanner page opened before the quotes are fetched. Defaults to one derived from the search; rarely needed."
306
306
  },
307
307
  {
308
308
  "name": "max_polls",
309
309
  "type": "integer",
310
310
  "required": false,
311
- "description": "",
311
+ "description": "How many times to poll Skyscanner for more results before answering, 1-20. More polls give fuller results and a slower call.",
312
312
  "default": 8
313
313
  },
314
314
  {
315
315
  "name": "poll_interval",
316
316
  "type": "number",
317
317
  "required": false,
318
- "description": "",
318
+ "description": "Seconds between polls, 0-10.",
319
319
  "default": 2
320
320
  },
321
321
  {
322
322
  "name": "settle",
323
323
  "type": "number",
324
324
  "required": false,
325
- "description": "",
325
+ "description": "Seconds to stay on the warm-up page before the first fetch, 0-20.",
326
326
  "default": 5
327
327
  }
328
328
  ]
@@ -1399,6 +1399,102 @@ var PLUGINS = [
1399
1399
  }
1400
1400
  ]
1401
1401
  },
1402
+ {
1403
+ "name": "google_ai_mode",
1404
+ "title": "Scrape a Google AI Mode answer",
1405
+ "category": "Google",
1406
+ "path": "/search/google-ai-mode",
1407
+ "fixed": {},
1408
+ "description": "Asks Google AI Mode (the `udm=50` AI Mode tab, not the AI Overview on a results page) the question `q` and returns its full answer as JSON: `answer.text` (plain text), `answer.markdown` and `answer.blocks` (paragraphs, headings, lists, tables and code, in order), `references` (the pages the answer cites: `title`, `url`, `domain`, `source`, `snippet`), `links` (links written into the answer text) and `followUps` (the follow-up questions Google closes the answer with, if any). Set `proxy_country` to ask from a market - the Google market (`gl`) follows it - and `hl` for the answer's language. Answers differ between identical requests, as they do for a person.",
1409
+ "params": [
1410
+ {
1411
+ "name": "q",
1412
+ "type": "string",
1413
+ "required": true,
1414
+ "description": "The question to ask Google AI Mode, e.g. 'how to learn python fast'."
1415
+ },
1416
+ {
1417
+ "name": "proxy_country",
1418
+ "type": "string",
1419
+ "required": false,
1420
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). The Google market (`gl`) follows it unless `gl` is set."
1421
+ },
1422
+ {
1423
+ "name": "gl",
1424
+ "type": "string",
1425
+ "required": false,
1426
+ "description": "Optional Google market override (ISO-2, e.g. 'us', 'de'). Default: `proxy_country`, else 'us'."
1427
+ },
1428
+ {
1429
+ "name": "hl",
1430
+ "type": "string",
1431
+ "required": false,
1432
+ "description": "Language Google answers in, e.g. 'en', 'de', 'pt-BR'. Default 'en'."
1433
+ }
1434
+ ]
1435
+ },
1436
+ {
1437
+ "name": "google_lens",
1438
+ "title": "Search Google Lens with an image URL",
1439
+ "category": "Google",
1440
+ "path": "/images/google-lens",
1441
+ "fixed": {},
1442
+ "description": "Runs a Google Lens search for the image at `url` and returns its visual matches as JSON (usually ~60). Every match carries `title`, `url` (the page the image is on), `domain`, `source` (site name), `imageUrl` (the matching image), `thumbnailUrl`, `width`, `height` and `position`; product matches add `price` and `currency` (and `product` details) when Google has them, and `priceText`, `rating` and `reviews` as the tile shows them. `relatedSearches` lists what Lens recognised in the image (e.g. 'Eiffel Tower', with its Knowledge Graph id) and `aiOverview` is Google's own description of the image when it is ready in time (else null). Shopping matches follow the country the request comes from - set `proxy_country` for a market (a US request is served from a European exit, where Google loads Lens matches; `proxyCountry` in the response says which).",
1443
+ "params": [
1444
+ {
1445
+ "name": "url",
1446
+ "type": "string",
1447
+ "required": true,
1448
+ "description": "Public http(s) URL of the image to search with, e.g. a product photo. Google fetches the image itself."
1449
+ },
1450
+ {
1451
+ "name": "proxy_country",
1452
+ "type": "string",
1453
+ "required": false,
1454
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Shopping matches and prices follow the country Google sees the request from."
1455
+ },
1456
+ {
1457
+ "name": "gl",
1458
+ "type": "string",
1459
+ "required": false,
1460
+ "description": "Optional Google market override (ISO-2). Default: `proxy_country`, else 'us'."
1461
+ },
1462
+ {
1463
+ "name": "hl",
1464
+ "type": "string",
1465
+ "required": false,
1466
+ "description": "Google UI language, e.g. 'en', 'de'. Default 'en'."
1467
+ },
1468
+ {
1469
+ "name": "max_results",
1470
+ "type": "integer",
1471
+ "required": false,
1472
+ "description": "Optional cap on the visual matches returned (1-100; default: all, usually ~60)."
1473
+ }
1474
+ ]
1475
+ },
1476
+ {
1477
+ "name": "gemini",
1478
+ "title": "Ask Google Gemini and get its answer and cited sources",
1479
+ "category": "AI",
1480
+ "path": "/ai/gemini",
1481
+ "fixed": {},
1482
+ "description": "Asks Google Gemini (gemini.google.com, signed out) one question and returns `answer` (plain text) and `answerMarkdown`, `citations` (pages cited inline: `position`, `title`, `url`, `domain`, `siteName`, `description`, `citedText` - the answer sentences that page backs - and `firstCitedAt`, the character offset of the first of them), `sources` (pages Gemini consulted when it searched the web: `position`, `title`, `url`, `domain`), `webSearch` (whether it searched the web), `followUpPrompts` (`label`, `prompt`), `richBlocks` (cards Gemini drew that have no text, e.g. a sports score or image strip, left out of the answer), `model` (the model label the app shows), `location` and `locationCountry` (where Gemini placed the visitor), `complete` and `conversationId`. `country` asks from that country. Answers vary between identical calls, as they do for people. One unit per call.",
1483
+ "params": [
1484
+ {
1485
+ "name": "prompt",
1486
+ "type": "string",
1487
+ "required": true,
1488
+ "description": "The question to ask Gemini, as a user would type it, e.g. 'best CRM for small business' (max 4000 characters). Each call starts a new conversation."
1489
+ },
1490
+ {
1491
+ "name": "country",
1492
+ "type": "string",
1493
+ "required": false,
1494
+ "description": "Two-letter country code to ask from, e.g. US, GB, DE. Gemini answers for where it locates the visitor (local results, currency, language defaults); `locationCountry` in the answer says where it placed this call. Leave blank for any European location."
1495
+ }
1496
+ ]
1497
+ },
1402
1498
  {
1403
1499
  "name": "bing_search",
1404
1500
  "title": "Search Bing",
@@ -1811,6 +1907,111 @@ var PLUGINS = [
1811
1907
  }
1812
1908
  ]
1813
1909
  },
1910
+ {
1911
+ "name": "amazon_offers",
1912
+ "title": "Scrape every offer (all sellers) for an Amazon product",
1913
+ "category": "E-commerce",
1914
+ "path": "/marketplace/amazon-offers",
1915
+ "fixed": {},
1916
+ "description": "Returns the offers Amazon lists for a product under \"All buying options\", as JSON. Each offer has the seller (`sellerName`, `sellerId`, `sellerUrl`, `sellerRating`, `sellerRatingCount`, `sellerPositivePercent`), `price` + `currency`, `listPrice` and `savingsPercent`, `shippingPrice` and `totalPrice`, `condition` (as Amazon words it) with `conditionType` (new, used, collectible, refurbished) and the seller's `conditionNote`, `delivery` / `deliveryDate`, `alternativeDelivery` (the faster or Prime-member option Amazon also offers), `shipsFrom`, `soldByAmazon`, `fulfilledByAmazon`, `prime`, the `offerId` and a `buyBoxWinner` flag. The response also carries the product `title`, `rating`, `reviewCount`, `image` and `totalOffers`. Page 1 starts with the Buy Box (featured) offer, also returned as `buyBox`; Amazon shows it whatever filter is set. Amazon lists 10 other offers per page: follow `nextPage`, or read up to 5 pages in one call with `pages`. Filter with `condition`, `free_shipping` and `prime`. `shippingPrice` is 0 for free delivery and null when Amazon shows no delivery promise for the location. `proxy_country` defaults to the marketplace's home country so prices and delivery are the ones a local shopper sees; the proxy that served the request is reported as `exitCountry` and `exitProvider`.",
1917
+ "params": [
1918
+ {
1919
+ "name": "asin",
1920
+ "type": "string",
1921
+ "required": false,
1922
+ "description": "Amazon product id (10-char ASIN, e.g. 'B07VGRJDFY'; books use their ISBN-10). Give either `asin` (with `marketplace`) or a product `url`."
1923
+ },
1924
+ {
1925
+ "name": "url",
1926
+ "type": "string",
1927
+ "required": false,
1928
+ "description": "Full Amazon product url, e.g. 'https://www.amazon.de/dp/1847941834'. The ASIN and marketplace are read from it."
1929
+ },
1930
+ {
1931
+ "name": "marketplace",
1932
+ "type": "string",
1933
+ "required": false,
1934
+ "description": "Regional Amazon site whose offers to list. Prices, sellers and delivery differ per marketplace. One of: amazon.com, amazon.co.uk, amazon.de, amazon.fr, amazon.it, amazon.es, amazon.nl, amazon.se, amazon.pl, amazon.com.be, amazon.com.tr, amazon.ca, amazon.com.mx, amazon.com.br, amazon.co.jp, amazon.in, amazon.ae, amazon.sa, amazon.sg, amazon.com.au.",
1935
+ "default": "amazon.com"
1936
+ },
1937
+ {
1938
+ "name": "condition",
1939
+ "type": "string",
1940
+ "required": false,
1941
+ "description": "Only offers in this condition: all, new, used, used_like_new, used_very_good, used_good, used_acceptable. Default 'all'.",
1942
+ "default": "all"
1943
+ },
1944
+ {
1945
+ "name": "free_shipping",
1946
+ "type": "boolean",
1947
+ "required": false,
1948
+ "description": "Only offers with free delivery.",
1949
+ "default": false
1950
+ },
1951
+ {
1952
+ "name": "prime",
1953
+ "type": "boolean",
1954
+ "required": false,
1955
+ "description": "Only Prime-eligible offers.",
1956
+ "default": false
1957
+ },
1958
+ {
1959
+ "name": "page",
1960
+ "type": "integer",
1961
+ "required": false,
1962
+ "description": "1-based offers page to start at. Amazon lists 10 offers per page (page 1 also carries the Buy Box offer and the product header).",
1963
+ "default": 1
1964
+ },
1965
+ {
1966
+ "name": "pages",
1967
+ "type": "integer",
1968
+ "required": false,
1969
+ "description": "How many consecutive pages to read in this call (1-5). Reading stops early at the last page. Each page delivered is billed as one request.",
1970
+ "default": 1
1971
+ },
1972
+ {
1973
+ "name": "proxy_country",
1974
+ "type": "string",
1975
+ "required": false,
1976
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Defaults to the marketplace's home country, so prices, shipping costs and delivery dates are the ones a local shopper sees."
1977
+ }
1978
+ ]
1979
+ },
1980
+ {
1981
+ "name": "amazon_seller",
1982
+ "title": "Scrape an Amazon seller profile",
1983
+ "category": "E-commerce",
1984
+ "path": "/marketplace/amazon-seller",
1985
+ "fixed": {},
1986
+ "description": "Returns an Amazon third-party seller's public profile as JSON: `name`, `logo`, `storefrontUrl`, the headline `rating`, `ratingCount` and `positivePercent` Amazon shows (the last 12 months, or lifetime for a seller with few recent ratings; `ratingPeriod` says which), and `feedbackSummary` for `30d`, `90d`, `12m` and `lifetime` - each with the average `rating`, `ratingCount`, `positivePercent` / `neutralPercent` / `negativePercent` (4-5, 3 and 1-2 stars), the matching counts and the 5..1-star histogram. Also `about` (the seller's own description), `businessName`, `businessAddress` (+ `businessAddressLines`), `businessDetails` (every row of Amazon's \"Detailed Seller Information\", e.g. business type, trade register and VAT number where the marketplace shows them), `contactUrl` and `recentFeedback` (each with `rating`, `text`, `author`, `date`, `struckThrough` and `amazonMessage` when Amazon took responsibility for the order). Identify the seller with `seller_id` (plus `marketplace`), e.g. the `sellerId` of an offer from `/marketplace/amazon-offers`, or with any Amazon `url` naming the seller. Ratings are per marketplace. Amazon's own retail sellers show no ratings; those fields are null.",
1987
+ "params": [
1988
+ {
1989
+ "name": "seller_id",
1990
+ "type": "string",
1991
+ "required": false,
1992
+ "description": "Amazon seller (merchant) id, e.g. 'A3PEV2IAOYFKM6' - the `sellerId` of an offer from /marketplace/amazon-offers. Give either `seller_id` (with `marketplace`) or a `url`."
1993
+ },
1994
+ {
1995
+ "name": "url",
1996
+ "type": "string",
1997
+ "required": false,
1998
+ "description": "Any Amazon url that names the seller: the profile ('https://www.amazon.de/sp?seller=A1J6G6R957S11K'), a storefront ('/s?me=...') or a sold-by link. The seller id and marketplace are read from it."
1999
+ },
2000
+ {
2001
+ "name": "marketplace",
2002
+ "type": "string",
2003
+ "required": false,
2004
+ "description": "Regional Amazon site the seller sells on. Ratings and feedback are per marketplace. One of: amazon.com, amazon.co.uk, amazon.de, amazon.fr, amazon.it, amazon.es, amazon.nl, amazon.se, amazon.pl, amazon.com.be, amazon.com.tr, amazon.ca, amazon.com.mx, amazon.com.br, amazon.co.jp, amazon.in, amazon.ae, amazon.sa, amazon.sg, amazon.com.au.",
2005
+ "default": "amazon.com"
2006
+ },
2007
+ {
2008
+ "name": "proxy_country",
2009
+ "type": "string",
2010
+ "required": false,
2011
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Optional: a seller profile is the same from every country, so by default any country is used."
2012
+ }
2013
+ ]
2014
+ },
1814
2015
  {
1815
2016
  "name": "walmart_search",
1816
2017
  "title": "Scrape Walmart product search",
@@ -2024,6 +2225,91 @@ var PLUGINS = [
2024
2225
  }
2025
2226
  ]
2026
2227
  },
2228
+ {
2229
+ "name": "costco_search",
2230
+ "title": "Scrape Costco product search",
2231
+ "category": "E-commerce",
2232
+ "path": "/marketplace/costco-search",
2233
+ "fixed": {},
2234
+ "description": "Searches Costco (costco.com, or costco.ca with `domain=ca`) for `query` and returns `products`: `productId`, `itemNumber`, `title`, `brand`, `url`, `image`, `price` (and `priceMax` for a price range), `wasPrice`, `currency`, `promotions`, `marketingStatement`, `rating`, `reviewCount`, `memberOnly`, `onlineOnly`, `warehouseOnly`, `badges`, `availability`, `inWarehouse`, `shipIt`, `buyableOnline`, `priceShownInCartOnly`, `model`, `features`, `category`, `categoryPath` and `variantCount`, plus `totalResults`. A keyword Costco sends to a category page (e.g. 'tv') returns that category, named in `redirectedTo`. `availability` is for the delivery location in `deliveryLocation`. Sort with `sort`, start at `page` and collect up to `max_results`.",
2235
+ "params": [
2236
+ {
2237
+ "name": "query",
2238
+ "type": "string",
2239
+ "required": true,
2240
+ "description": "What to search for, e.g. 'paper towels', 'kirkland coffee' or 'tv'."
2241
+ },
2242
+ {
2243
+ "name": "sort",
2244
+ "type": "string",
2245
+ "required": false,
2246
+ "description": "Result order: relevance, price_low, price_high, rating, newest, brand.",
2247
+ "default": "relevance"
2248
+ },
2249
+ {
2250
+ "name": "page",
2251
+ "type": "integer",
2252
+ "required": false,
2253
+ "description": "1-based results page to start from (24 products per page, as on costco.com).",
2254
+ "default": 1
2255
+ },
2256
+ {
2257
+ "name": "max_results",
2258
+ "type": "integer",
2259
+ "required": false,
2260
+ "description": "Products to collect from `page` on, 1-240. Up to 120 are billed as one request.",
2261
+ "default": 24
2262
+ },
2263
+ {
2264
+ "name": "include_out_of_stock",
2265
+ "type": "boolean",
2266
+ "required": false,
2267
+ "description": "Also return products that are out of stock (Costco hides them by default).",
2268
+ "default": false
2269
+ },
2270
+ {
2271
+ "name": "domain",
2272
+ "type": "string",
2273
+ "required": false,
2274
+ "description": "Costco storefront: com, ca ('com' is costco.com, 'ca' is costco.ca).",
2275
+ "default": "com"
2276
+ },
2277
+ {
2278
+ "name": "proxy_country",
2279
+ "type": "string",
2280
+ "required": false,
2281
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US'). Leave blank to let the API pick. Costco computes `availability` for the delivery location it derives from the visitor; it is named in `deliveryLocation`."
2282
+ }
2283
+ ]
2284
+ },
2285
+ {
2286
+ "name": "costco_product",
2287
+ "title": "Scrape a Costco product",
2288
+ "category": "E-commerce",
2289
+ "path": "/marketplace/costco-product",
2290
+ "fixed": {},
2291
+ "description": "Returns one Costco product (costco.com, or costco.ca with `domain=ca`) as JSON: `productId`, `itemNumber`, `title`, `brand`, `url`, `price`, `discount`, `currency`, `rating`, `reviewCount`, `memberOnly`, `onlineOnly`, `buyable`, `inWarehouse`, `shipIt`, `description`, `details`, `features`, `marketingStatement`, `promotionalStatement`, `shipping`, `manufacturer`, `manufacturerPartNumber`, `upc`, `minQuantity`, `maxQuantity`, `categoryPath`, `specifications`, `images`, `options` (e.g. every color and size) and `variants` (item number, option values, UPC). `product` takes a product id, an item number or a product link.",
2292
+ "params": [
2293
+ {
2294
+ "name": "product",
2295
+ "type": "string",
2296
+ "required": true,
2297
+ "description": "A Costco product id ('100361434'), item number ('17767') or product link (https://www.costco.com/p/-/kirkland-signature-colombian-coffee-dark-roast-3-lbs/100361434)."
2298
+ },
2299
+ {
2300
+ "name": "domain",
2301
+ "type": "string",
2302
+ "required": false,
2303
+ "description": "Costco storefront: com, ca ('com' is costco.com, 'ca' is costco.ca). Defaults to the link's storefront, else 'com'."
2304
+ },
2305
+ {
2306
+ "name": "proxy_country",
2307
+ "type": "string",
2308
+ "required": false,
2309
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US'). Leave blank to let the API pick."
2310
+ }
2311
+ ]
2312
+ },
2027
2313
  {
2028
2314
  "name": "etsy_search",
2029
2315
  "title": "Scrape Etsy product search",
@@ -2092,7 +2378,7 @@ var PLUGINS = [
2092
2378
  "category": "E-commerce",
2093
2379
  "path": "/marketplace/shein-search",
2094
2380
  "fixed": {},
2095
- "description": "Searches SHEIN (US store) for `query` and returns the products as JSON: `id`, `sku`, `title`, `url`, `price`, `originalPrice`, `currency`, `discountPercent`, `rating`, `reviewCount`, `category`, `image`, `soldOut` and `storeCode`. Order with `sort`, filter with `min_price`/`max_price`. Returns SHEIN's first results page (up to 20 products); SHEIN does not serve deeper pages to automated clients.",
2381
+ "description": "Searches SHEIN (US store) for `query` and returns the products as JSON: `id`, `sku`, `title`, `url`, `price`, `originalPrice`, `currency`, `discountPercent`, `rating`, `reviewCount`, `reviewCountText`, `category`, `image`, `soldOut` and `storeCode`. Order with `sort`, filter with `min_price`/`max_price` (enforced on `price`). Returns SHEIN's first results page (up to 20 products); SHEIN does not serve deeper pages to automated clients.",
2096
2382
  "params": [
2097
2383
  {
2098
2384
  "name": "query",
@@ -2886,62 +3172,501 @@ var PLUGINS = [
2886
3172
  ]
2887
3173
  },
2888
3174
  {
2889
- "name": "ebay_search",
2890
- "title": "Scrape eBay search listings",
2891
- "category": "Classifieds & Resale",
2892
- "path": "/marketplace/ebay-search",
3175
+ "name": "flipkart_search",
3176
+ "title": "Scrape Flipkart product search",
3177
+ "category": "E-commerce",
3178
+ "path": "/marketplace/flipkart-search",
2893
3179
  "fixed": {},
2894
- "description": "Searches any regional eBay marketplace for `keyword` and returns the listings as JSON: `title`, `price` + `currency`, `condition` (with a normalised `conditionCode`), `seller` (username, feedback percentage and score), `shippingCost`, `sold`, `watchers`, `bids`, `image` and a clean item `url`. Filter with `condition`, `listing_type`, `min_price`/`max_price`, `free_shipping`, `seller` or `category`, sort with `sort`, and page with `page`/`page_size` (60, 120 or 240 per page). Set `marketplace` to search a specific site - prices, currency and availability differ between ebay.com, ebay.de, ebay.co.uk and the rest. When eBay finds no exact match it still serves a full page of its own loosely-related suggestions. That case is reported honestly: `exactMatches` is `false` and a `notice` explains it, so those listings are never mistaken for real matches.",
3180
+ "description": "Searches Flipkart (India) for `query` and returns `products`, each with `productId` (the FSN, e.g. MOBHQV9YCUG4ZQZK), `itemId`, `listingId`, `title`, `brand`, `price`, `originalPrice` (MRP when discounted), `discountPercent`, `currency` (INR), `rating`, `ratingCount`, `reviewCount`, `assured` (F-Assured), `sponsored`, `badge` (e.g. Bestseller), `availability` / `inStock`, `keySpecs`, `category`, `image`, `images` and `url`. Also `total` (results Flipkart reports), `totalPages` and `nextPage`. `sort` orders the results, `min_price` / `max_price` filter by price, `page` picks the first page and `max_results` collects across pages. One unit per Flipkart page read.",
2895
3181
  "params": [
2896
3182
  {
2897
- "name": "keyword",
3183
+ "name": "query",
2898
3184
  "type": "string",
2899
3185
  "required": true,
2900
- "description": "Search phrase, e.g. 'iphone 13' or a part number like '1K0953519A'."
3186
+ "description": "What to search for, e.g. 'iphone 17' or 'running shoes'."
2901
3187
  },
2902
3188
  {
2903
- "name": "marketplace",
3189
+ "name": "sort",
2904
3190
  "type": "string",
2905
3191
  "required": false,
2906
- "description": "Regional eBay site to search. Prices, currency and availability differ per marketplace. One of: ebay.com, ebay.co.uk, ebay.de, ebay.fr, ebay.it, ebay.es, ebay.nl, ebay.pl, ebay.at, ebay.ch, ebay.be, ebay.ie, ebay.ca, ebay.com.au, ebay.in, ebay.ph, ebay.com.sg, ebay.com.my, ebay.com.hk.",
2907
- "default": "ebay.com"
3192
+ "description": "Result order: relevance, popularity, price_asc, price_desc, newest.",
3193
+ "default": "relevance"
2908
3194
  },
2909
3195
  {
2910
3196
  "name": "page",
2911
3197
  "type": "integer",
2912
3198
  "required": false,
2913
- "description": "1-based page number.",
3199
+ "description": "First Flipkart results page to read (1-100).",
2914
3200
  "default": 1
2915
3201
  },
2916
3202
  {
2917
- "name": "page_size",
3203
+ "name": "min_price",
2918
3204
  "type": "integer",
2919
3205
  "required": false,
2920
- "description": "Listings per page - eBay's own page sizes: 60, 120, 240.",
2921
- "default": 60
3206
+ "description": "Lowest price in rupees (INR)."
2922
3207
  },
2923
3208
  {
2924
- "name": "condition",
2925
- "type": "string",
3209
+ "name": "max_price",
3210
+ "type": "integer",
2926
3211
  "required": false,
2927
- "description": "Item condition filter: new, open_box, refurbished, used, for_parts. Omit for every condition."
3212
+ "description": "Highest price in rupees (INR)."
2928
3213
  },
2929
3214
  {
2930
- "name": "sort",
2931
- "type": "string",
3215
+ "name": "max_results",
3216
+ "type": "integer",
2932
3217
  "required": false,
2933
- "description": "Ordering: best_match, newly_listed, ending_soon, price_asc, price_desc. Default 'best_match'.",
2934
- "default": "best_match"
3218
+ "description": "Products to collect across pages, 1-240. A page holds 24 products (40 in fashion grids); each page is one unit.",
3219
+ "default": 24
2935
3220
  },
2936
3221
  {
2937
- "name": "listing_type",
3222
+ "name": "proxy_country",
2938
3223
  "type": "string",
2939
3224
  "required": false,
2940
- "description": "Listing format: all, buy_it_now, auction. Default 'all'.",
2941
- "default": "all"
2942
- },
2943
- {
2944
- "name": "min_price",
3225
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Leave blank to let the API pick."
3226
+ }
3227
+ ]
3228
+ },
3229
+ {
3230
+ "name": "flipkart_product",
3231
+ "title": "Scrape a Flipkart product",
3232
+ "category": "E-commerce",
3233
+ "path": "/marketplace/flipkart-product",
3234
+ "fixed": {},
3235
+ "description": "Returns one Flipkart (India) product by `product_id` (FSN or `itm` id) or `url`: `productId`, `itemId`, `listingId`, `title`, `brand`, `description`, `category`, `breadcrumbs`, `price`, `originalPrice` (MRP), `discountPercent`, `bestPrice` (with bank offers), `currency`, `availability` / `inStock`, `rating`, `ratingCount`, `reviewCount`, `ratingBreakdown` (1-5 stars), `aspectRatings` (e.g. Camera, Battery), `assured`, `selectedAttributes`, `highlights`, `specifications` (group / name / value), `images`, `variants` (dimension, value, productId, price, available, url), `seller` (name, id, rating, years on Flipkart), `offerCount`, `offers` (bank and exchange offers), `deliveryDays`, `cashOnDelivery`, `returnPolicy`, `reviews` (top reviews) and `url`. One unit per call.",
3236
+ "params": [
3237
+ {
3238
+ "name": "product_id",
3239
+ "type": "string",
3240
+ "required": false,
3241
+ "description": "Flipkart product id: the FSN (`pid`, e.g. MOBHQV9YCUG4ZQZK) or the `itm...` id from a product link."
3242
+ },
3243
+ {
3244
+ "name": "url",
3245
+ "type": "string",
3246
+ "required": false,
3247
+ "description": "A Flipkart product link, e.g. https://www.flipkart.com/apple-iphone-17-black-256-gb/p/itmc61b40459dd98?pid=MOBHQV9YCUG4ZQZK. Used instead of `product_id`."
3248
+ },
3249
+ {
3250
+ "name": "proxy_country",
3251
+ "type": "string",
3252
+ "required": false,
3253
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Leave blank to let the API pick."
3254
+ }
3255
+ ]
3256
+ },
3257
+ {
3258
+ "name": "lazada_search",
3259
+ "title": "Scrape Lazada product search",
3260
+ "category": "E-commerce",
3261
+ "path": "/marketplace/lazada-search",
3262
+ "fixed": {},
3263
+ "description": "Searches a Lazada market (Singapore, Malaysia, Thailand, Philippines, Vietnam or Indonesia - `country`) for `query` and returns `products`, each with `position`, `itemId`, `skuId`, `name`, `price`, `priceText`, `originalPrice` (crossed-out price), `discountPercent`, `rating`, `reviewCount`, `sold` (units sold, as Lazada rounds it) and `soldText`, `brand`, `seller` / `sellerId`, `location` (ships from), `inStock`, `lazMall`, `freeShipping`, `sponsored`, `image` and `url`. Also `total` (results Lazada lets you page through), `matches` (all matches it reports), `currency` and `nextPage`. `sort` orders the results, `min_price` / `max_price` filter by price, `page` picks the first page and `max_results` collects across pages (40 a page). One unit per Lazada page read.",
3264
+ "params": [
3265
+ {
3266
+ "name": "query",
3267
+ "type": "string",
3268
+ "required": true,
3269
+ "description": "What to search for, e.g. 'iphone case' or 'air fryer'."
3270
+ },
3271
+ {
3272
+ "name": "country",
3273
+ "type": "string",
3274
+ "required": false,
3275
+ "description": "Lazada market: 'sg' (lazada.sg), 'my' (lazada.com.my), 'th' (lazada.co.th), 'ph' (lazada.com.ph), 'vn' (lazada.vn), 'id' (lazada.co.id). Default 'sg'. Prices are in that market's currency."
3276
+ },
3277
+ {
3278
+ "name": "sort",
3279
+ "type": "string",
3280
+ "required": false,
3281
+ "description": "Result order: relevance, price_asc, price_desc.",
3282
+ "default": "relevance"
3283
+ },
3284
+ {
3285
+ "name": "page",
3286
+ "type": "integer",
3287
+ "required": false,
3288
+ "description": "First Lazada results page to read (1-102).",
3289
+ "default": 1
3290
+ },
3291
+ {
3292
+ "name": "min_price",
3293
+ "type": "number",
3294
+ "required": false,
3295
+ "description": "Lowest price, in the market's currency."
3296
+ },
3297
+ {
3298
+ "name": "max_price",
3299
+ "type": "number",
3300
+ "required": false,
3301
+ "description": "Highest price, in the market's currency."
3302
+ },
3303
+ {
3304
+ "name": "max_results",
3305
+ "type": "integer",
3306
+ "required": false,
3307
+ "description": "Products to collect across pages, 1-400. A page holds 40 products; each page is one unit.",
3308
+ "default": 40
3309
+ }
3310
+ ]
3311
+ },
3312
+ {
3313
+ "name": "lazada_product",
3314
+ "title": "Scrape a Lazada product",
3315
+ "category": "E-commerce",
3316
+ "path": "/marketplace/lazada-product",
3317
+ "fixed": {},
3318
+ "description": "Returns one Lazada product by `url`, or by `item_id` (+ optional `sku_id`) and `country`: `itemId`, `skuId`, `title`, `brand`, `description`, `highlights`, `categories`, `price`, `priceText`, `originalPrice`, `discountPercent`, `currency`, `rating`, `reviewCount`, `ratingBreakdown` (1-5 stars), `inStock`, `maxQuantity`, `images`, `specifications`, `variantDimensions` (e.g. colour and storage with their values), `variants` (every SKU with its attributes, price, image, availability and link), `seller` (id, shop id, name, positive rating, store highlights, link), `delivery` (option and estimate), `warranties` and `url`. One unit per call.",
3319
+ "params": [
3320
+ {
3321
+ "name": "item_id",
3322
+ "type": "string",
3323
+ "required": false,
3324
+ "description": "Lazada item id (the number after '-i' in a product link, e.g. 13907853520)."
3325
+ },
3326
+ {
3327
+ "name": "url",
3328
+ "type": "string",
3329
+ "required": false,
3330
+ "description": "A Lazada product link, e.g. https://www.lazada.sg/products/apple-iphone-18-pro-max-i13907853520-s124925162667.html. Used instead of `item_id` / `country`."
3331
+ },
3332
+ {
3333
+ "name": "sku_id",
3334
+ "type": "string",
3335
+ "required": false,
3336
+ "description": "Optional SKU id (the number after '-s') to select one variant."
3337
+ },
3338
+ {
3339
+ "name": "country",
3340
+ "type": "string",
3341
+ "required": false,
3342
+ "description": "Lazada market: 'sg' (lazada.sg), 'my' (lazada.com.my), 'th' (lazada.co.th), 'ph' (lazada.com.ph), 'vn' (lazada.vn), 'id' (lazada.co.id). Default 'sg'. Prices are in that market's currency."
3343
+ }
3344
+ ]
3345
+ },
3346
+ {
3347
+ "name": "allegro_search",
3348
+ "title": "Scrape Allegro search",
3349
+ "category": "E-commerce",
3350
+ "path": "/marketplace/allegro-search",
3351
+ "fixed": {},
3352
+ "description": "Searches Allegro (Poland) for `query` and returns `products` (offers), each with `position`, `offerId`, `productId`, `title`, `price`, `currency` (PLN), `priceWithDelivery`, `deliveryFrom`, `freeDelivery`, `smart` (Allegro Smart!), `deliveryLabel`, `rating`, `ratingCount`, `recentBuyers` (bought in the last 30 days), `offersOfProduct`, `quantity`, `sponsored`, `promoted`, `superSeller`, `seller` (id, login, company, positive feedback %), `parameters`, `image`, `images` and `url`. Also `total` (all matches), `available` (offers Allegro lets you page through), `lastPage`, `category` and `nextPage`. Filter with `min_price` / `max_price`, `condition`, `shipping_from`, `delivery_time`, `offer_type`, `store_city` and `store_region`; `sort` orders the results; `page` and `max_results` page through them. One unit per Allegro page read.",
3353
+ "params": [
3354
+ {
3355
+ "name": "query",
3356
+ "type": "string",
3357
+ "required": true,
3358
+ "description": "What to search for, e.g. 'iphone 15' or 'lego'."
3359
+ },
3360
+ {
3361
+ "name": "sort",
3362
+ "type": "string",
3363
+ "required": false,
3364
+ "description": "Result order: relevance, price_asc, price_desc, price_with_delivery_asc, price_with_delivery_desc, popularity, ending_soon, newest, rating.",
3365
+ "default": "relevance"
3366
+ },
3367
+ {
3368
+ "name": "page",
3369
+ "type": "integer",
3370
+ "required": false,
3371
+ "description": "First Allegro results page to read (1-100).",
3372
+ "default": 1
3373
+ },
3374
+ {
3375
+ "name": "min_price",
3376
+ "type": "number",
3377
+ "required": false,
3378
+ "description": "Lowest price in zloty (PLN)."
3379
+ },
3380
+ {
3381
+ "name": "max_price",
3382
+ "type": "number",
3383
+ "required": false,
3384
+ "description": "Highest price in zloty (PLN)."
3385
+ },
3386
+ {
3387
+ "name": "condition",
3388
+ "type": "string",
3389
+ "required": false,
3390
+ "description": "Item condition: new, like_new, refurbished, used, damaged."
3391
+ },
3392
+ {
3393
+ "name": "shipping_from",
3394
+ "type": "string",
3395
+ "required": false,
3396
+ "description": "Where the item ships from: pl, cz, sk, hu, cn, eu, allegro_warehouse."
3397
+ },
3398
+ {
3399
+ "name": "delivery_time",
3400
+ "type": "string",
3401
+ "required": false,
3402
+ "description": "Delivery speed: one_day, two_days, three_days (one_day = tomorrow)."
3403
+ },
3404
+ {
3405
+ "name": "offer_type",
3406
+ "type": "string",
3407
+ "required": false,
3408
+ "description": "Offer type: buy_now, auction (buy_now = fixed price)."
3409
+ },
3410
+ {
3411
+ "name": "store_city",
3412
+ "type": "string",
3413
+ "required": false,
3414
+ "description": "The seller's town, e.g. 'Krak\xF3w'."
3415
+ },
3416
+ {
3417
+ "name": "store_region",
3418
+ "type": "string",
3419
+ "required": false,
3420
+ "description": "The seller's voivodeship, e.g. 'mazowieckie' or 'slaskie' (or its number 1-16)."
3421
+ },
3422
+ {
3423
+ "name": "max_results",
3424
+ "type": "integer",
3425
+ "required": false,
3426
+ "description": "Offers to collect across pages, 1-300. A page holds about 60 offers; each page is one unit.",
3427
+ "default": 60
3428
+ },
3429
+ {
3430
+ "name": "proxy_country",
3431
+ "type": "string",
3432
+ "required": false,
3433
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'DE', 'CZ'). Leave blank to let the API pick (recommended: Allegro refuses some countries' exits)."
3434
+ }
3435
+ ]
3436
+ },
3437
+ {
3438
+ "name": "allegro_product",
3439
+ "title": "Scrape an Allegro offer",
3440
+ "category": "E-commerce",
3441
+ "path": "/marketplace/allegro-product",
3442
+ "fixed": {},
3443
+ "description": "Returns one Allegro (Poland) offer by `offer_id` or `url`: `offerId`, `productId`, `title`, `productName`, `brand`, `gtin`, `price`, `originalPrice`, `currency`, `sellingMode` (buy_now / auction), `available` (stock), `condition`, `rating`, `ratingCount`, `ratingBreakdown` (1-5 stars), `recentBuyers`, `category`, `breadcrumbs`, `parameters` (group / name / value), `description`, `images`, `variants`, `seller` (id, login, Super Seller, feedback, company name and tax id), `location`, `smart`, `delivery`, `shippingMethods` (name, price, Smart! price), `returnDays`, `warranty`, `endsAt`, `reviews` and `url`. One unit per call.",
3444
+ "params": [
3445
+ {
3446
+ "name": "offer_id",
3447
+ "type": "string",
3448
+ "required": false,
3449
+ "description": "Allegro offer number, e.g. 16680923539 (the number at the end of an /oferta/ link or its offerId)."
3450
+ },
3451
+ {
3452
+ "name": "url",
3453
+ "type": "string",
3454
+ "required": false,
3455
+ "description": "An Allegro offer or product link, e.g. https://allegro.pl/oferta/16680923539 or https://allegro.pl/produkt/...?offerId=16680923539. Used instead of `offer_id`."
3456
+ },
3457
+ {
3458
+ "name": "proxy_country",
3459
+ "type": "string",
3460
+ "required": false,
3461
+ "description": "Proxy country the request is sent from (ISO-2, e.g. 'DE', 'CZ'). Leave blank to let the API pick (recommended: Allegro refuses some countries' exits)."
3462
+ }
3463
+ ]
3464
+ },
3465
+ {
3466
+ "name": "falabella_search",
3467
+ "title": "Scrape Falabella product search (Chile, Colombia, Peru)",
3468
+ "category": "E-commerce",
3469
+ "path": "/marketplace/falabella-search",
3470
+ "fixed": {},
3471
+ "description": "Searches a Falabella store (`country`: cl, co or pe) for `query` and returns the products as JSON: `productId`, `skuId`, `title`, `brand`, `url`, `price` (and `priceMax` for a price range), `cmrPrice` (price with the Falabella CMR card), `originalPrice` (crossed-out list price), `discountPercent`, `currency`, `rating`, `reviewCount`, `sellerId` / `sellerName`, `sponsored`, `bestSeller`, `freeShipping`, `deliveryLabels`, `badges`, `installmentsWithoutInterest`, `image` / `images`, `topSpecifications` and `variants` (colour / size options). Sort with `sort`, start at `page`, and collect up to `max_results` across pages (48 per page, each page billed as one request, see `pagesFetched`). `url` takes a Falabella search link instead of `query`.",
3472
+ "params": [
3473
+ {
3474
+ "name": "query",
3475
+ "type": "string",
3476
+ "required": false,
3477
+ "description": "What to search, e.g. 'zapatillas nike', 'televisor 55' or 'notebook'."
3478
+ },
3479
+ {
3480
+ "name": "country",
3481
+ "type": "string",
3482
+ "required": false,
3483
+ "description": "Falabella store: 'cl' (www.falabella.com, prices in CLP), 'co' (www.falabella.com.co, prices in COP), 'pe' (www.falabella.com.pe, prices in PEN). Default 'cl'."
3484
+ },
3485
+ {
3486
+ "name": "sort",
3487
+ "type": "string",
3488
+ "required": false,
3489
+ "description": "Order: relevance, price_low, price_high, rating, brand.",
3490
+ "default": "relevance"
3491
+ },
3492
+ {
3493
+ "name": "page",
3494
+ "type": "integer",
3495
+ "required": false,
3496
+ "description": "1-based results page to start from (1-200).",
3497
+ "default": 1
3498
+ },
3499
+ {
3500
+ "name": "max_results",
3501
+ "type": "integer",
3502
+ "required": false,
3503
+ "description": "Products to collect across pages (1-480); Falabella serves 48 per page and each page fetched is billed as one request.",
3504
+ "default": 48
3505
+ },
3506
+ {
3507
+ "name": "url",
3508
+ "type": "string",
3509
+ "required": false,
3510
+ "description": "Instead of `query`: a Falabella search link, e.g. https://www.falabella.com/falabella-cl/search?Ntt=zapatillas (its store, sort and page are used)."
3511
+ }
3512
+ ]
3513
+ },
3514
+ {
3515
+ "name": "falabella_product",
3516
+ "title": "Scrape one Falabella product's full detail",
3517
+ "category": "E-commerce",
3518
+ "path": "/marketplace/falabella-product",
3519
+ "fixed": {},
3520
+ "description": "Fetches one Falabella product (by `product_id` + `country`, or `url`) and returns it as JSON: `productId`, `skuId`, `url`, `title`, `brand`, `description` / `longDescription`, `price` / `priceMax`, `cmrPrice`, `originalPrice`, `discountPercent`, `currency`, `available`, `stockUnits` (only when Falabella shows a low-stock count), `rating`, `reviewCount`, `sellerId` / `sellerName`, `freeShipping`, `deliveryLabels`, `badges`, `installmentsWithoutInterest`, `breadcrumbs`, `topSpecifications`, `specifications` (name / value), `images`, `videos`, `returnPolicy` and `variants` (every colour / size SKU with its own price, availability, delivery options and images). The top-level price fields are those of `sku` (default the main variant). Companion to `/marketplace/falabella-search`.",
3521
+ "params": [
3522
+ {
3523
+ "name": "product_id",
3524
+ "type": "string",
3525
+ "required": false,
3526
+ "description": "Falabella product id, e.g. '17776888' or 'prod11930024' (the part after /product/ in a product link). Needs `country` unless it is 'cl'."
3527
+ },
3528
+ {
3529
+ "name": "url",
3530
+ "type": "string",
3531
+ "required": false,
3532
+ "description": "Instead of `product_id`: a Falabella product link, e.g. https://www.falabella.com/falabella-cl/product/17776888/iphone-duo-256gb-night-sky/17776887 (its store and SKU are used)."
3533
+ },
3534
+ {
3535
+ "name": "sku",
3536
+ "type": "string",
3537
+ "required": false,
3538
+ "description": "Variant (SKU) whose price and availability fill the top-level fields; default the product's main variant. Every variant is listed in `variants` either way."
3539
+ },
3540
+ {
3541
+ "name": "country",
3542
+ "type": "string",
3543
+ "required": false,
3544
+ "description": "With `product_id`: Falabella store: 'cl' (www.falabella.com, prices in CLP), 'co' (www.falabella.com.co, prices in COP), 'pe' (www.falabella.com.pe, prices in PEN). Default 'cl'."
3545
+ }
3546
+ ]
3547
+ },
3548
+ {
3549
+ "name": "magazineluiza_search",
3550
+ "title": "Scrape Magazine Luiza (Magalu) product search",
3551
+ "category": "E-commerce",
3552
+ "path": "/marketplace/magazineluiza-search",
3553
+ "fixed": {},
3554
+ "description": "Searches Magazine Luiza (magazineluiza.com.br, Brazil) for `query` and returns the products as JSON: `productId`, `offerId`, `title`, `brand`, `url`, `price`, `bestPrice` with `bestPriceMethod` (usually the Pix price), `originalPrice` (list price), `discountPercent`, `currency` (BRL), `installments` (count, amount, interest-free), `rating`, `reviewCount`, `sellerId` / `sellerName`, `available`, `sponsored`, `magaluIndica`, `category` / `subcategory`, `badges`, `image` and `variations`. Sort with `sort`, start at `page`, and collect up to `max_results` across pages (40 per page, each page billed as one request, see `pagesFetched`). `url` takes a Magalu search link instead of `query`.",
3555
+ "params": [
3556
+ {
3557
+ "name": "query",
3558
+ "type": "string",
3559
+ "required": false,
3560
+ "description": "What to search, e.g. 'geladeira', 'smart tv 55' or 'air fryer'."
3561
+ },
3562
+ {
3563
+ "name": "sort",
3564
+ "type": "string",
3565
+ "required": false,
3566
+ "description": "Order: relevance, price_low, price_high, best_selling, rating, newest, fastest_delivery, price_with_shipping_low.",
3567
+ "default": "relevance"
3568
+ },
3569
+ {
3570
+ "name": "page",
3571
+ "type": "integer",
3572
+ "required": false,
3573
+ "description": "1-based results page to start from (1-25).",
3574
+ "default": 1
3575
+ },
3576
+ {
3577
+ "name": "max_results",
3578
+ "type": "integer",
3579
+ "required": false,
3580
+ "description": "Products to collect across pages (1-200); Magalu serves 40 per page and each page fetched is billed as one request.",
3581
+ "default": 40
3582
+ },
3583
+ {
3584
+ "name": "url",
3585
+ "type": "string",
3586
+ "required": false,
3587
+ "description": "Instead of `query`: a Magazine Luiza search link, e.g. https://www.magazineluiza.com.br/busca/geladeira/ (its sort and page are used)."
3588
+ }
3589
+ ]
3590
+ },
3591
+ {
3592
+ "name": "magazineluiza_product",
3593
+ "title": "Scrape one Magazine Luiza (Magalu) product's full detail",
3594
+ "category": "E-commerce",
3595
+ "path": "/marketplace/magazineluiza-product",
3596
+ "fixed": {},
3597
+ "description": "Fetches one Magazine Luiza product (by `product_id` or `url`) and returns it as JSON: `productId`, `offerId`, `url`, `title`, `brand`, `reference`, `description`, `keySellingPoints`, `price`, `bestPrice` / `bestPriceMethod`, `originalPrice`, `discountPercent`, `currency` (BRL), `installments`, `available`, `rating`, `reviewCount`, `commentCount`, `ratingHistogram`, `ratingAspects`, `reviews` (first page: rating, text, author, date, photos), `seller` (id, name, legal name, city / state, seller since, score, total sales, answer and delivery rate), `coupon`, `badges`, `breadcrumbs`, `specifications` (group / name / value), `variations` (colour, size, capacity... with the product id of each option), `images`, `videos` and package `dimensions`. Companion to `/marketplace/magazineluiza-search`.",
3598
+ "params": [
3599
+ {
3600
+ "name": "product_id",
3601
+ "type": "string",
3602
+ "required": false,
3603
+ "description": "Magalu product id, e.g. '240354400' or 'jc60hbaa6d' (the part after /p/ in a product link)."
3604
+ },
3605
+ {
3606
+ "name": "url",
3607
+ "type": "string",
3608
+ "required": false,
3609
+ "description": "Instead of `product_id`: a Magazine Luiza product link, e.g. https://www.magazineluiza.com.br/notebook-acer-aspire-go/p/240354400/in/nota/."
3610
+ }
3611
+ ]
3612
+ },
3613
+ {
3614
+ "name": "ebay_search",
3615
+ "title": "Scrape eBay search listings",
3616
+ "category": "Classifieds & Resale",
3617
+ "path": "/marketplace/ebay-search",
3618
+ "fixed": {},
3619
+ "description": "Searches any regional eBay marketplace for `keyword` and returns the listings as JSON: `title`, `price` + `currency`, `condition` (with a normalised `conditionCode`), `seller` (username, feedback percentage and score), `shippingCost`, `sold`, `watchers`, `bids`, `image` and a clean item `url`. Filter with `condition`, `listing_type`, `min_price`/`max_price`, `free_shipping`, `seller` or `category`, sort with `sort`, and page with `page`/`page_size` (60, 120 or 240 per page). Set `marketplace` to search a specific site - prices, currency and availability differ between ebay.com, ebay.de, ebay.co.uk and the rest. When eBay finds no exact match it still serves a full page of its own loosely-related suggestions. That case is reported honestly: `exactMatches` is `false` and a `notice` explains it, so those listings are never mistaken for real matches.",
3620
+ "params": [
3621
+ {
3622
+ "name": "keyword",
3623
+ "type": "string",
3624
+ "required": true,
3625
+ "description": "Search phrase, e.g. 'iphone 13' or a part number like '1K0953519A'."
3626
+ },
3627
+ {
3628
+ "name": "marketplace",
3629
+ "type": "string",
3630
+ "required": false,
3631
+ "description": "Regional eBay site to search. Prices, currency and availability differ per marketplace. One of: ebay.com, ebay.co.uk, ebay.de, ebay.fr, ebay.it, ebay.es, ebay.nl, ebay.pl, ebay.at, ebay.ch, ebay.be, ebay.ie, ebay.ca, ebay.com.au, ebay.in, ebay.ph, ebay.com.sg, ebay.com.my, ebay.com.hk.",
3632
+ "default": "ebay.com"
3633
+ },
3634
+ {
3635
+ "name": "page",
3636
+ "type": "integer",
3637
+ "required": false,
3638
+ "description": "1-based page number.",
3639
+ "default": 1
3640
+ },
3641
+ {
3642
+ "name": "page_size",
3643
+ "type": "integer",
3644
+ "required": false,
3645
+ "description": "Listings per page - eBay's own page sizes: 60, 120, 240.",
3646
+ "default": 60
3647
+ },
3648
+ {
3649
+ "name": "condition",
3650
+ "type": "string",
3651
+ "required": false,
3652
+ "description": "Item condition filter: new, open_box, refurbished, used, for_parts. Omit for every condition."
3653
+ },
3654
+ {
3655
+ "name": "sort",
3656
+ "type": "string",
3657
+ "required": false,
3658
+ "description": "Ordering: best_match, newly_listed, ending_soon, price_asc, price_desc. Default 'best_match'.",
3659
+ "default": "best_match"
3660
+ },
3661
+ {
3662
+ "name": "listing_type",
3663
+ "type": "string",
3664
+ "required": false,
3665
+ "description": "Listing format: all, buy_it_now, auction. Default 'all'.",
3666
+ "default": "all"
3667
+ },
3668
+ {
3669
+ "name": "min_price",
2945
3670
  "type": "number",
2946
3671
  "required": false,
2947
3672
  "description": "Lowest price to include, in the marketplace's currency."
@@ -3617,6 +4342,221 @@ var PLUGINS = [
3617
4342
  }
3618
4343
  ]
3619
4344
  },
4345
+ {
4346
+ "name": "kroger_search",
4347
+ "title": "Search Kroger and its banner stores (Ralphs, Fred Meyer, King Soopers, ...)",
4348
+ "category": "Groceries",
4349
+ "path": "/groceries/kroger-search",
4350
+ "fixed": {},
4351
+ "description": "Products matching `query` on Kroger or one of its banner sites (`banner`: kroger, ralphs, fredmeyer, kingsoopers, frysfood, smithsfoodanddrug, qfc, dillons, bakersplus, citymarket, gerbes, foodfourless, harristeeter, marianos, metromarket, picknsave, jaycfoods, payless, foodsco), priced for one store. Returns `products` in the site's order with `productId` (Kroger's 13-digit id), `upc`, `gtin14`, `name`, `brand`, `size`, `url`, `image`, `price` (what the shopper pays now), `regularPrice`, `salePrice`, `onSale`, `savings`, `promotion` (`type` sale / price_drop / multibuy / must_buy / bogo, `text`, multibuy `quantity` and `quantityPrice`, `expiresAt`), `unitPrice` (`price`, `unit`, `text`), `soldBy` (unit / weight; weighed items carry Kroger's per-item estimate), `available`, `stockLevel` (HIGH / LOW / TEMPORARILY_OUT_OF_STOCK), `maxOrderQuantity`, `fulfillment` (`pickup`, `delivery`, `inStore`, `ship`: whether the store offers the product that way), `aisle` (`number`, `description`, `side`, `bay`, `shelf`), `rating`, `reviewCount`, `categories`, `snapEligible` and `offers` (extra deals such as 'Save $2 each when you buy 3'), plus `position` and `sponsored`. `totalResults` is the site's total match count; one call returns the first page (up to 24 products). `brand` narrows the search to one or more brands. `store` names the store the prices are for: `storeId`, `name`, `banner`, `address`, `latitude`, `longitude`, `fulfillmentMethods`, `hours`, `pricesFor` (pickup or inStore) and `selectedBy` (store_id / zip / default); with `zip`, `nearbyStores` lists the banner's other stores near it. Prices are in USD and depend on the store. One billed unit per call.",
4352
+ "params": [
4353
+ {
4354
+ "name": "query",
4355
+ "type": "string",
4356
+ "required": true,
4357
+ "description": "What to search for, e.g. 'milk', 'coca cola', 'gluten free bread'."
4358
+ },
4359
+ {
4360
+ "name": "banner",
4361
+ "type": "string",
4362
+ "required": false,
4363
+ "description": "Which Kroger-family store site to use: 'kroger' (Kroger), 'ralphs' (Ralphs), 'fredmeyer' (Fred Meyer), 'kingsoopers' (King Soopers), 'frysfood' (Fry's Food), 'smithsfoodanddrug' (Smith's), 'qfc' (QFC), 'dillons' (Dillons), 'bakersplus' (Baker's), 'citymarket' (City Market), 'gerbes' (Gerbes), 'foodfourless' (Food 4 Less), 'harristeeter' (Harris Teeter), 'marianos' (Mariano's), 'metromarket' (Metro Market), 'picknsave' (Pick 'n Save), 'jaycfoods' (Jay C Food Stores), 'payless' (Pay Less), 'foodsco' (FoodsCo). Host names (ralphs.com) and common spellings (food4less, smiths, frys) work too.",
4364
+ "default": "kroger"
4365
+ },
4366
+ {
4367
+ "name": "brand",
4368
+ "type": "string",
4369
+ "required": false,
4370
+ "description": "Only products of these brands, e.g. 'Kroger' or 'Kroger|Simple Truth' (separate several with | or ,)."
4371
+ },
4372
+ {
4373
+ "name": "store_id",
4374
+ "type": "string",
4375
+ "required": false,
4376
+ "description": "Kroger store id (8 digits, e.g. '01400929'): prices, stock and aisles are that store's. The id is shown as `store.storeId` in every answer and in `nearbyStores` when you search by `zip`."
4377
+ },
4378
+ {
4379
+ "name": "zip",
4380
+ "type": "string",
4381
+ "required": false,
4382
+ "description": "US ZIP code: prices for the banner's nearest store to it that takes online orders (the nearest store at all when none does). The answer lists the nearby stores in `nearbyStores`. Leave both `store_id` and `zip` blank for the banner's default store."
4383
+ },
4384
+ {
4385
+ "name": "max_results",
4386
+ "type": "integer",
4387
+ "required": false,
4388
+ "description": "Products to return, 1-24 (the first page of results).",
4389
+ "default": 24
4390
+ }
4391
+ ]
4392
+ },
4393
+ {
4394
+ "name": "kroger_product",
4395
+ "title": "Kroger product details (Kroger, Ralphs, Fred Meyer, King Soopers, ...)",
4396
+ "category": "Groceries",
4397
+ "path": "/groceries/kroger-product",
4398
+ "fixed": {},
4399
+ "description": "One product from Kroger or one of its banner sites, by Kroger product id, UPC / GTIN barcode or product link, priced for one store. `product` has `productId` (Kroger's 13-digit id), `upc`, `gtin14`, `name`, `brand`, `size`, `url`, `image`, `price` (what the shopper pays now), `regularPrice`, `salePrice`, `onSale`, `savings`, `promotion` (`type` sale / price_drop / multibuy / must_buy / bogo, `text`, multibuy `quantity` and `quantityPrice`, `expiresAt`), `unitPrice` (`price`, `unit`, `text`), `soldBy` (unit / weight; weighed items carry Kroger's per-item estimate), `available`, `stockLevel` (HIGH / LOW / TEMPORARILY_OUT_OF_STOCK), `maxOrderQuantity`, `fulfillment` (`pickup`, `delivery`, `inStore`, `ship`: whether the store offers the product that way), `aisle` (`number`, `description`, `side`, `bay`, `shelf`), `rating`, `reviewCount`, `categories`, `snapEligible` and `offers` (extra deals such as 'Save $2 each when you buy 3'), and the product page details: `description`, `highlights`, `images` (every angle, large), `ingredients`, `allergens`, `nutrition` (`servingSize`, `servingsPerContainer`, `nutrients` with amount, unit and % daily value), `dietary`, `claims`, `organic`, `glutenFree`, `kosher`, `nonGmo`, `taxonomy` (category paths), `countryOfOrigin`, `storage`, `dimensions`, `weight`, `ratingBreakdown`, `alcohol` and `ageRestricted`. `store` names the store the prices are for: `storeId`, `name`, `banner`, `address`, `latitude`, `longitude`, `fulfillmentMethods`, `hours`, `pricesFor` (pickup or inStore) and `selectedBy` (store_id / zip / default). One billed unit per call.",
4400
+ "params": [
4401
+ {
4402
+ "name": "product",
4403
+ "type": "string",
4404
+ "required": true,
4405
+ "description": "The product: Kroger's 13-digit product id ('0001111041700'), a UPC or GTIN barcode ('011110417005'), or a product link from any banner (https://www.kroger.com/p/kroger-2-reduced-fat-milk/0001111041700). A link picks its banner by itself."
4406
+ },
4407
+ {
4408
+ "name": "banner",
4409
+ "type": "string",
4410
+ "required": false,
4411
+ "description": "Which Kroger-family store site to use: 'kroger' (Kroger), 'ralphs' (Ralphs), 'fredmeyer' (Fred Meyer), 'kingsoopers' (King Soopers), 'frysfood' (Fry's Food), 'smithsfoodanddrug' (Smith's), 'qfc' (QFC), 'dillons' (Dillons), 'bakersplus' (Baker's), 'citymarket' (City Market), 'gerbes' (Gerbes), 'foodfourless' (Food 4 Less), 'harristeeter' (Harris Teeter), 'marianos' (Mariano's), 'metromarket' (Metro Market), 'picknsave' (Pick 'n Save), 'jaycfoods' (Jay C Food Stores), 'payless' (Pay Less), 'foodsco' (FoodsCo). Host names (ralphs.com) and common spellings (food4less, smiths, frys) work too. Default 'kroger'."
4412
+ },
4413
+ {
4414
+ "name": "store_id",
4415
+ "type": "string",
4416
+ "required": false,
4417
+ "description": "Kroger store id (8 digits, e.g. '01400929'): prices, stock and aisles are that store's. The id is shown as `store.storeId` in every answer and in `nearbyStores` when you search by `zip`."
4418
+ },
4419
+ {
4420
+ "name": "zip",
4421
+ "type": "string",
4422
+ "required": false,
4423
+ "description": "US ZIP code: prices for the banner's nearest store to it that takes online orders (the nearest store at all when none does). The answer lists the nearby stores in `nearbyStores`. Leave both `store_id` and `zip` blank for the banner's default store."
4424
+ }
4425
+ ]
4426
+ },
4427
+ {
4428
+ "name": "instacart_search",
4429
+ "title": "Scrape Instacart product search",
4430
+ "category": "Groceries",
4431
+ "path": "/groceries/instacart-search",
4432
+ "fixed": {},
4433
+ "description": "Searches one retailer's Instacart catalogue (Costco, Aldi, Publix, Safeway, Kroger, CVS, Sprouts, ... named by `retailer`) for `query` and returns `products` in Instacart's order, priced at the store Instacart assigns to `zip`: `id` (item id), `productId`, `name`, `brand`, `size`, `packageSize`, `price`, `priceText`, `wasPrice`, `onSale`, `unitPrice` (`price`, `per`, `text`), `soldBy` (each / weight), `estimatedWeight`, `promotions` (`text`, `type`), `available`, `stockLevel`, `rating`, `reviewCount`, `category`, `storeBrand`, `dietary`, `aisle`, `image` and `url`, plus `store` (the shop, its location id and the ZIP code used) and `totalResults`. Prices are Instacart's prices in USD, which can differ from the retailer's in-store prices. Up to `max_results` products, billed one unit per 30.",
4434
+ "params": [
4435
+ {
4436
+ "name": "query",
4437
+ "type": "string",
4438
+ "required": true,
4439
+ "description": "What to search for, e.g. 'milk', 'greek yogurt', 'paper towels'."
4440
+ },
4441
+ {
4442
+ "name": "retailer",
4443
+ "type": "string",
4444
+ "required": false,
4445
+ "description": "The retailer's Instacart slug: the part after /store/ in an Instacart link, e.g. 'costco', 'aldi', 'publix', 'safeway', 'kroger', 'cvs', 'sprouts', 'wegmans', 'sams-club'. An Instacart store link is accepted too."
4446
+ },
4447
+ {
4448
+ "name": "zip",
4449
+ "type": "string",
4450
+ "required": false,
4451
+ "description": "5-digit US ZIP code of the delivery area. Instacart prices and stock belong to the store serving it. Default 94105 (San Francisco)."
4452
+ },
4453
+ {
4454
+ "name": "max_results",
4455
+ "type": "integer",
4456
+ "required": false,
4457
+ "description": "Products to return, 1-300, in Instacart's order. Billed one unit per 30.",
4458
+ "default": 30
4459
+ }
4460
+ ]
4461
+ },
4462
+ {
4463
+ "name": "instacart_product",
4464
+ "title": "Scrape an Instacart product",
4465
+ "category": "Groceries",
4466
+ "path": "/groceries/instacart-product",
4467
+ "fixed": {},
4468
+ "description": "One product of a retailer on Instacart, priced at the store Instacart assigns to `zip`: the search fields (`id`, `productId`, `name`, `brand`, `size`, `packageSize`, `price`, `wasPrice`, `onSale`, `unitPrice`, `soldBy`, `promotions`, `available`, `stockLevel`, `rating`, `reviewCount`, `category`, `dietary`, `aisle`, `image`, `url`) plus `description`, `ingredients`, `directions`, `warnings`, the product page `sections` and the `images` gallery, and `store`. `product` is an Instacart product id, an item id from a search result or a product link. One unit per call.",
4469
+ "params": [
4470
+ {
4471
+ "name": "product",
4472
+ "type": "string",
4473
+ "required": true,
4474
+ "description": "An Instacart product id ('16902650'), an item id from a search result ('items_4142-16902650') or a product link (https://www.instacart.com/products/16902650-...)."
4475
+ },
4476
+ {
4477
+ "name": "retailer",
4478
+ "type": "string",
4479
+ "required": false,
4480
+ "description": "The retailer's Instacart slug: the part after /store/ in an Instacart link, e.g. 'costco', 'aldi', 'publix', 'safeway', 'kroger', 'cvs', 'sprouts', 'wegmans', 'sams-club'. An Instacart store link is accepted too. Optional when `product` is a link carrying `retailerSlug`."
4481
+ },
4482
+ {
4483
+ "name": "zip",
4484
+ "type": "string",
4485
+ "required": false,
4486
+ "description": "5-digit US ZIP code of the delivery area. Instacart prices and stock belong to the store serving it. Default 94105 (San Francisco)."
4487
+ }
4488
+ ]
4489
+ },
4490
+ {
4491
+ "name": "publix_search",
4492
+ "title": "Scrape Publix grocery search",
4493
+ "category": "Groceries",
4494
+ "path": "/groceries/publix-search",
4495
+ "fixed": {},
4496
+ "description": "Searches publix.com (US) for `query` at one store and returns `products`: `productId`, `itemCode`, `title`, `brand`, `size`, `url`, `image`, `price`, `priceText`, `unit` (e.g. 'lb' for items sold by weight), `wasPrice`, `currency`, `onSale`, `promotion` (`type` such as BOGO, `message`, `conditions`, `validThrough`, `savings`), `hasCoupon`, `soldByWeight`, `aisle`, `category`, `categoryPath` and `storeId`, plus `store` (the store the prices are for), `totalResults`, `totalPages` and `nextPage`. Publix publishes a price online only while an item is on promotion, so `price` is null for the rest. A keyword Publix sends to a category returns that category, named in `redirectedTo`; one it sends to a page that lists no products (the weekly ad, cake ordering, store locations) answers with no products and `sentElsewhere` true.",
4497
+ "params": [
4498
+ {
4499
+ "name": "query",
4500
+ "type": "string",
4501
+ "required": true,
4502
+ "description": "What to search for, e.g. 'milk', 'cheerios' or 'chicken breast'."
4503
+ },
4504
+ {
4505
+ "name": "store_id",
4506
+ "type": "string",
4507
+ "required": false,
4508
+ "description": "Publix store number whose prices and promotions to return, e.g. '1614'. Give this or `zip`; with neither, a store in Lakeland, FL is used. The store used is named in `store`."
4509
+ },
4510
+ {
4511
+ "name": "zip",
4512
+ "type": "string",
4513
+ "required": false,
4514
+ "description": "US ZIP code; the nearest Publix store is used, e.g. '33801'."
4515
+ },
4516
+ {
4517
+ "name": "page",
4518
+ "type": "integer",
4519
+ "required": false,
4520
+ "description": "1-based results page to start from (48 products per page).",
4521
+ "default": 1
4522
+ },
4523
+ {
4524
+ "name": "max_results",
4525
+ "type": "integer",
4526
+ "required": false,
4527
+ "description": "Products to collect from `page` on, 1-480. Each page fetched is billed one unit.",
4528
+ "default": 48
4529
+ }
4530
+ ]
4531
+ },
4532
+ {
4533
+ "name": "publix_product",
4534
+ "title": "Scrape a Publix product",
4535
+ "category": "Groceries",
4536
+ "path": "/groceries/publix-product",
4537
+ "fixed": {},
4538
+ "description": "Returns one publix.com (US) product at one store as `product`: the search fields (`productId`, `itemCode`, `title`, `brand`, `size`, `price`, `wasPrice`, `promotion`, `aisle` and so on) plus `images`, `description`, `ingredients`, `directions`, `allergens`, `available`, `categories`, `badges`, `couponCount`, `smartLabelUrl` and `relatedProducts`, and `store`, the store the price is for. Publix publishes a price online only while an item is on promotion.",
4539
+ "params": [
4540
+ {
4541
+ "name": "product",
4542
+ "type": "string",
4543
+ "required": true,
4544
+ "description": "A Publix product id ('RIO-PCI-103438') or product link (https://www.publix.com/pd/cheerios-cereal-large-size/RIO-PCI-103438)."
4545
+ },
4546
+ {
4547
+ "name": "store_id",
4548
+ "type": "string",
4549
+ "required": false,
4550
+ "description": "Publix store number whose prices and promotions to return, e.g. '1614'. Give this or `zip`; with neither, a store in Lakeland, FL is used. The store used is named in `store`."
4551
+ },
4552
+ {
4553
+ "name": "zip",
4554
+ "type": "string",
4555
+ "required": false,
4556
+ "description": "US ZIP code; the nearest Publix store is used, e.g. '33801'."
4557
+ }
4558
+ ]
4559
+ },
3620
4560
  {
3621
4561
  "name": "zillow_search",
3622
4562
  "title": "Scrape Zillow real-estate listings",
@@ -6614,7 +7554,7 @@ ${body}`);
6614
7554
  }
6615
7555
 
6616
7556
  // src/index.ts
6617
- var VERSION = "0.8.0";
7557
+ var VERSION = "0.9.0";
6618
7558
  var DEFAULT_BASE_URL = "https://api.scrapeunblocker.com";
6619
7559
  var API_KEY_HEADER = "x-scrapeunblocker-key";
6620
7560
  function resolveApiKey() {