@getanyapi/sdk 0.1.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 +132 -0
- package/dist/index.cjs +5193 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +13840 -0
- package/dist/index.d.ts +13840 -0
- package/dist/index.js +5098 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# @getanyapi/sdk
|
|
2
|
+
|
|
3
|
+
Official typed TypeScript SDK for [AnyAPI](https://getanyapi.com): any API, one wallet, USD,
|
|
4
|
+
no subscriptions. Reach hundreds of scraping and data APIs through one interface and one key;
|
|
5
|
+
pay per request in real US dollars. Zero runtime dependencies (global `fetch`), ESM + CJS,
|
|
6
|
+
Node 18+ and edge runtimes.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @getanyapi/sdk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Quickstart
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { AnyAPI } from "@getanyapi/sdk";
|
|
16
|
+
|
|
17
|
+
// Reads ANYAPI_API_KEY from the environment when apiKey is omitted.
|
|
18
|
+
const client = new AnyAPI({ apiKey: process.env.ANYAPI_API_KEY });
|
|
19
|
+
|
|
20
|
+
const res = await client.reddit.search({ query: "mechanical keyboard" });
|
|
21
|
+
for (const post of res.output.posts) {
|
|
22
|
+
console.log(post.title, post.score);
|
|
23
|
+
}
|
|
24
|
+
console.log("charged", res.costUsd, "USD");
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Every SKU is a typed method under its platform namespace (`client.amazon.reviews(...)`,
|
|
28
|
+
`client.google.search(...)`). You can also call any SKU generically by slug with full typing:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const rev = await client.run("amazon.reviews", { product: "B07FZ8S74R", limit: 3 });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Not found vs error
|
|
35
|
+
|
|
36
|
+
A successful call always resolves. For most SKUs the payload is wrapped in a `found` flag:
|
|
37
|
+
`output.found` is `false` when the upstream had no matching entity (this is not an error).
|
|
38
|
+
Use `unwrap` to get the data or throw `ResultNotFoundError` when empty:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { unwrap, ResultNotFoundError } from "@getanyapi/sdk";
|
|
42
|
+
|
|
43
|
+
const res = await client.amazon.reviews({ product: "B07FZ8S74R" });
|
|
44
|
+
try {
|
|
45
|
+
const data = unwrap(res); // the typed data payload, or throws
|
|
46
|
+
} catch (e) {
|
|
47
|
+
if (e instanceof ResultNotFoundError) {
|
|
48
|
+
// empty result (found: false), not an HTTP failure
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`ResultNotFoundError` extends `NotFoundError`, so `catch (NotFoundError)` catches both an
|
|
54
|
+
HTTP 404 and an empty result; catch `ResultNotFoundError` to handle only empty results. A few
|
|
55
|
+
SKUs (e.g. `reddit.search`) return their data object directly as `output` with no `found`
|
|
56
|
+
wrapper; `unwrap` returns it as-is and never throws for those.
|
|
57
|
+
|
|
58
|
+
## Pagination
|
|
59
|
+
|
|
60
|
+
Paginated SKUs expose an iterator that yields items across pages and follows the cursor for
|
|
61
|
+
you. Call `.pages()` on it to walk whole results instead (each carries its own `costUsd`).
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// Flatten items across pages, capped at 100 total.
|
|
65
|
+
for await (const post of client.reddit.iterSearch({ query: "coffee" }, { maxItems: 100 })) {
|
|
66
|
+
console.log(post.title);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Or walk pages to read per-page cost.
|
|
70
|
+
for await (const page of client.reddit.iterSearch({ query: "coffee" }).pages()) {
|
|
71
|
+
console.log(page.costUsd);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Request options (context-cost savers)
|
|
76
|
+
|
|
77
|
+
Pass a second argument to shape the response. These trim what comes back but do NOT change the
|
|
78
|
+
price:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
await client.google.search(
|
|
82
|
+
{ query: "coffee" },
|
|
83
|
+
{
|
|
84
|
+
fields: ["title", "link"], // keep only these keys on each item
|
|
85
|
+
maxItems: 5, // cap result rows returned
|
|
86
|
+
summary: true, // structural outline instead of full data
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Per-call transport overrides: `timeoutMs`, `maxRetries`, and an `AbortSignal` via `signal`.
|
|
92
|
+
|
|
93
|
+
## Errors and retries
|
|
94
|
+
|
|
95
|
+
| Class | HTTP | Meaning |
|
|
96
|
+
| --- | --- | --- |
|
|
97
|
+
| `BadRequestError` | 400 | Input failed validation |
|
|
98
|
+
| `AuthenticationError` | 401 | Missing or invalid API key |
|
|
99
|
+
| `InsufficientBalanceError` | 402 | Wallet balance or per-key cap exceeded |
|
|
100
|
+
| `NotFoundError` | 404 | Slug or resource does not exist |
|
|
101
|
+
| `ResultNotFoundError` | - | `unwrap` on an empty found-data result |
|
|
102
|
+
| `RateLimitedError` | 429 | Too many requests (retried automatically) |
|
|
103
|
+
| `UpstreamError` | 502 | An upstream backend failed |
|
|
104
|
+
| `ConnectionError` | 0 | Network or transport failure (retried) |
|
|
105
|
+
| `TimeoutError` | 0 | Request exceeded its timeout (not retried) |
|
|
106
|
+
|
|
107
|
+
All extend `AnyAPIError` (with `status` and `requestId`). Retries cover only 429 and network
|
|
108
|
+
failures, with jittered exponential backoff honoring `Retry-After`. Default `maxRetries` is 2
|
|
109
|
+
(up to 3 attempts); set it on the client or per request. Timeouts are never retried. Configure
|
|
110
|
+
with `new AnyAPI({ timeoutMs, maxRetries })`.
|
|
111
|
+
|
|
112
|
+
## Agent signup
|
|
113
|
+
|
|
114
|
+
Bootstrap a key with no account (for autonomous agents):
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { agentSignup } from "@getanyapi/sdk";
|
|
118
|
+
|
|
119
|
+
const { secret, capUsd, claimUrl } = await agentSignup({ label: "my-agent" });
|
|
120
|
+
const client = new AnyAPI({ apiKey: secret });
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The key ships with a small starter credit and a per-key spend cap; a human funds it by
|
|
124
|
+
claiming it at `claimUrl`.
|
|
125
|
+
|
|
126
|
+
## Docs
|
|
127
|
+
|
|
128
|
+
Full API reference and catalog: [getanyapi.com/docs](https://getanyapi.com/docs).
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT
|