scavio 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,16 +33,31 @@ const client = new Scavio({
33
33
  baseUrl: "https://api.scavio.dev", // default
34
34
  timeout: 30_000, // ms, default
35
35
  maxRequestsPerSecond: 1, // 1-10, default 1
36
+ maxRetries: 2, // default 2, set 0 to disable
36
37
  });
37
38
  ```
38
39
 
40
+ `maxRetries` is the number of extra attempts after the first request, applied
41
+ only to transient failures — HTTP 429, 500, 502, 503, 504 and network or timeout
42
+ errors. Backoff is exponential with full jitter, capped at 8s, and a
43
+ `Retry-After` header is honored when the API sends one. Non-transient errors
44
+ (400, 401, 402, 404) are never retried.
45
+
46
+ `maxRequestsPerSecond` throttles the client so it never sends more than N
47
+ requests in any one-second window. Your plan also has a server-side concurrency
48
+ limit on simultaneous in-flight requests: 1 on free and pay-as-you-go, 2 on
49
+ Project, 3 on Bootstrap, 5 on Startup, 10 on Growth.
50
+
39
51
  ## API Reference
40
52
 
41
53
  ### Google
42
54
 
43
- Every method hits `/api/v2/google` and returns Google's full response (raw
44
- passthrough); each costs 1 credit. Any scrape.do parameter can be passed
45
- through.
55
+ Each method hits its own `/api/v2/google*` endpoint and returns Google's full
56
+ response (raw passthrough); each costs 1 credit. Results come back as
57
+ `organic_results[]` with `link` and `snippet`. Geo and paging use `gl`, `hl`,
58
+ `start`, `google_domain` and `device` — the old v1 vocabulary (`light_request`,
59
+ `country_code`, `language`, `search_type`, `page`) does not exist on v2 and is
60
+ dropped server-side.
46
61
 
47
62
  ```typescript
48
63
  // SERP search (includes the AI Overview when Google shows one)
@@ -129,6 +144,9 @@ await client.walmart.product({
129
144
 
130
145
  ### YouTube
131
146
 
147
+ Credit cost varies by endpoint: `transcript` costs 8; `streams` costs 3;
148
+ `search` and `shorts` cost 2; every other YouTube endpoint costs 1.
149
+
132
150
  ```typescript
133
151
  // Search videos
134
152
  await client.youtube.search({
@@ -176,6 +194,14 @@ await client.youtube.channelResolve({ channel: "@mkbhd" }); // handle/URL -> id
176
194
 
177
195
  ### Reddit
178
196
 
197
+ Every Reddit endpoint costs 1 credit.
198
+
199
+ `search()` takes only `query` and `cursor` — there is no result-type or sort
200
+ filter upstream, so anything else is dropped server-side. It returns
201
+ `data.results` with `next_cursor` and `has_more`. `post()` returns a flat post
202
+ object under `data` and carries no comments; use `postComments()` for those.
203
+ The subreddit and user feeds return `data.posts`.
204
+
179
205
  ```typescript
180
206
  // Search posts
181
207
  await client.reddit.search({ query: "typescript", cursor: "..." });
@@ -262,9 +288,11 @@ Credit cost varies by endpoint: `job` costs 30; `personPosts`, `companyPosts`,
262
288
  > `searchPosts`. They remain callable but always return HTTP 410 and are never
263
289
  > billed. `company()` returns `featured_employees` (a small sample of staff), and
264
290
  > `searchJobs()` with a company name substitutes for `companyJobs()`.
265
- >
266
- > `personPosts` and `companyPosts` return up to 50 posts; the provider exposes no
267
- > further pages, so those endpoints no longer take a cursor.
291
+
292
+ `personPosts`, `companyPosts` and `searchJobs` paginate: pass the previous
293
+ response's `next_cursor` as `cursor` to fetch the next page. `personPosts` also
294
+ takes `type` (`"posts"`, `"comments"` or `"reactions"`) to pick the feed.
295
+ `postComments` pages with a 1-based `page` instead.
268
296
 
269
297
  ### TikTok
270
298
 
@@ -284,8 +312,8 @@ await client.tiktok.videoComments({ video_id: "vid123", count: 20 });
284
312
  // Comment replies
285
313
  await client.tiktok.commentReplies({ video_id: "vid123", comment_id: "c456" });
286
314
 
287
- // Search videos
288
- await client.tiktok.searchVideos({ keyword: "dance", sort_type: "likes" });
315
+ // Search videos (sort_type: '0' = relevance, '1' = most likes)
316
+ await client.tiktok.searchVideos({ keyword: "dance", sort_type: "1" });
289
317
 
290
318
  // Search users
291
319
  await client.tiktok.searchUsers({ keyword: "cooking" });
@@ -364,8 +392,16 @@ await client.tiktokShop.resolve({ url: "https://vt.tiktok.com/ZT2AHoGsE/" });
364
392
 
365
393
  ### Instagram
366
394
 
367
- Credit cost varies by endpoint: `userPosts` costs 2 credits, every other
368
- Instagram endpoint costs 8.
395
+ Credit cost varies by endpoint, in three tiers:
396
+
397
+ | Credits | Methods |
398
+ |---|---|
399
+ | 2 | `userPosts` |
400
+ | 8 | `post`, `commentReplies` |
401
+ | 10 | `profile`, `userReels`, `userTagged`, `userStories`, `postComments`, `searchUsers`, `searchHashtags`, `userFollowers`, `userFollowings` |
402
+
403
+ The 10-credit endpoints run two upstream providers in parallel and bill both
404
+ legs; the 8-credit ones have no fallback leg to hedge against.
369
405
 
370
406
  ```typescript
371
407
  // User profile
@@ -422,12 +458,19 @@ All error classes:
422
458
  | Class | HTTP Status | Description |
423
459
  |-------|------------|-------------|
424
460
  | `MissingAPIKeyError` | — | No API key provided |
461
+ | `ScavioConnectionError` | — | Request never reached the API (DNS, reset, TLS) |
462
+ | `ScavioTimeoutError` | — | Request exceeded the configured `timeout` |
463
+ | `BadRequestError` | 400 | Invalid request parameters |
425
464
  | `InvalidAPIKeyError` | 401 | Invalid API key |
426
465
  | `InsufficientCreditsError` | 402 | No credits remaining |
427
- | `BadRequestError` | 400 | Invalid request parameters |
466
+ | `NotFoundError` | 404 | No data upstream for that id (see TikTok Shop above) |
428
467
  | `RateLimitError` | 429 | Rate limit exceeded |
429
468
  | `ScavioAPIError` | other | Catch-all (has `.statusCode`) |
430
469
 
470
+ Every class extends `ScavioError`, so `catch (e) { if (e instanceof ScavioError) }`
471
+ matches all of them. All except `MissingAPIKeyError`, `ScavioConnectionError` and
472
+ `ScavioTimeoutError` carry `.statusCode` and `.responseBody`.
473
+
431
474
  ## Runtime Support
432
475
 
433
476
  - Node.js 18+
package/dist/index.cjs CHANGED
@@ -398,12 +398,17 @@ var RedditNamespace = class {
398
398
  this.client = client;
399
399
  }
400
400
  client;
401
+ /** Returns `data.results` plus `next_cursor` / `has_more` (not `data.posts`). */
401
402
  async search(options) {
402
403
  return this.client._post("/api/v1/reddit/search", options);
403
404
  }
404
405
  async searchSuggestions(options) {
405
406
  return this.client._post("/api/v1/reddit/search/suggestions", options);
406
407
  }
408
+ /**
409
+ * Returns a flat post object under `data` (post_id, title, text, url,
410
+ * subreddit, author, score, ...). Comments are a separate call.
411
+ */
407
412
  async post(options) {
408
413
  return this.client._post("/api/v1/reddit/post", options);
409
414
  }