composio-scavio 0.3.0 → 0.4.1
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.
- package/README.md +78 -6
- package/dist/index.cjs +1253 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +1253 -19
- package/dist/index.js.map +1 -1
- package/package.json +9 -3
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,11 @@ var str = (d) => import_zod.z.string().describe(d);
|
|
|
31
31
|
var ostr = (d) => import_zod.z.string().optional().describe(d);
|
|
32
32
|
var onum = (d) => import_zod.z.number().optional().describe(d);
|
|
33
33
|
var obool = (d) => import_zod.z.boolean().optional().describe(d);
|
|
34
|
+
var arrstr = (d) => import_zod.z.array(import_zod.z.string()).describe(d);
|
|
35
|
+
var oarrstr = (d) => import_zod.z.array(import_zod.z.string()).optional().describe(d);
|
|
36
|
+
var oarrnum = (d) => import_zod.z.array(import_zod.z.number()).optional().describe(d);
|
|
37
|
+
var ostrnum = (d) => import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).optional().describe(d);
|
|
38
|
+
var ostrarr = (d) => import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string())]).optional().describe(d);
|
|
34
39
|
var gl = ostr("Country of the search (ISO 3166-1 alpha-2, e.g. 'us', 'gb', 'de').");
|
|
35
40
|
var hl = ostr("UI language (ISO 639-1, e.g. 'en').");
|
|
36
41
|
var googleDomain = ostr("Regional Google domain, e.g. 'google.co.uk'.");
|
|
@@ -52,6 +57,28 @@ function buildScavioToolkit(options = {}) {
|
|
|
52
57
|
enableInstagram = true,
|
|
53
58
|
enableX = true,
|
|
54
59
|
enableLinkedin = true,
|
|
60
|
+
enableExtract = true,
|
|
61
|
+
enableThreads = false,
|
|
62
|
+
enableKuaishou = false,
|
|
63
|
+
enableEbay = false,
|
|
64
|
+
enableTarget = false,
|
|
65
|
+
enableHomeDepot = false,
|
|
66
|
+
enableZillow = false,
|
|
67
|
+
enableBooking = false,
|
|
68
|
+
enableTripadvisor = false,
|
|
69
|
+
enableIndeed = false,
|
|
70
|
+
enableAirbnb = false,
|
|
71
|
+
enableGlassdoor = false,
|
|
72
|
+
enableYelp = false,
|
|
73
|
+
enableAppStore = false,
|
|
74
|
+
enableGooglePlay = false,
|
|
75
|
+
enableSec = false,
|
|
76
|
+
enableRedfin = false,
|
|
77
|
+
enableCompaniesHouse = false,
|
|
78
|
+
enableG2 = false,
|
|
79
|
+
enableCapterra = false,
|
|
80
|
+
enableGoogleAds = false,
|
|
81
|
+
enableMetaAds = false,
|
|
55
82
|
all = false
|
|
56
83
|
} = options;
|
|
57
84
|
const client = new import_scavio.Scavio({ apiKey: apiKey ?? process.env.SCAVIO_API_KEY });
|
|
@@ -337,6 +364,13 @@ function buildScavioToolkit(options = {}) {
|
|
|
337
364
|
country: ostr("Marketplace country code (ISO 3166-1 alpha-2), not a domain: 'us' (default), 'gb' (the UK is gb, not uk), 'ca', 'de', 'fr', 'es', 'it', 'jp', 'in', 'au', 'br', 'mx', 'nl', 'pl', 'se', 'sg', 'ae', 'sa', 'eg', 'cn', 'be', 'tr'. An unknown code falls back to us.")
|
|
338
365
|
}),
|
|
339
366
|
(i) => client.amazon.offers(i)
|
|
367
|
+
),
|
|
368
|
+
tool(
|
|
369
|
+
"AMAZON_OPTIONS",
|
|
370
|
+
"Scavio Amazon Options",
|
|
371
|
+
"Supported Amazon marketplaces, as 'domains' and 'countries'. 'languages' and 'currencies' remain in the payload but are always empty: neither is a request param any more. Needs no API key and costs no credits.",
|
|
372
|
+
import_zod.z.object({}),
|
|
373
|
+
() => client.amazon.options()
|
|
340
374
|
)
|
|
341
375
|
);
|
|
342
376
|
}
|
|
@@ -345,34 +379,82 @@ function buildScavioToolkit(options = {}) {
|
|
|
345
379
|
tool(
|
|
346
380
|
"WALMART_SEARCH",
|
|
347
381
|
"Scavio Walmart Search",
|
|
348
|
-
"Search Walmart
|
|
382
|
+
"Search Walmart and get structured product rows (products, products_count and the store the results were priced against). Costs 1 credit on domain 'com' or 'ca' and 2 credits on 'com.mx' - the price is a function of the request body, not a constant for the route.",
|
|
349
383
|
import_zod.z.object({
|
|
350
|
-
query: str("
|
|
351
|
-
domain: ostr("
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
min_price: onum("Minimum price filter."),
|
|
356
|
-
max_price: onum("Maximum price filter."),
|
|
357
|
-
fulfillment_speed: ostr("
|
|
358
|
-
fulfillment_type: ostr("
|
|
359
|
-
delivery_zip: ostr("Delivery ZIP/postal code."),
|
|
360
|
-
store_id: ostr("Restrict to a store id.")
|
|
384
|
+
query: str("Product search query (1-500 characters)."),
|
|
385
|
+
domain: ostr("Marketplace: 'com' (US, default, 1 credit), 'ca' (1 credit), 'com.mx' (2 credits). Sets the currency and product URLs of the response."),
|
|
386
|
+
page: onum("Results page, 1-based (integer >= 1). One page per call."),
|
|
387
|
+
start_page: onum("Deprecated alias for page; send page instead."),
|
|
388
|
+
sort_by: ostr("Result sort order. Defaults to 'best_match'. Accepted values: 'best_match', 'price_low', 'price_high', 'best_seller', 'rating_high', 'new'."),
|
|
389
|
+
min_price: onum("Minimum price filter in the marketplace's own currency; decimals allowed (e.g. 19.99)."),
|
|
390
|
+
max_price: onum("Maximum price filter in the marketplace's own currency; decimals allowed (e.g. 199.5)."),
|
|
391
|
+
fulfillment_speed: ostr("Only items deliverable today, or by tomorrow. '2_days' and 'anytime' are not accepted - for anytime, omit this parameter."),
|
|
392
|
+
fulfillment_type: ostr("Set to 'in_store' to return only items available for in-store pickup.")
|
|
361
393
|
}),
|
|
362
394
|
(i) => client.walmart.search(i)
|
|
363
395
|
),
|
|
364
396
|
tool(
|
|
365
397
|
"WALMART_PRODUCT",
|
|
366
398
|
"Scavio Walmart Product",
|
|
367
|
-
"
|
|
399
|
+
"Full detail for a single Walmart product: price, rating, images, specifications, availability and seller. US marketplace only - walmart.ca product pages could not be fetched at all, so this endpoint takes no domain. Costs 1 credit: Walmart is body-priced through `domain`, but this endpoint takes no domain, so it is always 1.",
|
|
368
400
|
import_zod.z.object({
|
|
369
|
-
product_id: str("Walmart
|
|
370
|
-
domain: ostr("Walmart domain."),
|
|
371
|
-
device: ostr("Device profile: 'desktop' or 'mobile'."),
|
|
372
|
-
delivery_zip: ostr("Delivery ZIP/postal code."),
|
|
373
|
-
store_id: ostr("Restrict to a store id.")
|
|
401
|
+
product_id: str("Walmart item id (usItemId), e.g. '13544111159'.")
|
|
374
402
|
}),
|
|
375
403
|
(i) => client.walmart.product(i)
|
|
404
|
+
),
|
|
405
|
+
tool(
|
|
406
|
+
"WALMART_REVIEWS",
|
|
407
|
+
"Scavio Walmart Reviews",
|
|
408
|
+
"Customer reviews for a Walmart product with ratings, text, author, date and the rating breakdown. 10 reviews per page; paginate with page. Costs 1 credit: Walmart is body-priced through `domain`, but this endpoint takes no domain, so it is always 1.",
|
|
409
|
+
import_zod.z.object({
|
|
410
|
+
product_id: str("Walmart item id (usItemId), e.g. '13544111159'."),
|
|
411
|
+
page: onum("Reviews page, 1-based (integer >= 1). 10 reviews per page."),
|
|
412
|
+
sort: ostr("Review sort order. Omit for Walmart's own default ordering. Accepted values: 'relevancy', 'submission-desc', 'submission-asc', 'rating-desc', 'rating-asc', 'helpful-desc'.")
|
|
413
|
+
}),
|
|
414
|
+
(i) => client.walmart.reviews(i)
|
|
415
|
+
),
|
|
416
|
+
tool(
|
|
417
|
+
"WALMART_CATEGORY",
|
|
418
|
+
"Scavio Walmart Category",
|
|
419
|
+
"Products within a Walmart category, in the same product shape as search. Costs 1 credit on domain 'com' or 'ca' and 2 credits on 'com.mx' - the price is a function of the request body, not a constant for the route.",
|
|
420
|
+
import_zod.z.object({
|
|
421
|
+
category_id: str("Walmart category id: either a leaf id ('1095191') or the full underscore-joined path ('3944_133251_1095191'). Both are accepted."),
|
|
422
|
+
domain: ostr("Marketplace: 'com' (US, default, 1 credit), 'ca' (1 credit), 'com.mx' (2 credits). Sets the currency and product URLs of the response."),
|
|
423
|
+
page: onum("Results page, 1-based (integer >= 1). One page per call."),
|
|
424
|
+
limit: onum("Trim the returned products to at most this many (integer >= 1). Applied after fetching, so it does not reduce the credit cost of the call."),
|
|
425
|
+
sort_by: ostr("Result sort order. Defaults to 'best_match'. Accepted values: 'best_match', 'price_low', 'price_high', 'best_seller', 'rating_high', 'new'."),
|
|
426
|
+
min_price: onum("Minimum price filter in the marketplace's own currency; decimals allowed (e.g. 19.99)."),
|
|
427
|
+
max_price: onum("Maximum price filter in the marketplace's own currency; decimals allowed (e.g. 199.5)."),
|
|
428
|
+
fulfillment_speed: ostr("Only items deliverable today, or by tomorrow. '2_days' and 'anytime' are not accepted - for anytime, omit this parameter.")
|
|
429
|
+
}),
|
|
430
|
+
(i) => client.walmart.category(i)
|
|
431
|
+
),
|
|
432
|
+
tool(
|
|
433
|
+
"WALMART_OFFERS",
|
|
434
|
+
"Scavio Walmart Offers",
|
|
435
|
+
"The buy-box offer for a Walmart product: price, seller, condition and buy-box flag. BUY-BOX SELLER ONLY - this is not the full offer list, and there is no way to page through the other sellers. Costs 1 credit: Walmart is body-priced through `domain`, but this endpoint takes no domain, so it is always 1.",
|
|
436
|
+
import_zod.z.object({
|
|
437
|
+
product_id: str("Walmart item id (usItemId), e.g. '2979510112'.")
|
|
438
|
+
}),
|
|
439
|
+
(i) => client.walmart.offers(i)
|
|
440
|
+
),
|
|
441
|
+
tool(
|
|
442
|
+
"WALMART_SELLER",
|
|
443
|
+
"Scavio Walmart Seller",
|
|
444
|
+
"Marketplace seller storefront: name, rating, review count, Pro Seller badge and business details. Costs 1 credit: Walmart is body-priced through `domain`, but this endpoint takes no domain, so it is always 1.",
|
|
445
|
+
import_zod.z.object({
|
|
446
|
+
seller_id: str("Numeric Walmart catalog seller id, as returned in `seller_catalog_id` on a product, search or offers response (e.g. '101480084'). The GUID `seller_id` is not accepted here - it 404s.")
|
|
447
|
+
}),
|
|
448
|
+
(i) => client.walmart.seller(i)
|
|
449
|
+
),
|
|
450
|
+
tool(
|
|
451
|
+
"WALMART_SELLER_PRODUCTS",
|
|
452
|
+
"Scavio Walmart Seller Products",
|
|
453
|
+
"A marketplace seller's catalog. Roughly the first 40 items are server-rendered and returned; total_count reports the seller's real catalog size. There is no pagination - the rest of the catalog is not reachable. Costs 1 credit: Walmart is body-priced through `domain`, but this endpoint takes no domain, so it is always 1.",
|
|
454
|
+
import_zod.z.object({
|
|
455
|
+
seller_id: str("Numeric Walmart catalog seller id, as returned in `seller_catalog_id` on a product, search or offers response (e.g. '101480084'). The GUID `seller_id` 404s.")
|
|
456
|
+
}),
|
|
457
|
+
(i) => client.walmart.sellerProducts(i)
|
|
376
458
|
)
|
|
377
459
|
);
|
|
378
460
|
}
|
|
@@ -1200,9 +1282,1161 @@ function buildScavioToolkit(options = {}) {
|
|
|
1200
1282
|
)
|
|
1201
1283
|
);
|
|
1202
1284
|
}
|
|
1285
|
+
if (all || enableThreads) {
|
|
1286
|
+
tools.push(
|
|
1287
|
+
tool(
|
|
1288
|
+
"THREADS_PROFILE",
|
|
1289
|
+
"Scavio Threads Profile",
|
|
1290
|
+
"Profile details for a Threads user. Costs 2 credits addressed by user_id and 4 credits addressed by username - the price is a function of the request body, not a constant for the route; pass user_id whenever you have it.",
|
|
1291
|
+
import_zod.z.object({
|
|
1292
|
+
user_id: ostr("Numeric Threads user id, e.g. '63625256886'. The cheap path: 2 credits."),
|
|
1293
|
+
username: ostr("Threads handle without the @ (1-60 characters). Costs 2 extra credits (4 total): the upstream handle lookup is down, so the handle is resolved through people search first. Pass user_id instead to avoid that.")
|
|
1294
|
+
}),
|
|
1295
|
+
(i) => client.threads.profile(i)
|
|
1296
|
+
),
|
|
1297
|
+
tool(
|
|
1298
|
+
"THREADS_USER_POSTS",
|
|
1299
|
+
"Scavio Threads User Posts",
|
|
1300
|
+
"A user's Threads posts, cursor-paginated via next_cursor. Costs 2 credits addressed by user_id and 4 credits addressed by username - the price is a function of the request body, not a constant for the route; pass user_id whenever you have it.",
|
|
1301
|
+
import_zod.z.object({
|
|
1302
|
+
user_id: ostr("Numeric Threads user id, e.g. '63625256886'. The cheap path: 2 credits."),
|
|
1303
|
+
username: ostr("Threads handle without the @ (1-60 characters). Costs 2 extra credits (4 total) because the handle has to be resolved through people search first."),
|
|
1304
|
+
cursor: ostr("Pagination cursor from a prior response's next_cursor. Omit for the first page.")
|
|
1305
|
+
}),
|
|
1306
|
+
(i) => client.threads.userPosts(i)
|
|
1307
|
+
),
|
|
1308
|
+
tool(
|
|
1309
|
+
"THREADS_USER_REPLIES",
|
|
1310
|
+
"Scavio Threads User Replies",
|
|
1311
|
+
"A user's Threads replies, cursor-paginated via next_cursor. Costs 2 credits addressed by user_id and 4 credits addressed by username - the price is a function of the request body, not a constant for the route; pass user_id whenever you have it.",
|
|
1312
|
+
import_zod.z.object({
|
|
1313
|
+
user_id: ostr("Numeric Threads user id, e.g. '63625256886'. The cheap path: 2 credits."),
|
|
1314
|
+
username: ostr("Threads handle without the @ (1-60 characters). Costs 2 extra credits (4 total) because the handle has to be resolved through people search first."),
|
|
1315
|
+
cursor: ostr("Pagination cursor from a prior response's next_cursor. Omit for the first page.")
|
|
1316
|
+
}),
|
|
1317
|
+
(i) => client.threads.userReplies(i)
|
|
1318
|
+
),
|
|
1319
|
+
tool(
|
|
1320
|
+
"THREADS_POST",
|
|
1321
|
+
"Scavio Threads Post",
|
|
1322
|
+
"A single Threads post, addressed by post_id or by its threads.net URL. Costs 2 credits: Threads is body-priced by identifier, but this endpoint has no username form, so it is always 2.",
|
|
1323
|
+
import_zod.z.object({
|
|
1324
|
+
post_id: ostr("Threads post id, e.g. '3349029093483693129'."),
|
|
1325
|
+
url: ostr("Full threads.net post URL (e.g. 'https://www.threads.net/@natgeo/post/C8xY'), as an alternative to post_id.")
|
|
1326
|
+
}),
|
|
1327
|
+
(i) => client.threads.post(i)
|
|
1328
|
+
),
|
|
1329
|
+
tool(
|
|
1330
|
+
"THREADS_POST_COMMENTS",
|
|
1331
|
+
"Scavio Threads Post Comments",
|
|
1332
|
+
"Replies to a Threads post, cursor-paginated via next_cursor. Costs 2 credits: Threads is body-priced by identifier, but this endpoint has no username form, so it is always 2.",
|
|
1333
|
+
import_zod.z.object({
|
|
1334
|
+
post_id: str("Threads post id, e.g. '3349029093483693129'."),
|
|
1335
|
+
cursor: ostr("Pagination cursor from a prior response's next_cursor. Omit for the first page.")
|
|
1336
|
+
}),
|
|
1337
|
+
(i) => client.threads.postComments(i)
|
|
1338
|
+
),
|
|
1339
|
+
tool(
|
|
1340
|
+
"THREADS_SEARCH_USERS",
|
|
1341
|
+
"Scavio Threads Search Users",
|
|
1342
|
+
"Search Threads profiles by name or handle. This is the only search Threads exposes - there is no post or content search - and it returns a single unpaginated page. Costs 2 credits: Threads is body-priced by identifier, but this endpoint has no username form, so it is always 2.",
|
|
1343
|
+
import_zod.z.object({
|
|
1344
|
+
query: str("Name or handle to search for (1-200 characters).")
|
|
1345
|
+
}),
|
|
1346
|
+
(i) => client.threads.searchUsers(i)
|
|
1347
|
+
)
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
if (all || enableKuaishou) {
|
|
1351
|
+
tools.push(
|
|
1352
|
+
tool(
|
|
1353
|
+
"KUAISHOU_PROFILE",
|
|
1354
|
+
"Scavio Kuaishou Profile",
|
|
1355
|
+
"Profile details for a Kuaishou user. Costs 10 credits, the dearest single-object call on the platform: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1356
|
+
import_zod.z.object({
|
|
1357
|
+
user_id: str("Kuaishou user id (non-empty); get one from user_resolve or search_users.")
|
|
1358
|
+
}),
|
|
1359
|
+
(i) => client.kuaishou.profile(i)
|
|
1360
|
+
),
|
|
1361
|
+
tool(
|
|
1362
|
+
"KUAISHOU_USER_POSTS",
|
|
1363
|
+
"Scavio Kuaishou User Posts",
|
|
1364
|
+
"A Kuaishou user's top posts, cursor-paginated via next_cursor. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1365
|
+
import_zod.z.object({
|
|
1366
|
+
user_id: str("Kuaishou user id (non-empty); get one from user_resolve or search_users."),
|
|
1367
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1368
|
+
}),
|
|
1369
|
+
(i) => client.kuaishou.userPosts(i)
|
|
1370
|
+
),
|
|
1371
|
+
tool(
|
|
1372
|
+
"KUAISHOU_USER_LIVE",
|
|
1373
|
+
"Scavio Kuaishou User Live",
|
|
1374
|
+
"A Kuaishou user's current live-stream status. Not paginated. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1375
|
+
import_zod.z.object({
|
|
1376
|
+
user_id: str("Kuaishou user id (non-empty); get one from user_resolve or search_users.")
|
|
1377
|
+
}),
|
|
1378
|
+
(i) => client.kuaishou.userLive(i)
|
|
1379
|
+
),
|
|
1380
|
+
tool(
|
|
1381
|
+
"KUAISHOU_USER_RESOLVE",
|
|
1382
|
+
"Scavio Kuaishou User Resolve",
|
|
1383
|
+
"Turns a Kuaishou share link into a user id. Only kuaishou.com and v.kuaishou.com links are accepted; Kwai international (kwai.com) is not served upstream. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1384
|
+
import_zod.z.object({
|
|
1385
|
+
share_link: str("A kuaishou.com or v.kuaishou.com URL; kwai.com links are rejected.")
|
|
1386
|
+
}),
|
|
1387
|
+
(i) => client.kuaishou.userResolve(i)
|
|
1388
|
+
),
|
|
1389
|
+
tool(
|
|
1390
|
+
"KUAISHOU_VIDEO",
|
|
1391
|
+
"Scavio Kuaishou Video",
|
|
1392
|
+
"A single Kuaishou video by photo id or URL. Provide photo_id or url. Costs 2 credits: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1393
|
+
import_zod.z.object({
|
|
1394
|
+
photo_id: ostr("Kuaishou photo (video) id, non-empty."),
|
|
1395
|
+
url: ostr("Full kuaishou.com video URL, as an alternative to photo_id.")
|
|
1396
|
+
}),
|
|
1397
|
+
(i) => client.kuaishou.video(i)
|
|
1398
|
+
),
|
|
1399
|
+
tool(
|
|
1400
|
+
"KUAISHOU_VIDEO_COMMENTS",
|
|
1401
|
+
"Scavio Kuaishou Video Comments",
|
|
1402
|
+
"Comments on a Kuaishou video, cursor-paginated via next_cursor. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1403
|
+
import_zod.z.object({
|
|
1404
|
+
photo_id: str("Kuaishou photo (video) id, non-empty."),
|
|
1405
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1406
|
+
}),
|
|
1407
|
+
(i) => client.kuaishou.videoComments(i)
|
|
1408
|
+
),
|
|
1409
|
+
tool(
|
|
1410
|
+
"KUAISHOU_COMMENT_REPLIES",
|
|
1411
|
+
"Scavio Kuaishou Comment Replies",
|
|
1412
|
+
"Replies under a root comment on a Kuaishou video, cursor-paginated via next_cursor; count sizes the page (1-50). Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1413
|
+
import_zod.z.object({
|
|
1414
|
+
photo_id: str("Kuaishou photo (video) id, non-empty."),
|
|
1415
|
+
root_comment_id: str("Id of the top-level comment whose replies you want, from video_comments."),
|
|
1416
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page."),
|
|
1417
|
+
count: onum("Replies per page, 1-50. Omit to use the upstream default.")
|
|
1418
|
+
}),
|
|
1419
|
+
(i) => client.kuaishou.commentReplies(i)
|
|
1420
|
+
),
|
|
1421
|
+
tool(
|
|
1422
|
+
"KUAISHOU_VIDEOS_BATCH",
|
|
1423
|
+
"Scavio Kuaishou Videos Batch",
|
|
1424
|
+
"Several Kuaishou videos in one call, hard-capped at 20 photo ids. Costs 40 credits, the dearest call on the platform: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1425
|
+
import_zod.z.object({
|
|
1426
|
+
photo_ids: arrstr("Kuaishou photo (video) ids, 1-20 per call; more than 20 is rejected.")
|
|
1427
|
+
}),
|
|
1428
|
+
(i) => client.kuaishou.videosBatch(i)
|
|
1429
|
+
),
|
|
1430
|
+
tool(
|
|
1431
|
+
"KUAISHOU_SEARCH",
|
|
1432
|
+
"Scavio Kuaishou Search",
|
|
1433
|
+
"Mixed-result search across Kuaishou, cursor-paginated via next_cursor. Costs 10 credits per page: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1434
|
+
import_zod.z.object({
|
|
1435
|
+
keyword: str("Search keyword, 1-200 characters."),
|
|
1436
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1437
|
+
}),
|
|
1438
|
+
(i) => client.kuaishou.search(i)
|
|
1439
|
+
),
|
|
1440
|
+
tool(
|
|
1441
|
+
"KUAISHOU_SEARCH_VIDEOS",
|
|
1442
|
+
"Scavio Kuaishou Search Videos",
|
|
1443
|
+
"Kuaishou video search results, cursor-paginated via next_cursor. Costs 10 credits per page: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1444
|
+
import_zod.z.object({
|
|
1445
|
+
keyword: str("Search keyword, 1-200 characters."),
|
|
1446
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1447
|
+
}),
|
|
1448
|
+
(i) => client.kuaishou.searchVideos(i)
|
|
1449
|
+
),
|
|
1450
|
+
tool(
|
|
1451
|
+
"KUAISHOU_SEARCH_USERS",
|
|
1452
|
+
"Scavio Kuaishou Search Users",
|
|
1453
|
+
"Kuaishou user search results, cursor-paginated via next_cursor. Costs 10 credits per page: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1454
|
+
import_zod.z.object({
|
|
1455
|
+
keyword: str("Search keyword, 1-200 characters."),
|
|
1456
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1457
|
+
}),
|
|
1458
|
+
(i) => client.kuaishou.searchUsers(i)
|
|
1459
|
+
),
|
|
1460
|
+
tool(
|
|
1461
|
+
"KUAISHOU_SEARCH_LIVE",
|
|
1462
|
+
"Scavio Kuaishou Search Live",
|
|
1463
|
+
"Kuaishou live-stream search results, cursor-paginated via next_cursor. Costs 10 credits per page: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1464
|
+
import_zod.z.object({
|
|
1465
|
+
keyword: str("Search keyword, 1-200 characters."),
|
|
1466
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1467
|
+
}),
|
|
1468
|
+
(i) => client.kuaishou.searchLive(i)
|
|
1469
|
+
),
|
|
1470
|
+
tool(
|
|
1471
|
+
"KUAISHOU_TAG_FEED",
|
|
1472
|
+
"Scavio Kuaishou Tag Feed",
|
|
1473
|
+
"Posts under a Kuaishou hashtag, cursor-paginated via next_cursor. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1474
|
+
import_zod.z.object({
|
|
1475
|
+
tag: str("Hashtag text without the leading '#', 1-200 characters."),
|
|
1476
|
+
cursor: ostr("Opaque next_cursor from a prior response; omit for the first page.")
|
|
1477
|
+
}),
|
|
1478
|
+
(i) => client.kuaishou.tagFeed(i)
|
|
1479
|
+
),
|
|
1480
|
+
tool(
|
|
1481
|
+
"KUAISHOU_TRENDING",
|
|
1482
|
+
"Scavio Kuaishou Trending",
|
|
1483
|
+
"Kuaishou hot / live / shopping / brand / music leaderboards. One board per call, not paginated. Costs 1 credit: Kuaishou is priced PER ENDPOINT (1, 2, 10 or 40), never per platform.",
|
|
1484
|
+
import_zod.z.object({
|
|
1485
|
+
board: ostr("Leaderboard to return; defaults to 'hot' when omitted. Accepted values: 'hot', 'live', 'shopping', 'brand', 'music'.")
|
|
1486
|
+
}),
|
|
1487
|
+
(i) => client.kuaishou.trending(i)
|
|
1488
|
+
)
|
|
1489
|
+
);
|
|
1490
|
+
}
|
|
1491
|
+
if (all || enableEbay) {
|
|
1492
|
+
tools.push(
|
|
1493
|
+
tool(
|
|
1494
|
+
"EBAY_SEARCH",
|
|
1495
|
+
"Scavio eBay Search",
|
|
1496
|
+
"Search live or SOLD eBay listings: price, condition, bids, shipping, seller, feedback. Provide query or seller; per_page accepts only 60, 120 or 240. Costs 1 credit.",
|
|
1497
|
+
import_zod.z.object({
|
|
1498
|
+
query: ostr("Keyword to search (1-500 characters). Optional: a seller-only search pages that seller's whole catalogue."),
|
|
1499
|
+
seller: ostr("Restrict results to one seller's listings (1-64 characters), as in ebay.com/usr/<name>. Can be sent with no query."),
|
|
1500
|
+
page: onum("Results page, 1-based."),
|
|
1501
|
+
sort_by: ostr("Result sort order. Defaults to 'best_match'. eBay's 'Distance: nearest first' is deliberately unsupported (it ranks against our proxy exit, not the caller). Accepted values: 'best_match', 'ending_soonest', 'newly_listed', 'price_low', 'price_high'."),
|
|
1502
|
+
min_price: onum("Minimum price, inclusive. Must be 0 or greater."),
|
|
1503
|
+
max_price: onum("Maximum price, inclusive. Must be 0 or greater."),
|
|
1504
|
+
condition: ostr("Item condition filter. 'refurbished' is eBay's parent condition, not one of its three graded tiers. Accepted values: 'new', 'open_box', 'refurbished', 'used', 'for_parts'."),
|
|
1505
|
+
buying_format: ostr("Listing format: auction, fixed price (buy_it_now), or fixed price accepting offers (best_offer)."),
|
|
1506
|
+
free_shipping: obool("Only listings with free shipping."),
|
|
1507
|
+
sold: obool("Search completed listings that actually SOLD, for price research. eBay publishes no headline count on this view, so total_results is null."),
|
|
1508
|
+
category_id: ostr("eBay category id; must be numeric (e.g. '112529'). An unrecognised id returns the UNFILTERED set under a 200."),
|
|
1509
|
+
per_page: onum("Listings per page: 60, 120 or 240 only. Defaults to 60; eBay silently falls back to 60 for anything else.")
|
|
1510
|
+
}),
|
|
1511
|
+
(i) => client.ebay.search(i)
|
|
1512
|
+
),
|
|
1513
|
+
tool(
|
|
1514
|
+
"EBAY_PRODUCT",
|
|
1515
|
+
"Scavio eBay Product",
|
|
1516
|
+
"One eBay listing in full: price, condition, images, item specifics, shipping, returns, auction state, seller. Costs 1 credit.",
|
|
1517
|
+
import_zod.z.object({
|
|
1518
|
+
item_id: str("eBay item number (e.g. '168591664725'), or a full ebay.com/itm/... listing URL; tracking parameters on a pasted URL are discarded.")
|
|
1519
|
+
}),
|
|
1520
|
+
(i) => client.ebay.product(i)
|
|
1521
|
+
),
|
|
1522
|
+
tool(
|
|
1523
|
+
"EBAY_SELLER",
|
|
1524
|
+
"Scavio eBay Seller",
|
|
1525
|
+
"eBay seller profile card: store name, feedback score and %, items sold, followers, location, categories. Profile only: page a catalogue with search(seller=...). Costs 1 credit.",
|
|
1526
|
+
import_zod.z.object({
|
|
1527
|
+
seller: str("eBay username as it appears in ebay.com/usr/<name> (1-64 characters), which is what seller_name on a search or product result returns.")
|
|
1528
|
+
}),
|
|
1529
|
+
(i) => client.ebay.seller(i)
|
|
1530
|
+
)
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
if (all || enableTarget) {
|
|
1534
|
+
tools.push(
|
|
1535
|
+
tool(
|
|
1536
|
+
"TARGET_SEARCH",
|
|
1537
|
+
"Scavio Target Search",
|
|
1538
|
+
"Search Target.com, the US retailer: prices, ratings, badges and promotions. Up to 28 results per page; rendered upstream, so expect around 9 seconds. Costs 1 credit.",
|
|
1539
|
+
import_zod.z.object({
|
|
1540
|
+
keyword: str("Search keyword (1-500 characters)."),
|
|
1541
|
+
page: onum("Results page, 1-based."),
|
|
1542
|
+
count: onum("Results per page, 1-28. Defaults to 24; Target rejects anything above 28 outright."),
|
|
1543
|
+
sort: ostr("Result sort order. Defaults to 'relevance'. Accepted values: 'relevance', 'featured', 'price_low', 'price_high', 'rating_high', 'best_seller', 'newest'."),
|
|
1544
|
+
store_id: ostr("Numeric Target store id whose prices and availability the response reflects. Defaults to '3991', the store target.com uses with no store context.")
|
|
1545
|
+
}),
|
|
1546
|
+
(i) => client.target.search(i)
|
|
1547
|
+
),
|
|
1548
|
+
tool(
|
|
1549
|
+
"TARGET_CATEGORY",
|
|
1550
|
+
"Scavio Target Category",
|
|
1551
|
+
"Products in a Target category, same shape as search plus the category breadcrumb. Up to 28 per page; the slowest Target endpoint at around 37 seconds. Costs 1 credit.",
|
|
1552
|
+
import_zod.z.object({
|
|
1553
|
+
category_id: str("Target category id: the segment after 'N-' in a target.com /c/ URL (target.com/c/apple/-/N-5xtg6 -> '5xtg6')."),
|
|
1554
|
+
page: onum("Results page, 1-based."),
|
|
1555
|
+
count: onum("Results per page, 1-28. Defaults to 24; Target rejects anything above 28 outright."),
|
|
1556
|
+
sort: ostr("Result sort order. Defaults to 'relevance'. Accepted values: 'relevance', 'featured', 'price_low', 'price_high', 'rating_high', 'best_seller', 'newest'."),
|
|
1557
|
+
store_id: ostr("Numeric Target store id whose prices and availability the response reflects. Defaults to '3991'.")
|
|
1558
|
+
}),
|
|
1559
|
+
(i) => client.target.category(i)
|
|
1560
|
+
),
|
|
1561
|
+
tool(
|
|
1562
|
+
"TARGET_PRODUCT",
|
|
1563
|
+
"Scavio Target Product",
|
|
1564
|
+
"Target product details by TCIN: price, rating, images, specifications, variants, return policy, fulfillment. seller_id/seller_name are null for stock sold by Target. Costs 1 credit.",
|
|
1565
|
+
import_zod.z.object({
|
|
1566
|
+
tcin: str("Target catalog id (tcin, e.g. '1010453160'). A colour/size child tcin is answered by its variation parent, with the child present in 'variants'."),
|
|
1567
|
+
store_id: ostr("Numeric Target store id whose prices and availability the response reflects. Defaults to '3991'.")
|
|
1568
|
+
}),
|
|
1569
|
+
(i) => client.target.product(i)
|
|
1570
|
+
),
|
|
1571
|
+
tool(
|
|
1572
|
+
"TARGET_REVIEWS",
|
|
1573
|
+
"Scavio Target Reviews",
|
|
1574
|
+
"Target reviews with the rating breakdown, per-attribute averages and guest photos. 8 review bodies maximum and no paging; expect around 40 seconds. Costs 1 credit.",
|
|
1575
|
+
import_zod.z.object({
|
|
1576
|
+
tcin: str("Target catalog id (tcin, e.g. '1010453160')."),
|
|
1577
|
+
limit: onum("Trim the returned reviews to at most this many (1 or greater). Target publishes 8 anonymously and offers no paging, so this only trims."),
|
|
1578
|
+
store_id: ostr("Numeric Target store id whose prices and availability the response reflects. Defaults to '3991'.")
|
|
1579
|
+
}),
|
|
1580
|
+
(i) => client.target.reviews(i)
|
|
1581
|
+
)
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
if (all || enableHomeDepot) {
|
|
1585
|
+
tools.push(
|
|
1586
|
+
tool(
|
|
1587
|
+
"HOME_DEPOT_SEARCH",
|
|
1588
|
+
"Scavio Home Depot Search",
|
|
1589
|
+
"Search Home Depot: price and promotions, brand and model, ratings, badges, per-store pickup/delivery. Page size is fixed at 12 and cannot be changed. Costs 2 credits.",
|
|
1590
|
+
import_zod.z.object({
|
|
1591
|
+
query: str("Search keyword (1-500 characters)."),
|
|
1592
|
+
page: onum("Results page, 1-based. Home Depot serves 12 products per page and offers no way to change that, so paging is the only way to read further."),
|
|
1593
|
+
sort_by: ostr("Result sort order. Defaults to 'best_match'. Closed enum: Home Depot answers an unknown sort with an empty page that is still billed. 'Newest' is absent - it is rejected on keyword search. Accepted values: 'best_match', 'top_sellers', 'top_rated', 'price_low', 'price_high'."),
|
|
1594
|
+
min_price: onum("Minimum price, inclusive. Must be 0 or greater."),
|
|
1595
|
+
max_price: onum("Maximum price, inclusive. Must be 0 or greater.")
|
|
1596
|
+
}),
|
|
1597
|
+
(i) => client.homeDepot.search(i)
|
|
1598
|
+
),
|
|
1599
|
+
tool(
|
|
1600
|
+
"HOME_DEPOT_PRODUCT",
|
|
1601
|
+
"Scavio Home Depot Product",
|
|
1602
|
+
"Full Home Depot item detail: pricing, images and videos, spec table, dimensions, bullets, documents, return policy. Carries a 10-review preview only. Costs 2 credits.",
|
|
1603
|
+
import_zod.z.object({
|
|
1604
|
+
item_id: str("Home Depot item id (e.g. '325479354'), or a full homedepot.com/p/... product URL; tracking parameters on a pasted URL are discarded.")
|
|
1605
|
+
}),
|
|
1606
|
+
(i) => client.homeDepot.product(i)
|
|
1607
|
+
),
|
|
1608
|
+
tool(
|
|
1609
|
+
"HOME_DEPOT_REVIEWS",
|
|
1610
|
+
"Scavio Home Depot Reviews",
|
|
1611
|
+
"One page of full Home Depot review bodies, the rating distribution, per-attribute ratings, photos and seller responses. 30 reviews per page. Costs 2 credits.",
|
|
1612
|
+
import_zod.z.object({
|
|
1613
|
+
item_id: str("Home Depot item id (e.g. '325479354'), or a full homedepot.com/p/... product URL; tracking parameters on a pasted URL are discarded."),
|
|
1614
|
+
page: onum("Reviews page, 1-based. 30 reviews per page; 'total_pages' in the response is the last one that exists, and asking past it is a 404.")
|
|
1615
|
+
}),
|
|
1616
|
+
(i) => client.homeDepot.reviews(i)
|
|
1617
|
+
)
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
if (all || enableZillow) {
|
|
1621
|
+
tools.push(
|
|
1622
|
+
tool(
|
|
1623
|
+
"ZILLOW_SEARCH",
|
|
1624
|
+
"Scavio Zillow Search",
|
|
1625
|
+
"Zillow listings in a region: price, beds, baths, living area, Zestimate, coordinates, images, days on market. A bare ZIP works alone but cannot be combined with a filter or a sort. Costs 1 credit.",
|
|
1626
|
+
import_zod.z.object({
|
|
1627
|
+
location: str("Region to search (1-200 characters): a Zillow slug ('austin-tx'), a human form ('Austin, TX'), a ZIP, or a pasted zillow.com search URL. A ZIP works alone but cannot be combined with a filter or sort; an unresolvable region is a 404."),
|
|
1628
|
+
listing_status: ostr("Which listings to return. Defaults to 'for_sale'. Accepted values: 'for_sale', 'for_rent', 'sold'."),
|
|
1629
|
+
page: onum("Results page, 1-based."),
|
|
1630
|
+
sort: ostr("Result sort order. Sorts that rank against a signed-in profile (saved/featured/personalised) are unsupported - we are never signed in. Accepted values: 'relevance', 'recommended', 'newest', 'price_low', 'price_high', 'payment_low', 'payment_high', 'beds', 'baths', 'sqft', 'lot_size', 'zestimate_low', 'zestimate_high', 'recent_change'."),
|
|
1631
|
+
min_price: onum("Minimum price, inclusive (0 or greater). On listing_status='for_rent' this is MONTHLY RENT - Zillow files rent under its payment filter."),
|
|
1632
|
+
max_price: onum("Maximum price, inclusive (0 or greater). On listing_status='for_rent' this is MONTHLY RENT."),
|
|
1633
|
+
beds_min: onum("Minimum bedrooms; whole number, 0 or greater."),
|
|
1634
|
+
beds_max: onum("Maximum bedrooms; whole number, 0 or greater."),
|
|
1635
|
+
baths_min: onum("Minimum bathrooms, 0 or greater. Half-baths are allowed (1.5)."),
|
|
1636
|
+
baths_max: onum("Maximum bathrooms, 0 or greater. Half-baths are allowed (1.5)."),
|
|
1637
|
+
sqft_min: onum("Minimum living area in square feet; whole number, 0 or greater."),
|
|
1638
|
+
sqft_max: onum("Maximum living area in square feet; whole number, 0 or greater."),
|
|
1639
|
+
lot_size_min: onum("Minimum lot size in square feet; whole number, 0 or greater."),
|
|
1640
|
+
lot_size_max: onum("Maximum lot size in square feet; whole number, 0 or greater."),
|
|
1641
|
+
year_built_min: onum("Earliest year built; whole number, 0 or greater."),
|
|
1642
|
+
year_built_max: onum("Latest year built; whole number, 0 or greater."),
|
|
1643
|
+
max_hoa: onum("Maximum monthly HOA fee in dollars, 0 or greater."),
|
|
1644
|
+
home_type: ostr("Property type filter. Accepted values: 'houses', 'townhomes', 'multi_family', 'condos', 'apartments', 'manufactured', 'lots_land'."),
|
|
1645
|
+
days_on_zillow: ostr("Listed - or, with listing_status='sold', sold - within the last N days. Closed enum: an unrecognised value returns the UNFILTERED set under a 200. Accepted values: '1', '7', '14', '30', '90', '6m', '12m', '24m', '36m'."),
|
|
1646
|
+
keywords: ostr("Free-text match against the listing description (1-200 characters)."),
|
|
1647
|
+
has_pool: obool("Only listings with a pool."),
|
|
1648
|
+
has_garage: obool("Only listings with a garage."),
|
|
1649
|
+
has_air_conditioning: obool("Only listings with air conditioning."),
|
|
1650
|
+
is_waterfront: obool("Only waterfront listings."),
|
|
1651
|
+
has_basement: obool("Only listings with a basement."),
|
|
1652
|
+
is_new_construction: obool("Only new-construction listings."),
|
|
1653
|
+
has_open_house: obool("Only listings with an upcoming open house."),
|
|
1654
|
+
price_reduced: obool("Only listings whose price was reduced."),
|
|
1655
|
+
is_3d_tour: obool("Only listings with a 3D tour.")
|
|
1656
|
+
}),
|
|
1657
|
+
(i) => client.zillow.search(i)
|
|
1658
|
+
),
|
|
1659
|
+
tool(
|
|
1660
|
+
"ZILLOW_PROPERTY",
|
|
1661
|
+
"Scavio Zillow Property",
|
|
1662
|
+
"Full Zillow listing: price and price history, Zestimate, tax history, RESO facts, rooms, schools, open houses, photos. Rental buildings return floor plans instead. Costs 1 credit.",
|
|
1663
|
+
import_zod.z.object({
|
|
1664
|
+
zpid: str("Zillow property id (e.g. '29414894'), a full /homedetails/ URL, or a rental building URL (zillow.com/apartments/...). The building form is required for buildings: they have no zpid a caller can see.")
|
|
1665
|
+
}),
|
|
1666
|
+
(i) => client.zillow.property(i)
|
|
1667
|
+
),
|
|
1668
|
+
tool(
|
|
1669
|
+
"ZILLOW_AGENT_REVIEWS",
|
|
1670
|
+
"Scavio Zillow Agent Reviews",
|
|
1671
|
+
"A Zillow AGENT's profile and reviews: rating, bodies with sub-ratings, specialties, licenses, service areas, sales counts. Zillow server-renders the first five. Costs 1 credit.",
|
|
1672
|
+
import_zod.z.object({
|
|
1673
|
+
screen_name: str("Zillow agent profile screen name as it appears in zillow.com/profile/<name>/ (1-200 characters, may contain spaces), or a full profile URL.")
|
|
1674
|
+
}),
|
|
1675
|
+
(i) => client.zillow.agentReviews(i)
|
|
1676
|
+
)
|
|
1677
|
+
);
|
|
1678
|
+
}
|
|
1679
|
+
if (all || enableBooking) {
|
|
1680
|
+
tools.push(
|
|
1681
|
+
tool(
|
|
1682
|
+
"BOOKING_SEARCH",
|
|
1683
|
+
"Scavio Booking.com Search",
|
|
1684
|
+
"Booking.com properties for a destination and stay: live nightly price, review score, star rating, location, room type, deal badges. 25 properties per page. Provide destination or dest_id. Costs 1 credit.",
|
|
1685
|
+
import_zod.z.object({
|
|
1686
|
+
destination: ostr("Destination to search, e.g. 'Paris' (1-200 characters). Required unless dest_id is given."),
|
|
1687
|
+
dest_id: ostr("Numeric Booking.com destination id, as an alternative to destination."),
|
|
1688
|
+
dest_type: ostr("What dest_id refers to. Requires dest_id and is rejected without it, because Booking silently ignores a lone dest_type. Accepted values: 'city', 'region', 'country', 'district', 'landmark', 'airport', 'hotel'."),
|
|
1689
|
+
page: onum("Results page, 1-based. 25 properties per page, 1 credit each."),
|
|
1690
|
+
sort_by: ostr("Result sort order (default 'popularity'). Accepted values: 'popularity', 'price_low', 'price_high', 'stars_high', 'stars_low', 'stars_and_price', 'distance', 'review_score'."),
|
|
1691
|
+
min_price: onum("Minimum price PER NIGHT in `currency`, >= 0. Must not exceed max_price."),
|
|
1692
|
+
max_price: onum("Maximum price PER NIGHT in `currency`, >= 0."),
|
|
1693
|
+
stars: oarrnum("Star ratings to include, each 1-5, 1-5 values, OR'd together (e.g. [4, 5])."),
|
|
1694
|
+
min_review_score: ostr("Minimum guest review score. Only '6', '7', '8' and '9' exist upstream; any other threshold is silently dropped."),
|
|
1695
|
+
property_type: ostrnum("Accommodation type by name, or a raw numeric Booking accommodation-type id (>= 1). Accepted values: 'apartments', 'hostels', 'hotels', 'motels', 'resorts', 'bed_and_breakfasts', 'villas', 'campgrounds', 'vacation_homes', 'lodges', 'homestays'."),
|
|
1696
|
+
free_cancellation: obool("Only properties offering free cancellation."),
|
|
1697
|
+
no_prepayment: obool("Only properties that take no prepayment."),
|
|
1698
|
+
breakfast_included: obool("Only rates that include breakfast."),
|
|
1699
|
+
checkin: ostr("Check-in date, YYYY-MM-DD. Must be sent together with checkout: a lone checkin is ignored and Booking prices a default range of its own."),
|
|
1700
|
+
checkout: ostr("Check-out date, YYYY-MM-DD. Must be later than checkin and sent together with it."),
|
|
1701
|
+
adults: onum("Adult guests, >= 1 (default 2)."),
|
|
1702
|
+
children_ages: oarrnum("AGES of accompanying children, each 0-17, max 10 entries. Ages, not a count."),
|
|
1703
|
+
rooms: onum("Rooms required, >= 1 (default 1)."),
|
|
1704
|
+
currency: ostr("ISO 4217 currency for prices, 3 letters (default 'USD'). Without it Booking prices off the proxy exit and identical requests disagree.")
|
|
1705
|
+
}),
|
|
1706
|
+
(i) => client.booking.search(i)
|
|
1707
|
+
),
|
|
1708
|
+
tool(
|
|
1709
|
+
"BOOKING_HOTEL",
|
|
1710
|
+
"Scavio Booking.com Hotel",
|
|
1711
|
+
"One Booking.com property in full: rooms and rate plans, facilities, house rules, check-in windows, policies, images, location and review scores, priced for the stay asked for. Chaining the `url` a search row returns is cheaper than a bare slug. Costs 1 credit.",
|
|
1712
|
+
import_zod.z.object({
|
|
1713
|
+
hotel: str("Booking.com property URL or the bare page slug (1-500 characters); query params are discarded."),
|
|
1714
|
+
country_code: ostr("Two-letter country code for the property page (default 'us'). Only consulted for a bare slug, where a wrong one is a real, BILLED 404."),
|
|
1715
|
+
checkin: ostr("Check-in date, YYYY-MM-DD. Must be sent together with checkout; omitting both prices a two-night range Booking chose, echoed back in the response."),
|
|
1716
|
+
checkout: ostr("Check-out date, YYYY-MM-DD. Must be later than checkin and sent together with it."),
|
|
1717
|
+
adults: onum("Adult guests, >= 1 (default 2)."),
|
|
1718
|
+
children_ages: oarrnum("AGES of accompanying children, each 0-17, max 10 entries. Ages, not a count."),
|
|
1719
|
+
rooms: onum("Rooms required, >= 1 (default 1)."),
|
|
1720
|
+
currency: ostr("ISO 4217 currency for prices, 3 letters (default 'USD'). Without it Booking prices off the proxy exit and identical requests disagree.")
|
|
1721
|
+
}),
|
|
1722
|
+
(i) => client.booking.hotel(i)
|
|
1723
|
+
),
|
|
1724
|
+
tool(
|
|
1725
|
+
"BOOKING_REVIEWS",
|
|
1726
|
+
"Scavio Booking.com Reviews",
|
|
1727
|
+
"Booking.com guest reviews for a property with the score breakdown by category and Booking's own praise/complaint summary. No page param: total_count is the whole review history, count is what this response holds. Costs 1 credit.",
|
|
1728
|
+
import_zod.z.object({
|
|
1729
|
+
hotel: str("Booking.com property URL or the bare page slug (1-500 characters); query params are discarded."),
|
|
1730
|
+
country_code: ostr("Two-letter country code for the property page (default 'us'). Only consulted for a bare slug, where a wrong one is a real, BILLED 404."),
|
|
1731
|
+
checkin: ostr("Check-in date, YYYY-MM-DD. Must be sent together with checkout; it prices the stay the review page is rendered for."),
|
|
1732
|
+
checkout: ostr("Check-out date, YYYY-MM-DD. Must be later than checkin and sent together with it."),
|
|
1733
|
+
adults: onum("Adult guests, >= 1 (default 2)."),
|
|
1734
|
+
children_ages: oarrnum("AGES of accompanying children, each 0-17, max 10 entries. Ages, not a count."),
|
|
1735
|
+
rooms: onum("Rooms required, >= 1 (default 1)."),
|
|
1736
|
+
currency: ostr("ISO 4217 currency for prices, 3 letters (default 'USD').")
|
|
1737
|
+
}),
|
|
1738
|
+
(i) => client.booking.reviews(i)
|
|
1739
|
+
)
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1742
|
+
if (all || enableTripadvisor) {
|
|
1743
|
+
tools.push(
|
|
1744
|
+
tool(
|
|
1745
|
+
"TRIPADVISOR_LOCATIONS",
|
|
1746
|
+
"Scavio Tripadvisor Locations",
|
|
1747
|
+
"START HERE: resolve a place or business NAME to the TripAdvisor geo_id / location_id pair every other TripAdvisor endpoint is keyed by. Up to 20 rows. Costs 2 credits.",
|
|
1748
|
+
import_zod.z.object({
|
|
1749
|
+
query: str("Place or business name to resolve (1-120 characters)."),
|
|
1750
|
+
limit: onum("Rows to return, 1-20 (default 12). Sizes the response only; there is no paging here.")
|
|
1751
|
+
}),
|
|
1752
|
+
(i) => client.tripadvisor.locations(i)
|
|
1753
|
+
),
|
|
1754
|
+
tool(
|
|
1755
|
+
"TRIPADVISOR_SEARCH",
|
|
1756
|
+
"Scavio Tripadvisor Search",
|
|
1757
|
+
"Restaurants, hotels or attractions in a TripAdvisor geo, TripAdvisor-ranked: rating, review count, price band, address, coordinates, phone, hours, Travelers' Choice badge; each row carries the location_id + geo_id pair. 30 locations per page. Provide geo_id or url. Costs 2 credits.",
|
|
1758
|
+
import_zod.z.object({
|
|
1759
|
+
geo_id: ostr("TripAdvisor geo id (1-500 characters): 30196, g30196, or a URL carrying one. Required unless url is given."),
|
|
1760
|
+
category: ostr("Listing family to search (default 'restaurants'). Accepted values: 'restaurants', 'hotels', 'attractions'."),
|
|
1761
|
+
page: onum("Results page, 1-based. 30 locations per page; a page beyond the last is a 404, not an empty result."),
|
|
1762
|
+
url: ostr("Full tripadvisor.com listing URL (1-500 characters), as an alternative to geo_id; country sites are accepted.")
|
|
1763
|
+
}),
|
|
1764
|
+
(i) => client.tripadvisor.search(i)
|
|
1765
|
+
),
|
|
1766
|
+
tool(
|
|
1767
|
+
"TRIPADVISOR_LOCATION",
|
|
1768
|
+
"Scavio Tripadvisor Location",
|
|
1769
|
+
"One TripAdvisor location in full: rating, review histogram and per-aspect sub-ratings, city ranking, price band, cuisines, amenities, address, coordinates, contact, photos, and the FIRST PAGE OF REVIEWS. Provide location_id or url. Costs 2 credits.",
|
|
1770
|
+
import_zod.z.object({
|
|
1771
|
+
location_id: ostr("TripAdvisor location id (1-500 characters): 1899234, d1899234, or a full _Review URL. Required unless url is given."),
|
|
1772
|
+
geo_id: ostr("Geo the location sits in; required when location_id is a bare d-id."),
|
|
1773
|
+
category: ostr("Location family (default 'restaurants'); match the location's own type. Accepted values: 'restaurants', 'hotels', 'attractions'."),
|
|
1774
|
+
url: ostr("Full tripadvisor.com _Review URL (1-500 characters), as an alternative to location_id.")
|
|
1775
|
+
}),
|
|
1776
|
+
(i) => client.tripadvisor.location(i)
|
|
1777
|
+
),
|
|
1778
|
+
tool(
|
|
1779
|
+
"TRIPADVISOR_REVIEWS",
|
|
1780
|
+
"Scavio Tripadvisor Reviews",
|
|
1781
|
+
"A page of TripAdvisor reviews: rating, trip date and type, reviewer home town and contribution count, management response. Page 1 already rides along in location(), so use this to page PAST it; consecutive pages can repeat one review at the boundary, so de-duplicate on review_id. Provide location_id or url. Costs 2 credits.",
|
|
1782
|
+
import_zod.z.object({
|
|
1783
|
+
location_id: ostr("TripAdvisor location id (1-500 characters): 1899234, d1899234, or a full _Review URL. Required unless url is given."),
|
|
1784
|
+
geo_id: ostr("Geo the location sits in; required when location_id is a bare d-id."),
|
|
1785
|
+
category: ostr("Location family (default 'restaurants'). It sets the page size, so it must match the location's own type on any page past the first. Accepted values: 'restaurants', 'hotels', 'attractions'."),
|
|
1786
|
+
url: ostr("Full tripadvisor.com _Review URL (1-500 characters), as an alternative to location_id."),
|
|
1787
|
+
page: onum("Reviews page, 1-based. 15 per page for restaurants, 10 for hotels and attractions; past the last page is a 404.")
|
|
1788
|
+
}),
|
|
1789
|
+
(i) => client.tripadvisor.reviews(i)
|
|
1790
|
+
)
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1793
|
+
if (all || enableIndeed) {
|
|
1794
|
+
tools.push(
|
|
1795
|
+
tool(
|
|
1796
|
+
"INDEED_SEARCH",
|
|
1797
|
+
"Scavio Indeed Search",
|
|
1798
|
+
"Indeed job postings: title, employer, rating, location, salary range, job type, benefits, posting age, apply route. 10 postings per page. Provide query or location - a location-only search (every posting in a metro) is valid. Costs 2 credits.",
|
|
1799
|
+
import_zod.z.object({
|
|
1800
|
+
query: ostr("Job title, keywords or employer (1-500 characters). Required unless location is given."),
|
|
1801
|
+
location: ostr("City and state, postal code, state, country, or 'Remote' (1-200 characters). Valid on its own with no query."),
|
|
1802
|
+
page: onum("Results page, 1-based. 10 postings per page, 1 call each."),
|
|
1803
|
+
radius: onum("Search radius in miles around location. Closed set: Indeed IGNORES any other value and returns the unfiltered set. Upstream default 50. Accepted values: 0, 5, 10, 15, 25, 35, 50, 100."),
|
|
1804
|
+
max_age_days: onum("Maximum posting age in days. Closed set: Indeed IGNORES any other value and returns postings of every age. Accepted values: 1, 3, 7, 14."),
|
|
1805
|
+
job_type: ostr("Employment type filter. Accepted values: 'full_time', 'part_time', 'contract', 'temporary', 'internship'."),
|
|
1806
|
+
min_salary: onum("Minimum annual salary, >= 0. Filters on INDEED'S OWN ESTIMATE for the role, not a posted figure, so postings publishing no salary still match."),
|
|
1807
|
+
remote: obool("Remote postings only.")
|
|
1808
|
+
}),
|
|
1809
|
+
(i) => client.indeed.search(i)
|
|
1810
|
+
),
|
|
1811
|
+
tool(
|
|
1812
|
+
"INDEED_JOB",
|
|
1813
|
+
"Scavio Indeed Job",
|
|
1814
|
+
"One Indeed posting in full: description text and HTML, structured salary, employment types, benefits, geocoded address, employer rating, applicant count, original ATS link. An unknown job key is a real 404 that is still billed. Costs 2 credits.",
|
|
1815
|
+
import_zod.z.object({
|
|
1816
|
+
job_id: str("16-hex Indeed job key, or any indeed.com URL carrying jk= (/viewjob, /rc/clk, /pagead/clk).")
|
|
1817
|
+
}),
|
|
1818
|
+
(i) => client.indeed.job(i)
|
|
1819
|
+
),
|
|
1820
|
+
tool(
|
|
1821
|
+
"INDEED_COMPANY",
|
|
1822
|
+
"Scavio Indeed Company",
|
|
1823
|
+
"Indeed employer profile: description, industry, HQ, size, revenue, CEO approval, overall and per-category ratings, reported salaries, open roles, locations. An unknown slug is a real 404 that is still billed. Costs 2 credits.",
|
|
1824
|
+
import_zod.z.object({
|
|
1825
|
+
company: str("indeed.com/cmp/<slug> slug or a full profile URL (1-200 characters); slugs are untidy, e.g. 'Tata-Consultancy-Services-(tcs)'.")
|
|
1826
|
+
}),
|
|
1827
|
+
(i) => client.indeed.company(i)
|
|
1828
|
+
),
|
|
1829
|
+
tool(
|
|
1830
|
+
"INDEED_COMPANY_REVIEWS",
|
|
1831
|
+
"Scavio Indeed Company Reviews",
|
|
1832
|
+
"Indeed employee reviews, 20 per page, with per-category ratings, pros/cons, reviewer job title and location, plus aggregated sentiment and topic/location/job-title breakdowns. Costs 2 credits.",
|
|
1833
|
+
import_zod.z.object({
|
|
1834
|
+
company: str("indeed.com/cmp/<slug> slug or a full profile URL (1-200 characters)."),
|
|
1835
|
+
page: onum("Reviews page, 1-based. 20 reviews per page.")
|
|
1836
|
+
}),
|
|
1837
|
+
(i) => client.indeed.companyReviews(i)
|
|
1838
|
+
)
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
if (all || enableAirbnb) {
|
|
1842
|
+
tools.push(
|
|
1843
|
+
tool(
|
|
1844
|
+
"AIRBNB_SEARCH",
|
|
1845
|
+
"Scavio Airbnb Search",
|
|
1846
|
+
"Airbnb stays: stay-total and per-night price with the full discount ledger, rating and review count, bedrooms/beds/baths, coordinates, badges, images, dates_are_defaulted. 18 listings per page; page and cursor are mutually exclusive. Costs 1 credit.",
|
|
1847
|
+
import_zod.z.object({
|
|
1848
|
+
location: str("City, region, ZIP, or a pasted airbnb.com/s/ URL (1-200 characters). An unresolvable location is a 404."),
|
|
1849
|
+
check_in: ostr("Check-in date, YYYY-MM-DD. Must be sent with check_out; omitting both defaults to +30 days and flags dates_are_defaulted in the response."),
|
|
1850
|
+
check_out: ostr("Check-out date, YYYY-MM-DD. Must be later than check_in; defaults to check_in plus 5 nights when omitted."),
|
|
1851
|
+
adults: onum("Adult guests, >= 1."),
|
|
1852
|
+
children: onum("Children aged 2-12, >= 0."),
|
|
1853
|
+
infants: onum("Infants under 2, >= 0."),
|
|
1854
|
+
pets: onum("Pets, >= 0."),
|
|
1855
|
+
min_price: onum("Minimum price for the WHOLE STAY in `currency`, not per night, >= 0. Must not exceed max_price."),
|
|
1856
|
+
max_price: onum("Maximum price for the WHOLE STAY in `currency`, not per night, >= 0."),
|
|
1857
|
+
room_type: ostr("Room type. Validated before the scrape, because an unrecognised value returns the UNFILTERED set under a 200. Accepted values: 'entire_home', 'private_room', 'shared_room', 'hotel_room'."),
|
|
1858
|
+
min_bedrooms: onum("Minimum bedrooms, >= 0."),
|
|
1859
|
+
min_beds: onum("Minimum beds, >= 0."),
|
|
1860
|
+
min_bathrooms: onum("Minimum bathrooms, >= 0."),
|
|
1861
|
+
superhost: obool("Superhost listings only."),
|
|
1862
|
+
instant_book: obool("Instant Book listings only."),
|
|
1863
|
+
guest_favorite: obool("Guest Favorite listings only."),
|
|
1864
|
+
free_cancellation: obool("Listings with free cancellation only."),
|
|
1865
|
+
amenities: ostr("Comma-separated amenities (1-200 characters): wifi, air_conditioning, pool, kitchen, free_parking, washer, self_check_in, tv, or raw numeric Airbnb amenity ids. An unrecognised NAME is rejected before the scrape."),
|
|
1866
|
+
currency: ostr("ISO 4217 currency for prices, 3 letters (default 'USD'). Without it Airbnb prices off the proxy exit and identical requests disagree."),
|
|
1867
|
+
page: onum("Results page, 1-based. 18 listings per page. Cannot be combined with cursor."),
|
|
1868
|
+
cursor: ostr("next_cursor from a previous response (1-500 characters); wins over page, so sending both is rejected.")
|
|
1869
|
+
}),
|
|
1870
|
+
(i) => client.airbnb.search(i)
|
|
1871
|
+
),
|
|
1872
|
+
tool(
|
|
1873
|
+
"AIRBNB_LISTING",
|
|
1874
|
+
"Scavio Airbnb Listing",
|
|
1875
|
+
"One Airbnb listing in full: description, property/room type, capacity and room counts, the complete grouped amenity list (including what the place does NOT have), host profile and stats, house rules, cancellation policy, sleeping arrangements, photo tour and the RATING BREAKDOWN. Carries NO nightly price - prices are search-only. Costs 1 credit.",
|
|
1876
|
+
import_zod.z.object({
|
|
1877
|
+
listing_id: str("Airbnb listing id or a full /rooms/ URL (1-500 characters); query params are discarded, since they carry someone else's dates."),
|
|
1878
|
+
check_in: ostr("Check-in date, YYYY-MM-DD. Must be sent with check_out. Does not produce a price: the room page has no nightly rate."),
|
|
1879
|
+
check_out: ostr("Check-out date, YYYY-MM-DD. Must be later than check_in and sent together with it."),
|
|
1880
|
+
adults: onum("Adult guests, >= 1."),
|
|
1881
|
+
children: onum("Children aged 2-12, >= 0."),
|
|
1882
|
+
infants: onum("Infants under 2, >= 0."),
|
|
1883
|
+
pets: onum("Pets, >= 0."),
|
|
1884
|
+
currency: ostr("ISO 4217 currency, 3 letters (default 'USD').")
|
|
1885
|
+
}),
|
|
1886
|
+
(i) => client.airbnb.listing(i)
|
|
1887
|
+
),
|
|
1888
|
+
tool(
|
|
1889
|
+
"AIRBNB_REVIEWS",
|
|
1890
|
+
"Scavio Airbnb Reviews",
|
|
1891
|
+
"Airbnb review BODIES with per-review rating, date and reviewer name/photo/location, limit/offset paged at up to 50 per call. `count` is the listing's TOTAL review count, `returned` is how many this page holds. The rating breakdown lives on listing(), not here. Costs 1 credit.",
|
|
1892
|
+
import_zod.z.object({
|
|
1893
|
+
listing_id: str("Airbnb listing id or a full /rooms/ URL (1-500 characters)."),
|
|
1894
|
+
currency: ostr("ISO 4217 currency, 3 letters (default 'USD')."),
|
|
1895
|
+
limit: onum("Reviews to return, 1-50 (default 30). Upstream returns a fixed 7 when no explicit limit is sent."),
|
|
1896
|
+
offset: onum("Reviews to skip before this page, >= 0 (default 0).")
|
|
1897
|
+
}),
|
|
1898
|
+
(i) => client.airbnb.reviews(i)
|
|
1899
|
+
)
|
|
1900
|
+
);
|
|
1901
|
+
}
|
|
1902
|
+
if (all || enableGlassdoor) {
|
|
1903
|
+
tools.push(
|
|
1904
|
+
tool(
|
|
1905
|
+
"GLASSDOOR_COMPANIES",
|
|
1906
|
+
"Scavio Glassdoor Companies",
|
|
1907
|
+
"START HERE. Resolve a company NAME to the employer_id every other Glassdoor method is keyed by, ranked by Glassdoor and de-duplicated. Costs 1 credit.",
|
|
1908
|
+
import_zod.z.object({
|
|
1909
|
+
query: str("Company name to resolve (1-120 characters).")
|
|
1910
|
+
}),
|
|
1911
|
+
(i) => client.glassdoor.companies(i)
|
|
1912
|
+
),
|
|
1913
|
+
tool(
|
|
1914
|
+
"GLASSDOOR_COMPANY",
|
|
1915
|
+
"Scavio Glassdoor Company",
|
|
1916
|
+
"Glassdoor employer profile: description, mission, industry, sector, HQ, size and revenue bands, stock symbol, year founded, overall and per-category ratings, star distribution, CEO approval, awards, FAQ and the five server-rendered reviews. Also returns reviews_url and salaries_url, which reviews() and salaries() accept as url to save a fetch. Provide employer_id or url. Costs 1 credit.",
|
|
1917
|
+
import_zod.z.object({
|
|
1918
|
+
employer_id: ostr("Glassdoor employer id (1-50 characters) in any form Glassdoor writes it: '1699', 'E1699' or 'IE1699'. Must be a STRING - a JSON number is rejected."),
|
|
1919
|
+
company: ostr("Employer name as it appears in a Glassdoor slug (1-200 characters). COSMETIC: the profile resolves on employer_id alone, it is ignored entirely when url is set, and it does not satisfy the employer_id-or-url requirement."),
|
|
1920
|
+
url: ostr("Any glassdoor.com employer URL (1-500 characters): /Overview/, /Reviews/ or /Salary/. A non-glassdoor.com host is rejected.")
|
|
1921
|
+
}),
|
|
1922
|
+
(i) => client.glassdoor.company(i)
|
|
1923
|
+
),
|
|
1924
|
+
tool(
|
|
1925
|
+
"GLASSDOOR_REVIEWS",
|
|
1926
|
+
"Scavio Glassdoor Reviews",
|
|
1927
|
+
"Up to THREE full Glassdoor reviews - the cap is Glassdoor's login wall - with per-axis scores, pros, cons, advice, job title, location, employment status and employer response, plus complete rating statistics, star distribution, aggregate pro/con highlight terms and per-job-title review counts. There is no page param: move the window with category and employment_status. Provide employer_id or url. Costs 1 credit.",
|
|
1928
|
+
import_zod.z.object({
|
|
1929
|
+
employer_id: ostr("Glassdoor employer id (1-50 characters): '1699', 'E1699' or 'IE1699'. Must be a STRING - a JSON number is rejected. Addressing by id costs two upstream fetches; the customer price is unchanged."),
|
|
1930
|
+
company: ostr("Employer name as it appears in a Glassdoor slug (1-200 characters). COSMETIC: ignored when url is set, and it does not satisfy the employer_id-or-url requirement."),
|
|
1931
|
+
url: ostr("Any glassdoor.com employer URL (1-500 characters). Pass back reviews_url from company() to skip the resolve fetch. A non-glassdoor.com host is rejected."),
|
|
1932
|
+
category: ostr("Restrict to reviews Glassdoor files under one topic. Closed enum: Glassdoor IGNORES an unknown value and serves the unfiltered set under a 200. Read filtered_review_count on the response to see how many match. Accepted values: 'career_development', 'compensation', 'culture', 'diversity_and_inclusion', 'management', 'work_life_balance'."),
|
|
1933
|
+
employment_status: ostr("Restrict to one kind of employment. Closed enum for the same reason as category; FREELANCE is deliberately absent because it was never confirmed to change the result set. Accepted values: 'full_time', 'part_time', 'contract', 'intern'.")
|
|
1934
|
+
}),
|
|
1935
|
+
(i) => client.glassdoor.reviews(i)
|
|
1936
|
+
),
|
|
1937
|
+
tool(
|
|
1938
|
+
"GLASSDOOR_SALARIES",
|
|
1939
|
+
"Scavio Glassdoor Salaries",
|
|
1940
|
+
"Glassdoor salaries by job title, 10 titles per page: base-pay and total-pay percentiles P10-P90 with medians called out, sample counts, currency, pay period and last-reported date. The figures are Glassdoor's ESTIMATES for the title, not individual reported salaries. Provide employer_id or url. Costs 1 credit.",
|
|
1941
|
+
import_zod.z.object({
|
|
1942
|
+
employer_id: ostr("Glassdoor employer id (1-50 characters): '1699', 'E1699' or 'IE1699'. Must be a STRING - a JSON number is rejected. Addressing by id costs two upstream fetches; the customer price is unchanged."),
|
|
1943
|
+
company: ostr("Employer name as it appears in a Glassdoor slug (1-200 characters). COSMETIC: ignored when url is set, and it does not satisfy the employer_id-or-url requirement."),
|
|
1944
|
+
url: ostr("Any glassdoor.com employer URL (1-500 characters). Pass back salaries_url from company() to skip the resolve fetch. A non-glassdoor.com host is rejected."),
|
|
1945
|
+
page: onum("Results page, 1-based. Ten job titles per page; page_count on the response is how many pages exist.")
|
|
1946
|
+
}),
|
|
1947
|
+
(i) => client.glassdoor.salaries(i)
|
|
1948
|
+
)
|
|
1949
|
+
);
|
|
1950
|
+
}
|
|
1951
|
+
if (all || enableYelp) {
|
|
1952
|
+
tools.push(
|
|
1953
|
+
tool(
|
|
1954
|
+
"YELP_SEARCH",
|
|
1955
|
+
"Scavio Yelp Search",
|
|
1956
|
+
"Businesses in Yelp's ranked order: rating, review count, price band, categories, address, contact rails, hours, photos and a review snippet; every row carries both business_id and alias. Yelp fixes the page size at 10. Provide term and location, or url. Costs 2 credits.",
|
|
1957
|
+
import_zod.z.object({
|
|
1958
|
+
term: ostr("What to look for (1-200 characters): a category ('plumbers'), a dish, or a business name. Required together with location unless url is given."),
|
|
1959
|
+
location: ostr("Where to look (1-200 characters): city and region, a full address, or a postcode. Effectively required - Yelp geolocates a location-less search off the proxy exit, so the same request answers about a different metro run to run."),
|
|
1960
|
+
page: onum("Results page, 1-based. Yelp fixes the page size at 10."),
|
|
1961
|
+
sort: ostr("Result ordering (upstream default 'recommended'). Closed enum: Yelp IGNORES an unrecognised sortby and serves default ranking under a 200, billing a premium scrape for a sort that never ran. Accepted values: 'recommended', 'rating', 'review_count'."),
|
|
1962
|
+
price: oarrnum("Price bands to include, 1 ($) to 4 ($$$$); 1-4 values, combined freely - [1, 2] means $ or $$. Accepted values: 1, 2, 3, 4."),
|
|
1963
|
+
open_now: obool("Only businesses open at the moment of the request."),
|
|
1964
|
+
attributes: oarrstr("Raw Yelp filter aliases, max 20, each 1-100 characters ('RestaurantsDelivery', 'GoodForKids', 'WheelchairAccessible'). A deliberate PASSTHROUGH, not an enum - Yelp's vocabulary runs to ~117 values per vertical and an alias it does not know is ignored upstream, returning unfiltered results."),
|
|
1965
|
+
url: ostr("A full yelp.com/search URL (1-1000 characters) as an alternative to term + location; the query, offset and sort are read out of it and the URL is rebuilt.")
|
|
1966
|
+
}),
|
|
1967
|
+
(i) => client.yelp.search(i)
|
|
1968
|
+
),
|
|
1969
|
+
tool(
|
|
1970
|
+
"YELP_BUSINESS",
|
|
1971
|
+
"Scavio Yelp Business",
|
|
1972
|
+
"One business in full: rating and per-star histogram, review count, price band, categories, address and coordinates, phone, website and menu links, hours and holidays, amenities, photos and videos, popular items, health inspections, Q&A, licences and claim status - plus the first page of reviews at no extra cost. Provide business_id or url. Costs 2 credits.",
|
|
1973
|
+
import_zod.z.object({
|
|
1974
|
+
business_id: ostr("A Yelp business alias ('desnudo-coffee-austin-2'), its opaque encid, or any yelp.com/biz URL carrying one (1-500 characters). Search rows return both id forms."),
|
|
1975
|
+
url: ostr("A full yelp.com/biz URL (1-1000 characters) as an alternative to business_id.")
|
|
1976
|
+
}),
|
|
1977
|
+
(i) => client.yelp.business(i)
|
|
1978
|
+
),
|
|
1979
|
+
tool(
|
|
1980
|
+
"YELP_REVIEWS",
|
|
1981
|
+
"Scavio Yelp Reviews",
|
|
1982
|
+
"A page of reviews: rating, full text, language, author profile and expertise counts, attached photos, reaction counts and owner response. 10 per page. PAGE 1 IS REDUNDANT - it re-fetches the document business() already returned - so start at page 2. Provide business_id or url. Costs 2 credits.",
|
|
1983
|
+
import_zod.z.object({
|
|
1984
|
+
business_id: ostr("A Yelp business alias ('desnudo-coffee-austin-2'), its opaque encid, or any yelp.com/biz URL carrying one (1-500 characters)."),
|
|
1985
|
+
url: ostr("A full yelp.com/biz URL (1-1000 characters) as an alternative to business_id."),
|
|
1986
|
+
page: onum("Reviews page, 1-based, 10 per page. Page 1 duplicates the reviews business() already returned and costs another 2 credits - start at 2. A page past the last review is a 404, not an empty result."),
|
|
1987
|
+
sort: ostr("Review ordering (upstream default 'relevance'). Closed enum: Yelp IGNORES an unrecognised value and serves default ranking under a billed 200. Accepted values: 'relevance', 'newest', 'oldest', 'rating_high', 'rating_low', 'elites'."),
|
|
1988
|
+
rating: onum("Only reviews at this star rating, 1-5. Changes filtered_review_count on the response, not review_count. Accepted values: 1, 2, 3, 4, 5.")
|
|
1989
|
+
}),
|
|
1990
|
+
(i) => client.yelp.reviews(i)
|
|
1991
|
+
)
|
|
1992
|
+
);
|
|
1993
|
+
}
|
|
1994
|
+
if (all || enableAppStore) {
|
|
1995
|
+
tools.push(
|
|
1996
|
+
tool(
|
|
1997
|
+
"APP_STORE_SEARCH",
|
|
1998
|
+
"Scavio App Store Search",
|
|
1999
|
+
"Search the App Store and get up to 200 fully-shaped app rows - the same 43-field row as app() - so a search doubles as a bulk metadata fetch and as a publisher lookup. NO PAGINATION: raise limit, there is no second page. Costs 1 credit.",
|
|
2000
|
+
import_zod.z.object({
|
|
2001
|
+
term: str("What to search for (1-500 characters). Apple matches an app name, a keyword OR a publisher name, so searching a developer returns their catalogue."),
|
|
2002
|
+
limit: onum("Apps to return, 1-200 (default 25). The ONLY lever on result volume: the search API has no pagination and every offset spelling is silently ignored."),
|
|
2003
|
+
country: ostr("Two-letter ISO storefront code (default 'us'); decides price, currency, localised title and whether the app is sold there at all. Anything that is not exactly two letters is rejected with a free 400."),
|
|
2004
|
+
entity: ostr("Which catalogue to search: iPhone/iPad apps ('software', the default), iPad apps, or Mac App Store apps. These are separate stores, not a filter - Mac rows carry no iPad/Apple TV screenshots, advisories, features, supported devices or Game Center flag, returning them empty rather than absent. Accepted values: 'software', 'ipad_software', 'mac_software'."),
|
|
2005
|
+
lang: ostr("Listing text language as a five-letter code ('en_us', 'ja_jp'); any other shape is rejected. Independent of country: the storefront sets the price, this sets the words.")
|
|
2006
|
+
}),
|
|
2007
|
+
(i) => client.appStore.search(i)
|
|
2008
|
+
),
|
|
2009
|
+
tool(
|
|
2010
|
+
"APP_STORE_APP",
|
|
2011
|
+
"Scavio App Store App",
|
|
2012
|
+
"Full App Store listing: title, description, developer and seller identity, price and currency, all-time and current-version ratings, version and release notes, genres, content rating and advisories, icons at three sizes, screenshots, download size, minimum OS, languages, supported devices and the Game Center and VPP flags. Costs 1 credit.",
|
|
2013
|
+
import_zod.z.object({
|
|
2014
|
+
app_id: str("App Store id - the digits after 'id' in an apps.apple.com URL - or the app's bundle id ('notion.id', 'com.burbn.instagram'); both resolve to the identical payload. 1-255 characters matching ^[A-Za-z0-9][A-Za-z0-9._-]*$, so a pasted apps.apple.com URL is rejected with a free 400. An id Apple cannot resolve is a billed 404."),
|
|
2015
|
+
country: ostr("Two-letter ISO storefront code (default 'us'); decides price, currency, localised title and whether the app is sold there at all. Anything that is not exactly two letters is rejected with a free 400.")
|
|
2016
|
+
}),
|
|
2017
|
+
(i) => client.appStore.app(i)
|
|
2018
|
+
),
|
|
2019
|
+
tool(
|
|
2020
|
+
"APP_STORE_REVIEWS",
|
|
2021
|
+
"Scavio App Store Reviews",
|
|
2022
|
+
"A page of App Store reviews: star rating, title, full text, author and the APP VERSION the review was written against. 50 per page, hard-stopped at page 10 - 500 reviews per storefront is Apple's anonymous ceiling. This endpoint cannot 404: an unknown id and a real app with no reviews return the same empty feed. Costs 1 credit.",
|
|
2023
|
+
import_zod.z.object({
|
|
2024
|
+
app_id: str("App Store id, NUMERIC ONLY - unlike app(), the reviews feed has no bundle-id form."),
|
|
2025
|
+
country: ostr("Two-letter ISO storefront code (default 'us'). Anything that is not exactly two letters is rejected with a free 400. Ask a different country to reach past the 500-review ceiling."),
|
|
2026
|
+
page: onum("Reviews page, 1-10, 50 reviews each (default 1). Apple hard-stops at page 10."),
|
|
2027
|
+
sort: ostr("Review ordering (default 'most_recent'). The choice decides whether the vote fields mean anything: under most_recent almost every review is too new to have been voted on and returns zeroes, while most_helpful returns them densely populated.")
|
|
2028
|
+
}),
|
|
2029
|
+
(i) => client.appStore.reviews(i)
|
|
2030
|
+
)
|
|
2031
|
+
);
|
|
2032
|
+
}
|
|
2033
|
+
if (all || enableGooglePlay) {
|
|
2034
|
+
tools.push(
|
|
2035
|
+
tool(
|
|
2036
|
+
"GOOGLE_PLAY_SEARCH",
|
|
2037
|
+
"Scavio Google Play Search",
|
|
2038
|
+
"Ranked Google Play apps: package name, title, developer, rating, install count, price and IAP range, content rating, icon and screenshots. A branded query returns the hero card as result 1 in the same row shape, plus Play's related-query rail. NO PAGINATION - one shelf of about 30 apps. Costs 2 credits.",
|
|
2039
|
+
import_zod.z.object({
|
|
2040
|
+
query: str("What to search the store for (1-200 characters): an app name, a publisher, or a category phrase. Apps only - games are folded into the apps vertical, but books and films use a different card shape and are not covered."),
|
|
2041
|
+
hl: ostr("UI language, 2-20 characters (default 'en'). Changes the STOREFRONT, not only the strings: at hl=pt-BR the title, description, install formatting and content rating all move with it. Play silently falls back to English on a value it does not serve."),
|
|
2042
|
+
gl: ostr("Country code, 2-10 characters (default 'us'), deciding which storefront's price and availability are returned. Play silently falls back to the US storefront on a country it does not serve.")
|
|
2043
|
+
}),
|
|
2044
|
+
(i) => client.googlePlay.search(i)
|
|
2045
|
+
),
|
|
2046
|
+
tool(
|
|
2047
|
+
"GOOGLE_PLAY_APP",
|
|
2048
|
+
"Scavio Google Play App",
|
|
2049
|
+
"Full Google Play store listing: installs including the REAL count Play publishes but never renders, rating and star histogram, description, developer identity and legal contact, price and IAPs, categories and gameplay tags, screenshots and trailer, version and Android requirement, release and update dates, changelog, the full permission tree, the Data safety table, the 20 server-rendered reviews and the similar-apps and more-by-developer rails. Costs 2 credits.",
|
|
2050
|
+
import_zod.z.object({
|
|
2051
|
+
app_id: str("Android package name ('com.spotify.music') or any play.google.com URL carrying one in its id param (1-500 characters)."),
|
|
2052
|
+
hl: ostr("UI language, 2-20 characters (default 'en'). Changes the STOREFRONT, not only the strings: title, description, install formatting and content rating all move with it. Play silently falls back to English on a value it does not serve."),
|
|
2053
|
+
gl: ostr("Country code, 2-10 characters (default 'us'), deciding which storefront's price and availability are returned. Play silently falls back to the US storefront on a country it does not serve.")
|
|
2054
|
+
}),
|
|
2055
|
+
(i) => client.googlePlay.app(i)
|
|
2056
|
+
),
|
|
2057
|
+
tool(
|
|
2058
|
+
"GOOGLE_PLAY_REVIEWS",
|
|
2059
|
+
"Scavio Google Play Reviews",
|
|
2060
|
+
"A page of Google Play reviews: star score, full text, author, thumbs-up count, developer reply and the APP VERSION the reviewer was running. Paged by cursor, up to 200 per call. app() already returns the 20 reviews Play server-renders; use this to page past them or sort differently. Costs 2 credits.",
|
|
2061
|
+
import_zod.z.object({
|
|
2062
|
+
app_id: str("Android package name ('com.spotify.music') or any play.google.com URL carrying one in its id param (1-500 characters)."),
|
|
2063
|
+
sort: ostr("Review ordering (default 'newest'). Closed enum. The cursor encodes the sort, so keep this identical when paging. Accepted values: 'relevance', 'newest', 'rating'."),
|
|
2064
|
+
count: onum("Reviews to return, 1-200 (default 50); 200 is our cap, not Play's. Play honours more, but a single page that large is megabytes for one credit - page with cursor instead."),
|
|
2065
|
+
cursor: ostr("Continuation token from a prior response's next_cursor (1-4000 characters). Opaque and SINGLE-USE, and it encodes the sort as well as the position - send it back with the SAME sort it came from. A cursor past the last review is a 404, not an empty page."),
|
|
2066
|
+
hl: ostr("UI language, 2-20 characters (default 'en'). Changes the STOREFRONT, not only the strings. Play silently falls back to English on a value it does not serve."),
|
|
2067
|
+
gl: ostr("Country code, 2-10 characters (default 'us'), deciding which storefront's price and availability are returned. Play silently falls back to the US storefront on a country it does not serve.")
|
|
2068
|
+
}),
|
|
2069
|
+
(i) => client.googlePlay.reviews(i)
|
|
2070
|
+
)
|
|
2071
|
+
);
|
|
2072
|
+
}
|
|
2073
|
+
if (all || enableSec) {
|
|
2074
|
+
tools.push(
|
|
2075
|
+
tool(
|
|
2076
|
+
"SEC_LOOKUP",
|
|
2077
|
+
"Scavio SEC Lookup",
|
|
2078
|
+
"START HERE. Resolve a company name or ticker (AAPL) to the CIK (0000320193) every other SEC EDGAR endpoint is keyed by. Up to 100 rows, tiered by match quality. Costs 1 credit.",
|
|
2079
|
+
import_zod.z.object({
|
|
2080
|
+
query: str("Ticker ('AAPL', 'BRK.B'), company name, or a fragment of one (1-200 characters); each row carries its match tier as 'match'."),
|
|
2081
|
+
limit: onum("Rows to return, 1-100. Defaults to 10. Sizes the response; it is not a page param."),
|
|
2082
|
+
exchange: ostr("Restrict to one listing venue; matched case-insensitively, so 'Nasdaq' also works. Filers the SEC lists with no exchange at all are excluded by any value. Accepted values: 'NASDAQ', 'NYSE', 'OTC', 'CBOE'.")
|
|
2083
|
+
}),
|
|
2084
|
+
(i) => client.sec.lookup(i)
|
|
2085
|
+
),
|
|
2086
|
+
tool(
|
|
2087
|
+
"SEC_COMPANY",
|
|
2088
|
+
"Scavio SEC Company",
|
|
2089
|
+
"SEC filer profile: legal and former names, SIC industry, filer category, EIN, LEI, state of incorporation, fiscal year end, addresses, every ticker with its exchange, and a preview of its 10 most recent filings. Provide cik or ticker. Costs 1 credit.",
|
|
2090
|
+
import_zod.z.object({
|
|
2091
|
+
cik: ostr("Filer CIK in any spelling (1-20 characters): 320193, 0000320193 or CIK0000320193. A ticker is accepted here too."),
|
|
2092
|
+
ticker: ostr("Ticker symbol (1-20 characters), dotted or dashed (BRK.B / BRK-B). Wins over cik when both are given.")
|
|
2093
|
+
}),
|
|
2094
|
+
(i) => client.sec.company(i)
|
|
2095
|
+
),
|
|
2096
|
+
tool(
|
|
2097
|
+
"SEC_FILINGS",
|
|
2098
|
+
"Scavio SEC Filings",
|
|
2099
|
+
"A page of one filer's filings: accession number, form and root form, filing and period dates, 8-K item codes, direct links to the primary document, filing index and attachment directory. Up to 500 per page. Provide cik or ticker. Costs 1 credit.",
|
|
2100
|
+
import_zod.z.object({
|
|
2101
|
+
cik: ostr("Filer CIK, zero-padded or bare (1-20 characters). A ticker is accepted here too."),
|
|
2102
|
+
ticker: ostr("Ticker symbol (1-20 characters), as an alternative to cik."),
|
|
2103
|
+
form: ostrarr("Form types to keep: '10-K', ['10-K', '10-Q'] or the comma-joined '10-K,8-K'; each value 1-50 characters, at most 25 values. Matched against the form AND its root form, so 10-K also returns 10-K/A amendments; ask for '10-K/A' to get only amendments."),
|
|
2104
|
+
date_from: ostr("Earliest filing date, inclusive (YYYY-MM-DD)."),
|
|
2105
|
+
date_to: ostr("Latest filing date, inclusive (YYYY-MM-DD)."),
|
|
2106
|
+
page: onum("Results page, 1-based; page size is whatever limit is set to. No upper bound."),
|
|
2107
|
+
limit: onum("Filings per page, 1-500. Defaults to 50."),
|
|
2108
|
+
include_history: obool("Also fetch the archived filing history beyond EDGAR's 'recent' block, which is not a fixed window (a decade for a quiet filer, about a year for a prolific one). Off by default; at most 10 archived shards are fetched, history_truncated says when a filer had more, and it is still 1 credit.")
|
|
2109
|
+
}),
|
|
2110
|
+
(i) => client.sec.filings(i)
|
|
2111
|
+
),
|
|
2112
|
+
tool(
|
|
2113
|
+
"SEC_CONCEPT",
|
|
2114
|
+
"Scavio SEC Concept",
|
|
2115
|
+
"Every value a filer reported for one XBRL concept, newest period first, with the form and filing each number came from. Restatements are kept, not collapsed. Up to 2000 rows. Provide cik or ticker. Costs 1 credit.",
|
|
2116
|
+
import_zod.z.object({
|
|
2117
|
+
concept: str("XBRL concept tag, CASE-SENSITIVE (1-120 characters, ^[A-Za-z][A-Za-z0-9]*$): 'NetIncomeLoss' matches, 'netincomeloss' is a 404 upstream. Use facts() to list what a filer actually reports."),
|
|
2118
|
+
cik: ostr("Filer CIK, zero-padded or bare (1-20 characters). A ticker is accepted here too."),
|
|
2119
|
+
ticker: ostr("Ticker symbol (1-20 characters), as an alternative to cik."),
|
|
2120
|
+
taxonomy: ostr("Reporting taxonomy (1-40 characters, ^[A-Za-z][A-Za-z0-9-]*$): us-gaap, dei, ifrs-full or srt. Defaults to 'us-gaap'."),
|
|
2121
|
+
unit: ostr("Unit of measure to keep (1-40 characters), e.g. 'USD' vs 'USD/shares'."),
|
|
2122
|
+
form: ostr("Form to keep (1-50 characters). EXACT match here, unlike filings(), so '10-K' excludes 10-K/A."),
|
|
2123
|
+
limit: onum("Rows to return, 1-2000. Defaults to 250. Sizes the response; it is not a page param.")
|
|
2124
|
+
}),
|
|
2125
|
+
(i) => client.sec.concept(i)
|
|
2126
|
+
),
|
|
2127
|
+
tool(
|
|
2128
|
+
"SEC_FACTS",
|
|
2129
|
+
"Scavio SEC Facts",
|
|
2130
|
+
"The index of every XBRL concept a filer reports - tag, label, description, units and most recent value - across us-gaap, dei and any other taxonomy it uses. This is how you find what to ask concept() for. Up to 2000 rows. Provide cik or ticker. Costs 1 credit.",
|
|
2131
|
+
import_zod.z.object({
|
|
2132
|
+
cik: ostr("Filer CIK, zero-padded or bare (1-20 characters). A ticker is accepted here too."),
|
|
2133
|
+
ticker: ostr("Ticker symbol (1-20 characters), as an alternative to cik."),
|
|
2134
|
+
taxonomy: ostr("Restrict to one taxonomy (1-40 characters), e.g. 'us-gaap' or 'dei'."),
|
|
2135
|
+
query: ostr("Case-insensitive substring matched against the tag name and label (1-200 characters)."),
|
|
2136
|
+
limit: onum("Rows to return, 1-2000. Defaults to 250. Sizes the response; it is not a page param.")
|
|
2137
|
+
}),
|
|
2138
|
+
(i) => client.sec.facts(i)
|
|
2139
|
+
),
|
|
2140
|
+
tool(
|
|
2141
|
+
"SEC_SEARCH",
|
|
2142
|
+
"Scavio SEC Search",
|
|
2143
|
+
"EDGAR full-text search, coverage starting 2001: each hit is the matching DOCUMENT with its URL, form, filing date and filer identity, plus facets by company, form, industry and state. 100 documents per page, last page is 100. Costs 1 credit.",
|
|
2144
|
+
import_zod.z.object({
|
|
2145
|
+
query: ostr("Full-text query over filing documents (1-500 characters); a quoted phrase is matched exactly, bare words as a bag of terms. Optional - a cik, ticker, form or date filter on its own is a valid search."),
|
|
2146
|
+
cik: ostrarr("Restrict to one or more filers by CIK: a single value, a list, or a comma-joined string; each 1-20 characters, at most 25 values. Tickers are accepted here too."),
|
|
2147
|
+
ticker: ostrarr("Restrict to one or more filers by ticker symbol: a single value, a list, or a comma-joined string; each 1-20 characters, at most 25 values."),
|
|
2148
|
+
form: ostrarr("Form types to keep: '8-K', ['10-K', '10-Q'] or the comma-joined '10-K,10-Q'; each 1-50 characters, at most 25 values."),
|
|
2149
|
+
date_from: ostr("Earliest filing date, inclusive (YYYY-MM-DD). Full-text coverage starts in 2001."),
|
|
2150
|
+
date_to: ostr("Latest filing date, inclusive (YYYY-MM-DD)."),
|
|
2151
|
+
location: ostrarr("Filer business-address locations as EDGAR's own 2-character codes (CA, NY, and its alphanumeric codes for foreign jurisdictions): a single value, a list, or a comma-joined string; at most 25 values."),
|
|
2152
|
+
sort: ostr("Result ordering. Defaults to the index's own relevance ranking. Accepted values: 'relevance', 'newest', 'oldest'."),
|
|
2153
|
+
page: onum("Results page, 1-based, 1-100, 100 documents per page. The SEC's index refuses a result window past 10,000, so 100 is the last page for any query.")
|
|
2154
|
+
}),
|
|
2155
|
+
(i) => client.sec.search(i)
|
|
2156
|
+
)
|
|
2157
|
+
);
|
|
2158
|
+
}
|
|
2159
|
+
if (all || enableRedfin) {
|
|
2160
|
+
tools.push(
|
|
2161
|
+
tool(
|
|
2162
|
+
"REDFIN_SEARCH",
|
|
2163
|
+
"Scavio Redfin Search",
|
|
2164
|
+
"Redfin listings: price, price per sqft, beds, baths, living area, lot size, year built, coordinates, listing remarks and full photo galleries, for sale, sold or for rent. Up to 350 per page. Provide location, or region_id together with region_type. Costs 1 credit.",
|
|
2165
|
+
import_zod.z.object({
|
|
2166
|
+
location: ostr("A redfin.com region URL (/city/, /neighborhood/, /county/, /zipcode/) or a bare 5-digit ZIP (1-500 characters). CITY NAMES ARE NOT ACCEPTED - Redfin's own name lookup is blocked to us; use region_id + region_type instead."),
|
|
2167
|
+
region_id: onum("Redfin internal region id (>= 1), used together with region_type. NOT a ZIP code - the two are different number spaces and a ZIP here resolves to another city rather than failing."),
|
|
2168
|
+
region_type: onum("Region kind that region_id belongs to: 1 neighborhood, 2 ZIP, 5 county, 6 city. Must be sent together with region_id or both are ignored in favour of location."),
|
|
2169
|
+
listing_status: ostr("Market to search. Defaults to 'for_sale'. Accepted values: 'for_sale', 'sold', 'for_rent'."),
|
|
2170
|
+
sold_within_days: onum("Sold within the last N days (>= 1). REJECTED unless listing_status='sold', where it defaults to 90."),
|
|
2171
|
+
page: onum("Results page, 1-based; page size is whatever limit is set to. No upper bound."),
|
|
2172
|
+
limit: onum("Listings per page, 1-350. Defaults to 100."),
|
|
2173
|
+
sort: ostr("Result sort order. Defaults to 'recommended', Redfin's own ranking. Accepted values: 'recommended', 'price_low', 'price_high', 'newest', 'oldest', 'sqft_low', 'sqft_high', 'price_per_sqft_low', 'price_per_sqft_high'."),
|
|
2174
|
+
min_price: onum("Minimum price, inclusive (>= 0). Monthly rent when listing_status='for_rent'."),
|
|
2175
|
+
max_price: onum("Maximum price, inclusive (>= 0). Monthly rent when listing_status='for_rent'."),
|
|
2176
|
+
beds_min: onum("Minimum bedrooms (whole number >= 0); fractional values are rejected."),
|
|
2177
|
+
beds_max: onum("Maximum bedrooms (whole number >= 0); fractional values are rejected."),
|
|
2178
|
+
baths_min: onum("Minimum bathrooms (whole number >= 0). WHOLE BATHS ONLY - 1.5 is rejected rather than silently truncated to 1. There is no baths_max."),
|
|
2179
|
+
sqft_min: onum("Minimum living area in square feet (whole number >= 0)."),
|
|
2180
|
+
sqft_max: onum("Maximum living area in square feet (whole number >= 0)."),
|
|
2181
|
+
lot_size_min: onum("Minimum lot size in square feet (whole number >= 0). There is no lot_size_max."),
|
|
2182
|
+
year_built_min: onum("Earliest year built (whole number >= 0)."),
|
|
2183
|
+
year_built_max: onum("Latest year built (whole number >= 0)."),
|
|
2184
|
+
max_hoa: onum("Maximum monthly HOA fee in dollars (>= 0)."),
|
|
2185
|
+
property_type: ostr("Restrict to one property type. Accepted values: 'house', 'condo', 'townhouse', 'multi_family', 'land', 'other', 'co_op'."),
|
|
2186
|
+
has_pool: obool("Only listings with a pool."),
|
|
2187
|
+
max_days_on_market: onum("Listed at most N days ago (whole number >= 0). Cannot be combined with min_days_on_market - Redfin expresses both bounds through one param."),
|
|
2188
|
+
min_days_on_market: onum("Listed at least N days ago (whole number >= 0). Cannot be combined with max_days_on_market.")
|
|
2189
|
+
}),
|
|
2190
|
+
(i) => client.redfin.search(i)
|
|
2191
|
+
),
|
|
2192
|
+
tool(
|
|
2193
|
+
"REDFIN_PROPERTY",
|
|
2194
|
+
"Scavio Redfin Property",
|
|
2195
|
+
"One Redfin listing in full: price, Redfin Estimate and rental estimate, complete MLS fact sheet, price and tax history, listing agents, open houses, schools, climate risk, walkability, sun exposure, monthly weather, permits, zoning, comparable sales and photos. Costs 1 credit.",
|
|
2196
|
+
import_zod.z.object({
|
|
2197
|
+
property_id: str("Redfin property id, or any redfin.com listing URL carrying one (1-500 characters).")
|
|
2198
|
+
}),
|
|
2199
|
+
(i) => client.redfin.property(i)
|
|
2200
|
+
),
|
|
2201
|
+
tool(
|
|
2202
|
+
"REDFIN_MARKET",
|
|
2203
|
+
"Scavio Redfin Market",
|
|
2204
|
+
"Redfin housing-market stats for a region: median list and sale price, price per sqft, sale-to-list ratio, average offers and days on market, YoY movement, 0-100 compete score, live inventory by property type and by bedroom count, and Redfin agent presence. Provide location, or region_id together with region_type. Costs 1 credit.",
|
|
2205
|
+
import_zod.z.object({
|
|
2206
|
+
location: ostr("A redfin.com region URL (/city/, /neighborhood/, /county/, /zipcode/) or a bare 5-digit ZIP (1-500 characters). City names are not accepted."),
|
|
2207
|
+
region_id: onum("Redfin internal region id (>= 1), used together with region_type. Not a ZIP code."),
|
|
2208
|
+
region_type: onum("Region kind that region_id belongs to: 1 neighborhood, 2 ZIP, 5 county, 6 city. Must be sent together with region_id or both are ignored in favour of location.")
|
|
2209
|
+
}),
|
|
2210
|
+
(i) => client.redfin.market(i)
|
|
2211
|
+
)
|
|
2212
|
+
);
|
|
2213
|
+
}
|
|
2214
|
+
if (all || enableCompaniesHouse) {
|
|
2215
|
+
tools.push(
|
|
2216
|
+
tool(
|
|
2217
|
+
"COMPANIES_HOUSE_SEARCH",
|
|
2218
|
+
"Scavio Companies House Search",
|
|
2219
|
+
"START HERE. Search the UK register by name and get the company_number every other Companies House endpoint is keyed by, plus status, incorporation or dissolution date, registered office and matched former names. 20 per page, last page is 50. Costs 1 credit.",
|
|
2220
|
+
import_zod.z.object({
|
|
2221
|
+
query: str("Company name or fragment (1-200 characters, non-blank). Matches CURRENT AND FORMER names."),
|
|
2222
|
+
page: onum("Results page, 1-based, 1-50, 20 results per page. Defaults to 1. The register serves only a 1000-result window per term whatever hit count it prints, and answers page 51 with HTTP 416.")
|
|
2223
|
+
}),
|
|
2224
|
+
(i) => client.companiesHouse.search(i)
|
|
2225
|
+
),
|
|
2226
|
+
tool(
|
|
2227
|
+
"COMPANIES_HOUSE_COMPANY",
|
|
2228
|
+
"Scavio Companies House Company",
|
|
2229
|
+
"Full UK register entry: status, type, incorporation and dissolution dates, registered office, SIC codes, previous names, accounts and confirmation-statement due dates with overdue flags, and whether it has charges, insolvency history, officers or UK establishments. Costs 1 credit.",
|
|
2230
|
+
import_zod.z.object({
|
|
2231
|
+
company_number: str("UK company number (1-20 characters), zero-padded and upper-cased for you, so '445790' and 'sc090312' both work. Registry prefixes supported: SC, NI, OC, SO, NC, FC, BR, CE.")
|
|
2232
|
+
}),
|
|
2233
|
+
(i) => client.companiesHouse.company(i)
|
|
2234
|
+
),
|
|
2235
|
+
tool(
|
|
2236
|
+
"COMPANIES_HOUSE_OFFICERS",
|
|
2237
|
+
"Scavio Companies House Officers",
|
|
2238
|
+
"UK company officers, current and resigned, 35 per page: name, role, appointment and resignation dates, correspondence address, nationality, country of residence, month-and-year date of birth and identity-verification status. Costs 1 credit.",
|
|
2239
|
+
import_zod.z.object({
|
|
2240
|
+
company_number: str("UK company number (1-20 characters), zero-padded and upper-cased for you."),
|
|
2241
|
+
page: onum("Results page, 1-based, 35 per page. Defaults to 1. No upper bound: past the last page the register answers an ordinary 200 with an empty list, identical to a company with no officers.")
|
|
2242
|
+
}),
|
|
2243
|
+
(i) => client.companiesHouse.officers(i)
|
|
2244
|
+
),
|
|
2245
|
+
tool(
|
|
2246
|
+
"COMPANIES_HOUSE_FILING_HISTORY",
|
|
2247
|
+
"Scavio Companies House Filing History",
|
|
2248
|
+
"UK filings, most recent first: date, filing type code (AA, CS01, SH03), description, register annotations and child documents, and a link to the filed PDF with its page count. A filing the register has not finished processing carries a processing_note instead of a document. Costs 1 credit.",
|
|
2249
|
+
import_zod.z.object({
|
|
2250
|
+
company_number: str("UK company number (1-20 characters), zero-padded and upper-cased for you."),
|
|
2251
|
+
page: onum("Results page, 1-based. Defaults to 1. No upper bound: past the last page the register answers an ordinary 200 with an empty list.")
|
|
2252
|
+
}),
|
|
2253
|
+
(i) => client.companiesHouse.filingHistory(i)
|
|
2254
|
+
)
|
|
2255
|
+
);
|
|
2256
|
+
}
|
|
2257
|
+
if (all || enableG2) {
|
|
2258
|
+
tools.push(
|
|
2259
|
+
tool(
|
|
2260
|
+
"G2_SEARCH",
|
|
2261
|
+
"Scavio G2 Search",
|
|
2262
|
+
"Search G2, the B2B software review site, for products: star rating, review count, vendor, categories, seller description and logo, with product_id and slug on every row. Up to 100 results per page (server default 20) and page-paginated; total_results is G2's Products-tab headline and caps at 10000, while total_by_type splits the query across products, sellers, categories and discussions. Provide query or url. Costs 5 credits.",
|
|
2263
|
+
import_zod.z.object({
|
|
2264
|
+
query: ostr("Search term (1-200 characters). Provide this or url."),
|
|
2265
|
+
page: onum("1-based page number; page size follows limit (server default 20). G2 keeps paginating well past its own widget's page links."),
|
|
2266
|
+
limit: onum("Results per page (1-100; server default 20). The 100 ceiling is ours, to keep a single request inside the 60s deadline; G2 itself paginates at any size."),
|
|
2267
|
+
sort: ostr("Result sort order (server default 'relevance'). Closed enum: G2 silently accepts an unknown sort and answers 200 with an unstated ordering. Accepted values: 'relevance', 'popular', 'alphabetical', 'rating'."),
|
|
2268
|
+
rating: onum("Only products at or above this star rating (1-5, sent as an integer). Omit for no rating floor. Accepted values: 1, 2, 3, 4, 5."),
|
|
2269
|
+
url: ostr("Full g2.com/search URL, as an alternative to query (1-1000 characters; the host is checked by the transport).")
|
|
2270
|
+
}),
|
|
2271
|
+
(i) => client.g2.search(i)
|
|
2272
|
+
),
|
|
2273
|
+
tool(
|
|
2274
|
+
"G2_PRODUCT",
|
|
2275
|
+
"Scavio G2 Product",
|
|
2276
|
+
"Full G2 product profile: rating with per-star histogram, review count, vendor, description and seller website, pricing editions with parsed amounts, feature groups, categories and breadcrumbs, supported languages, integrations, alternatives, head-to-head comparisons, media, community discussions and G2's AI-derived pros and cons. Carries NO review text at all -- G2 loads review bodies in a separate frame, so call reviews() for those. Provide product_id or url. Costs 5 credits.",
|
|
2277
|
+
import_zod.z.object({
|
|
2278
|
+
product_id: ostr("G2 product slug ('notion') or the numeric G2 id ('82623') as a string (1-200 characters); both resolve on the same upstream path."),
|
|
2279
|
+
url: ostr("Full g2.com product URL, as an alternative to product_id (1-1000 characters).")
|
|
2280
|
+
}),
|
|
2281
|
+
(i) => client.g2.product(i)
|
|
2282
|
+
),
|
|
2283
|
+
tool(
|
|
2284
|
+
"G2_REVIEWS",
|
|
2285
|
+
"Scavio G2 Reviews",
|
|
2286
|
+
"A page of G2 reviews: rating, title, likes and dislikes, problems solved, reviewer job title, industry and company size, validated and incentivized flags -- plus what the profile page has no form of: exact per-star counts, pros and cons with per-theme counts, and company-size, role, industry, region and category facets with counts. Fixed at 10 reviews per page and paginates well past the 10 pages G2's own widget links to. Provide product_id or url. Costs 5 credits.",
|
|
2287
|
+
import_zod.z.object({
|
|
2288
|
+
product_id: ostr("G2 product slug or numeric G2 id as a string (1-200 characters)."),
|
|
2289
|
+
url: ostr("Full g2.com reviews URL, as an alternative to product_id (1-1000 characters)."),
|
|
2290
|
+
page: onum("1-based page number; fixed at 10 reviews per page."),
|
|
2291
|
+
sort: ostr("Review sort order (server default 'relevance'). Closed enum: an unknown sort is silently accepted upstream and never runs. Accepted values: 'relevance', 'newest', 'most_helpful', 'rating_high', 'rating_low'."),
|
|
2292
|
+
rating: onum("Only reviews in this star bucket (1-5, sent as an integer). Buckets are half- star-inclusive: 1 returns 0, 0.5 and 1-star reviews. Accepted values: 1, 2, 3, 4, 5."),
|
|
2293
|
+
company_size: ostr("Reviewer company size: small_business is 50 employees or fewer, mid_market 51-1000, enterprise over 1000. Closed enum -- an unknown value matches nothing and returns a billed 'Reviews (0)'."),
|
|
2294
|
+
role: ostr("Reviewer role. Closed enum -- an unknown value matches nothing rather than erroring. Accepted values: 'user', 'administrator', 'executive_sponsor', 'internal_consultant', 'consultant', 'agency', 'industry_analyst'."),
|
|
2295
|
+
region: ostr("Reviewer region. Closed enum -- an unknown value matches nothing rather than erroring. Accepted values: 'north_america', 'europe', 'asia', 'latin_america', 'anz', 'middle_east', 'africa'."),
|
|
2296
|
+
query: ostr("Full-text search within this product's reviews (1-200 characters); narrows the review list AND every facet count.")
|
|
2297
|
+
}),
|
|
2298
|
+
(i) => client.g2.reviews(i)
|
|
2299
|
+
)
|
|
2300
|
+
);
|
|
2301
|
+
}
|
|
2302
|
+
if (all || enableCapterra) {
|
|
2303
|
+
tools.push(
|
|
2304
|
+
tool(
|
|
2305
|
+
"CAPTERRA_SEARCH",
|
|
2306
|
+
"Scavio Capterra Search",
|
|
2307
|
+
"Search Capterra, the B2B software review site: 20 ranked products with name, vendor description, rating, review count, logo and paid-placement flag, each row carrying product_id and slug. The result set is fixed at 20 and does NOT paginate -- Capterra serves identical rows for page 2, so there is deliberately no page parameter. Provide query or url. Costs 2 credits.",
|
|
2308
|
+
import_zod.z.object({
|
|
2309
|
+
query: ostr("Search term (1-200 characters). Required in practice: a term-less Capterra search serves a fixed popular-products list unrelated to the caller."),
|
|
2310
|
+
url: ostr("Full capterra.com search URL, as an alternative to query (1-1000 characters; the transport also accepts capterra.co.uk and capterra.com.br hosts).")
|
|
2311
|
+
}),
|
|
2312
|
+
(i) => client.capterra.search(i)
|
|
2313
|
+
),
|
|
2314
|
+
tool(
|
|
2315
|
+
"CAPTERRA_PRODUCT",
|
|
2316
|
+
"Scavio Capterra Product",
|
|
2317
|
+
"Full Capterra profile: rating with per-star histogram and the four scored criteria, likelihood to recommend, review sentiment and topics, the complete pricing table with every plan and its features, every rated feature and integration, AI-derived pros and cons with the quoted review, FAQs, screenshots, badges and awards, competitor comparisons and alternatives, and the buyer profile by company size, industry and job function -- PLUS the 25 most recent reviews at no extra cost. vendor is always null here: Capterra does not publish it as structured data on the product page. Provide product_id or url. Costs 2 credits.",
|
|
2318
|
+
import_zod.z.object({
|
|
2319
|
+
product_id: ostr("The number in a Capterra product path such as /p/186596/Notion/ (1-50 characters). Must be a STRING -- a JSON number is rejected."),
|
|
2320
|
+
slug: ostr("Product slug (1-200 characters). Cosmetic on this endpoint -- a wrong slug still returns the right profile -- but load-bearing on reviews()."),
|
|
2321
|
+
url: ostr("Full Capterra product URL, as an alternative to product_id (1-1000 characters).")
|
|
2322
|
+
}),
|
|
2323
|
+
(i) => client.capterra.product(i)
|
|
2324
|
+
),
|
|
2325
|
+
tool(
|
|
2326
|
+
"CAPTERRA_REVIEWS",
|
|
2327
|
+
"Scavio Capterra Reviews",
|
|
2328
|
+
"A page of Capterra reviews: overall score plus five per-criterion scores, title, pros, cons, advice, usage duration, incentivized flag, alternatives considered and what they switched from, reviewer job title, industry and company size, and the vendor response -- plus a competitor list richer than the profile's, each alternative with its own rating histogram and starting price. 25 reviews per page, capped at page 100. Page 1 already rides along inside product(), so use this to page past it. Provide product_id or url. Costs 2 credits.",
|
|
2329
|
+
import_zod.z.object({
|
|
2330
|
+
product_id: ostr("Capterra product id as a string (1-50 characters)."),
|
|
2331
|
+
slug: ostr("Product slug (1-200 characters). LOAD-BEARING here: it is case-sensitive upstream and a wrong one silently serves page one under a billed 200. Pass back the slug from search() or product()."),
|
|
2332
|
+
url: ostr("Full Capterra reviews URL, as an alternative to product_id (1-1000 characters). Passing back reviews_url from product() is the reliable way to page."),
|
|
2333
|
+
page: onum("1-based page number (1-100); 25 reviews per page. 100 is a hard cap whatever the review count says -- past it Capterra answers 200 with page one.")
|
|
2334
|
+
}),
|
|
2335
|
+
(i) => client.capterra.reviews(i)
|
|
2336
|
+
)
|
|
2337
|
+
);
|
|
2338
|
+
}
|
|
2339
|
+
if (all || enableGoogleAds) {
|
|
2340
|
+
tools.push(
|
|
2341
|
+
tool(
|
|
2342
|
+
"GOOGLE_ADS_ADVERTISERS",
|
|
2343
|
+
"Scavio Google Ads Advertisers",
|
|
2344
|
+
"Resolve a brand name or domain to the advertiser_id that search() and creative() are keyed by. Returns two row kinds in one list: 'advertiser' rows carrying the id, verified name, verification country and total ad count as a range, and 'domain' rows carrying a website. A name query returns both kinds; a domain-shaped query returns domains only. Autocomplete-backed, roughly 20 rows per arm, and it does not paginate. Costs 1 credit.",
|
|
2345
|
+
import_zod.z.object({
|
|
2346
|
+
query: str("Brand name or domain to resolve (1-200 characters)."),
|
|
2347
|
+
region: ostr("ISO 3166-1 alpha-2 country ('US', 'GB', 'DE') or a Google geo criteria id as a string (2-12 characters). Default: no region filter."),
|
|
2348
|
+
limit: onum("Rows per arm (1-20; server default 10). Advertisers and domains are capped separately, so a name query can return up to twice this many rows.")
|
|
2349
|
+
}),
|
|
2350
|
+
(i) => client.googleAds.advertisers(i)
|
|
2351
|
+
),
|
|
2352
|
+
tool(
|
|
2353
|
+
"GOOGLE_ADS_SEARCH",
|
|
2354
|
+
"Scavio Google Ads Search",
|
|
2355
|
+
"Every ad Google Ads Transparency holds for one advertiser: the creative (archived image, rich-media bundle, Google's renderer link, dimensions), advertiser id and name, format, first and last seen dates and days actually run, plus total_ads_min and total_ads_max -- Google publishes the advertiser's ad total as a range, never an exact figure. Up to 100 ads per page (server default 40); paginate by sending next_cursor back as cursor alongside the SAME filters. Provide domain or advertiser_id. Costs 1 credit.",
|
|
2356
|
+
import_zod.z.object({
|
|
2357
|
+
domain: ostr("Advertiser website (1-253 characters): bare host, www host or full URL, reduced to the registrable host. The only way to get `domain` back on each row."),
|
|
2358
|
+
advertiser_id: ostr("Google advertiser id, e.g. 'AR16735076323512287233' (3-40 characters). The shape is checked before any request, so a typo costs no credits. Querying by id drops `domain` from every row."),
|
|
2359
|
+
region: ostr("ISO 3166-1 alpha-2 country ('US', 'GB', 'DE') or a Google geo criteria id as a string (2-12 characters). Scopes the deep links on every row, and the same advertiser can share zero creatives between two countries. Default: worldwide."),
|
|
2360
|
+
format: ostr("Creative format. The three sets are disjoint -- an advertiser's text, image and video ads share no creatives. Default: all formats."),
|
|
2361
|
+
platform: ostr("Google surface the ad ran on. Default: all surfaces. Accepted values: 'play', 'maps', 'search', 'shopping', 'youtube'."),
|
|
2362
|
+
topic: ostr("Ad topic (server default 'all'). Accepted values: 'all', 'political'."),
|
|
2363
|
+
limit: onum("Ads per page (1-100; server default 40). 100 is a hard upstream ceiling, not our policy: Google answers a larger request with zero rows rather than an error."),
|
|
2364
|
+
cursor: ostr("next_cursor from the previous response (1-4000 characters), 100 ads per page. Re-send the same filters alongside it; next_cursor is null once exhausted.")
|
|
2365
|
+
}),
|
|
2366
|
+
(i) => client.googleAds.search(i)
|
|
2367
|
+
),
|
|
2368
|
+
tool(
|
|
2369
|
+
"GOOGLE_ADS_CREATIVE",
|
|
2370
|
+
"Scavio Google Ads Creative",
|
|
2371
|
+
"One creative in full, and the only endpoint carrying its history: every size variation of the asset, the impression bucket, the per-region breakdown with first and last shown dates and a per-surface impression split inside each region, the format, Google's category label and the funder disclosure on political ads. Impressions and first_shown are EEA-only (DSA-compelled) and come back null for US creatives, and an impression bucket may carry only a lower or only an upper bound. Costs 1 credit.",
|
|
2372
|
+
import_zod.z.object({
|
|
2373
|
+
advertiser_id: str("Google advertiser id, e.g. 'AR16735076323512287233' (3-40 characters)."),
|
|
2374
|
+
creative_id: str("Creative id (3-40 characters). It must belong to the advertiser_id sent with it -- the lookup is keyed by the pair and a mismatched pair is a 404.")
|
|
2375
|
+
}),
|
|
2376
|
+
(i) => client.googleAds.creative(i)
|
|
2377
|
+
)
|
|
2378
|
+
);
|
|
2379
|
+
}
|
|
2380
|
+
if (all || enableMetaAds) {
|
|
2381
|
+
tools.push(
|
|
2382
|
+
tool(
|
|
2383
|
+
"META_ADS_SEARCH",
|
|
2384
|
+
"Scavio Meta Ads Search",
|
|
2385
|
+
"Search the Meta Ad Library by keyword: 30 ads on page 1 with the full creative -- page name, ad copy, headline, CTA, images and videos, the platforms each ran on and its run dates -- then 10 ads per cursor page, walking has_next_page to the end of the query. total_results caps at 50000 with total_is_capped true, because Meta only reports '>50,000'; never present it as an exact count. Every page costs 1 credit.",
|
|
2386
|
+
import_zod.z.object({
|
|
2387
|
+
query: str("Keyword to search the ad library for (1-200 characters)."),
|
|
2388
|
+
country: ostr("Ad library country as an exactly 2-character ISO 3166-1 alpha-2 code (server default 'US')."),
|
|
2389
|
+
active_status: ostr("Whether the ad is still running (server default 'all'). Accepted values: 'all', 'active', 'inactive'."),
|
|
2390
|
+
ad_type: ostr("Set 'political_and_issue_ads' to expose spend, reach, impressions and the paid-for-by disclosure; commercial ads leave all four null (server default 'all')."),
|
|
2391
|
+
media_type: ostr("Creative media filter. Default: no media filter. Accepted values: 'all', 'image', 'video', 'meme', 'image_and_meme', 'none'."),
|
|
2392
|
+
search_type: ostr("How the query is matched (server default 'keyword_unordered'). Accepted values: 'keyword_unordered', 'keyword_exact_phrase'."),
|
|
2393
|
+
cursor: ostr("next_cursor from the previous response: page 1 is 30 ads, every cursor page is 10. The cursor is a self-contained blob, so ALL other filters are ignored when it is present.")
|
|
2394
|
+
}),
|
|
2395
|
+
(i) => client.metaAds.search(i)
|
|
2396
|
+
),
|
|
2397
|
+
tool(
|
|
2398
|
+
"META_ADS_ADVERTISER",
|
|
2399
|
+
"Scavio Meta Ads Advertiser",
|
|
2400
|
+
"Every ad a Facebook Page is running, by numeric page id: 30 ads on page 1 with the same creative detail as search(), then 10 ads per cursor page, walking has_next_page to the end of the advertiser. Every page costs 1 credit.",
|
|
2401
|
+
import_zod.z.object({
|
|
2402
|
+
page_id: str("The advertiser's numeric Facebook Page id (3-25 digits, as a string)."),
|
|
2403
|
+
country: ostr("Ad library country as an exactly 2-character ISO 3166-1 alpha-2 code (server default 'US')."),
|
|
2404
|
+
active_status: ostr("Whether the ad is still running (server default 'all'). Accepted values: 'all', 'active', 'inactive'."),
|
|
2405
|
+
ad_type: ostr("Set 'political_and_issue_ads' to expose spend, reach, impressions and the paid-for-by disclosure; commercial ads leave all four null (server default 'all')."),
|
|
2406
|
+
media_type: ostr("Creative media filter. Default: no media filter. Accepted values: 'all', 'image', 'video', 'meme', 'image_and_meme', 'none'."),
|
|
2407
|
+
cursor: ostr("next_cursor from the previous response: page 1 is 30 ads, every cursor page is 10. ALL other filters are ignored when it is present.")
|
|
2408
|
+
}),
|
|
2409
|
+
(i) => client.metaAds.advertiser(i)
|
|
2410
|
+
),
|
|
2411
|
+
tool(
|
|
2412
|
+
"META_ADS_AD",
|
|
2413
|
+
"Scavio Meta Ads Ad",
|
|
2414
|
+
"One Meta ad in full by archive id: creative, advertiser, run dates, the platforms it ran on, and the political disclosure when the ad carries one. Commercial ads leave spend, reach and impressions null. Costs 1 credit.",
|
|
2415
|
+
import_zod.z.object({
|
|
2416
|
+
ad_archive_id: str("Meta ad archive id (3-25 digits, as a string).")
|
|
2417
|
+
}),
|
|
2418
|
+
(i) => client.metaAds.ad(i)
|
|
2419
|
+
)
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
if (all || enableExtract) {
|
|
2423
|
+
tools.push(
|
|
2424
|
+
tool(
|
|
2425
|
+
"EXTRACT",
|
|
2426
|
+
"Scavio Extract",
|
|
2427
|
+
"Read any URL and get the page back as raw HTML, readability Markdown or plain text: { url, format, mode, content, content_length }. Tier-priced by mode: 'normal' and 'advanced' cost 1 credit, 'ultra' costs 2. Only a successful extraction is billed - a dead link, bot wall or timeout costs nothing.",
|
|
2428
|
+
import_zod.z.object({
|
|
2429
|
+
url: str("Page to read (1-2048 characters). http(s) only; a bare host is upgraded to https, and loopback, private, link-local and metadata hosts are rejected with a 400."),
|
|
2430
|
+
format: ostr("Output format: 'html' is the raw page, 'markdown' a readability extraction, 'text' that markdown flattened to plain text (server default 'markdown')."),
|
|
2431
|
+
mode: ostr("Fetch tier, and the price-bearing parameter: 'normal' plain datacenter fetch (1 credit), 'advanced' full browser render (1 credit), 'ultra' the hardest-target tier (2 credits). Server default 'normal'.")
|
|
2432
|
+
}),
|
|
2433
|
+
(i) => client.extract(i)
|
|
2434
|
+
)
|
|
2435
|
+
);
|
|
2436
|
+
}
|
|
1203
2437
|
return (0, import_core.experimental_createToolkit)("SCAVIO", {
|
|
1204
2438
|
name: "Scavio",
|
|
1205
|
-
description: "Real-time structured search over Google (SERP, AI Mode, Maps, Shopping, Flights, Hotels, News, Trends), YouTube, Amazon, Walmart, Reddit, TikTok, TikTok Shop, Instagram, X and
|
|
2439
|
+
description: "Real-time structured search over 31 platforms - Google (SERP, AI Mode, Maps, Shopping, Flights, Hotels, News, Trends), YouTube, Amazon, Walmart, eBay, Target, Home Depot, Reddit, TikTok, TikTok Shop, Instagram, X, LinkedIn, Threads, Kuaishou, Zillow, Redfin, Booking.com, Airbnb, Tripadvisor, Yelp, Indeed, Glassdoor, the Apple App Store, Google Play, SEC EDGAR, Companies House, G2, Capterra, Google Ads Transparency and the Meta Ad Library - plus extract, which reads any URL as Markdown, plain text or raw HTML.",
|
|
1206
2440
|
tools
|
|
1207
2441
|
});
|
|
1208
2442
|
}
|