@wuapidev/sdk 0.1.0 → 0.1.2

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
@@ -1,12 +1,18 @@
1
- # wuapi
1
+ # wuapi TypeScript SDK
2
2
 
3
- TypeScript SDK for [wuapi](https://wuapi.dev), an unofficial WhatsApp API. Link your own WhatsApp numbers by QR code or pairing code, send and receive messages, manage chats, contacts, groups, communities and channels, split them into projects, and verify webhooks.
3
+ [![npm version](https://img.shields.io/npm/v/@wuapidev/sdk.svg)](https://www.npmjs.com/package/@wuapidev/sdk)
4
+ [![CI](https://github.com/wuapidev/wuapi-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/wuapidev/wuapi-typescript/actions/workflows/ci.yml)
5
+ [![license](https://img.shields.io/npm/l/@wuapidev/sdk.svg)](LICENSE)
6
+
7
+ TypeScript SDK for [wuapi](https://wuapi.dev), a secure, fast and scalable WhatsApp API for developers. Link your own WhatsApp numbers by QR code or pairing code, send and receive messages, manage chats, contacts, groups, communities and channels, split them into projects, and verify webhooks.
4
8
 
5
9
  - Zero runtime dependencies. Uses the global `fetch` and WebCrypto.
6
- - Runs on Node 18+, Bun, Deno and edge runtimes.
7
10
  - ESM with TypeScript types that match the [OpenAPI spec](https://wuapi.dev/openapi.json).
11
+ - Retries, timeouts and idempotency keys built in.
12
+
13
+ Docs: [wuapi.dev/docs](https://wuapi.dev/docs). OpenAPI: [wuapi.dev/openapi.json](https://wuapi.dev/openapi.json).
8
14
 
9
- > **Unofficial.** wuapi is not affiliated with, endorsed by or sponsored by WhatsApp or Meta, and it does not use the WhatsApp Business Platform (Cloud API). Numbers are linked as devices, the same way WhatsApp Web works. WhatsApp can restrict or ban numbers that behave like spam. You are responsible for your recipients' consent and for following WhatsApp's terms.
15
+ > **How it works.** wuapi does not use the WhatsApp Business Platform (Cloud API). Numbers are linked as devices, the same way WhatsApp Web works. WhatsApp can restrict or ban numbers that behave like spam. You are responsible for your recipients' consent and for following WhatsApp's terms.
10
16
 
11
17
  ## Install
12
18
 
@@ -15,7 +21,32 @@ npm install @wuapidev/sdk
15
21
  # or: pnpm add @wuapidev/sdk / yarn add @wuapidev/sdk / bun add @wuapidev/sdk
16
22
  ```
17
23
 
18
- Using a coding agent? Paste [wuapi.dev/llms-full.txt](https://wuapi.dev/llms-full.txt), the whole documentation as one Markdown file, or install the skills once with `npx skills add wuapi/skills`.
24
+ Using a coding agent? Paste [wuapi.dev/llms-full.txt](https://wuapi.dev/llms-full.txt), the whole documentation as one Markdown file.
25
+
26
+ ## Requirements
27
+
28
+ The SDK needs a global `fetch` and WebCrypto (`crypto.subtle`, for webhook signatures). It runs on:
29
+
30
+ - Node 18 or later
31
+ - Bun
32
+ - Deno: `import { Wuapi } from "npm:@wuapidev/sdk";`
33
+ - Edge runtimes with `fetch` and WebCrypto, such as Cloudflare Workers and Vercel Edge Functions
34
+
35
+ Elsewhere, pass your own implementation as `new Wuapi({ fetch })`. The package is ESM only.
36
+
37
+ ## Authentication
38
+
39
+ Create an API key in the dashboard at [wuapi.dev/app/api-keys](https://wuapi.dev/app/api-keys). Keys look like `wu_live_...` and are sent as `Authorization: Bearer <key>`. Keep them on your server.
40
+
41
+ ```ts
42
+ import { Wuapi } from "@wuapidev/sdk";
43
+
44
+ const wuapi = new Wuapi({ apiKey: process.env.WUAPI_API_KEY });
45
+ ```
46
+
47
+ `apiKey` falls back to the `WUAPI_API_KEY` environment variable, so `new Wuapi()` works when it is set. On runtimes without `process.env`, such as most edge runtimes, pass `apiKey` yourself. A missing key throws when the client is created.
48
+
49
+ An organization key reaches every project. A project key, created with `projects.apiKeys.create`, reaches only its project: see [Projects](#projects).
19
50
 
20
51
  ## Quickstart: link a number and send a message
21
52
 
@@ -56,8 +87,6 @@ console.log(message.id, message.status); // "queued"
56
87
 
57
88
  `proxyLocation` is required: every account connects through its own residential proxy, and `{ country, city }` says where it exits. `proxyLocations.list()` returns every supported pair (`country` is ISO 3166-1 alpha-2, `city` a lowercase slug); anything else answers `400 unsupported_proxy_location`. Search it with `q`, which ignores case and accents and returns the best match first: `proxyLocations.list({ q: "sao" })` starts with São Paulo.
58
89
 
59
- `apiKey` falls back to the `WUAPI_API_KEY` environment variable, so `new Wuapi()` works when it is set.
60
-
61
90
  A send returns the message with `status: "queued"`. The outcome arrives as the `message.sent` or `message.failed` webhook, or by calling `wuapi.messages.get(id)`. A recipient without WhatsApp fails with `error.code: "not_on_whatsapp"`.
62
91
 
63
92
  Every resource carries `object` (`"account"`, `"message"`, ...). Contacts are E.164 (`+584241112233`), or `lid:<digits>` when WhatsApp hides the number; groups are `…@g.us`, channels `…@newsletter`.
@@ -281,7 +310,7 @@ for (const line of report.projects) console.log(line.externalId, line.billableAc
281
310
 
282
311
  wuapi bills the organization across all its projects; `usage.byProject` is what you rebill from. `usage.get()` is the organization's own bill this month: every billable account includes 0.5 GB of proxy, pooled, so `proxyBytes` is everything used, `includedProxyBytes` the pool, and `proxyFeeCents` bills only `billableProxyBytes`, the traffic past it, at $3 per GB.
283
312
 
284
- ## Errors and retries
313
+ ## Errors
285
314
 
286
315
  Every non-2xx response throws a `WuapiError` with `status`, `code`, `message`, `details` and `requestId` (when the server sends `x-request-id`).
287
316
 
@@ -297,10 +326,26 @@ try {
297
326
  }
298
327
  ```
299
328
 
300
- The client retries up to `maxRetries` times (default 2):
329
+ A request that never got a response throws a `WuapiError` with `status: 0` and `code` set to `timeout`, `network_error` or `aborted` (your `signal` fired). The docs list every API error code.
330
+
331
+ ## Retries and timeouts
332
+
333
+ The client retries a failed request up to `maxRetries` times (default 2):
301
334
 
302
- - `429 rate_limited`, waiting for `Retry-After`.
303
- - 5xx responses, network errors and timeouts, with exponential backoff.
335
+ - `429 rate_limited`, waiting for `Retry-After` (at most 60 seconds).
336
+ - 5xx responses, network errors and timeouts, with exponential backoff and jitter, starting under 0.5 s and capped at 8 s.
337
+
338
+ Other 4xx responses throw right away. `timeoutMs` (default `30_000`) applies to each attempt. Cancel a call with an `AbortSignal`:
339
+
340
+ ```ts
341
+ const wuapi = new Wuapi({ timeoutMs: 10_000, maxRetries: 4 });
342
+
343
+ const controller = new AbortController();
344
+ setTimeout(() => controller.abort(), 5_000);
345
+ await wuapi.messages.get("msg_...", { signal: controller.signal });
346
+ ```
347
+
348
+ ## Idempotency
304
349
 
305
350
  Every `POST` carries an `Idempotency-Key` header, generated per call when you do not pass one, so a retried send or create is answered with the first response (`Idempotent-Replayed: true`) instead of running twice. Pass your own key to make retries across processes safe too:
306
351
 
@@ -348,8 +393,21 @@ new Wuapi({
348
393
  | `usage` | `get`, `byProject` |
349
394
  | client | `me()`, `withProject(project)`, `project` |
350
395
 
351
- Account-level resources take the `accountId` first. Full API reference: [wuapi.dev/docs](https://wuapi.dev/docs) and [openapi.json](https://wuapi.dev/openapi.json).
396
+ Account-level resources take the `accountId` first.
397
+
398
+ ## Links
399
+
400
+ - Documentation: [wuapi.dev/docs](https://wuapi.dev/docs)
401
+ - OpenAPI spec: [wuapi.dev/openapi.json](https://wuapi.dev/openapi.json)
402
+ - The docs as one Markdown file, for coding agents: [wuapi.dev/llms-full.txt](https://wuapi.dev/llms-full.txt)
403
+ - Releases and changelog: [GitHub Releases](https://github.com/wuapidev/wuapi-typescript/releases)
404
+
405
+ ## Contributing
406
+
407
+ This repository mirrors the SDK from the wuapi monorepo, where it is developed. Issues are welcome here, and a maintainer ports pull requests: see [CONTRIBUTING.md](CONTRIBUTING.md). To report a vulnerability, see [SECURITY.md](SECURITY.md).
352
408
 
353
409
  ## License
354
410
 
355
411
  MIT
412
+
413
+ wuapi is an independent service. It is not affiliated with, endorsed or sponsored by WhatsApp or Meta. WhatsApp is a trademark of Meta Platforms, Inc.
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CallOptions } from "./types.js";
2
- export declare const VERSION = "0.1.0";
2
+ export declare const VERSION = "0.1.2";
3
3
  export declare const DEFAULT_BASE_URL = "https://api.wuapi.dev";
4
4
  export type FetchLike = (input: string, init: RequestInit) => Promise<Response>;
5
5
  export interface ClientOptions {
package/dist/core.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WuapiError } from "./errors.js";
2
- export const VERSION = "0.1.0";
2
+ export const VERSION = "0.1.2";
3
3
  export const DEFAULT_BASE_URL = "https://api.wuapi.dev";
4
4
  export const PROJECT_HEADER = "Wuapi-Project";
5
5
  export const IDEMPOTENCY_HEADER = "Idempotency-Key";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wuapidev/sdk",
3
- "version": "0.1.0",
4
- "description": "TypeScript SDK for wuapi, an unofficial WhatsApp API. Link numbers by QR or pairing code, send and receive messages, manage chats, contacts, groups and channels, split them into projects and verify webhooks.",
3
+ "version": "0.1.2",
4
+ "description": "TypeScript SDK for wuapi, a WhatsApp API for developers. Link numbers by QR or pairing code, send and receive messages, manage chats, contacts, groups and channels, split them into projects and verify webhooks.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -25,7 +25,6 @@
25
25
  "keywords": [
26
26
  "whatsapp",
27
27
  "whatsapp-api",
28
- "unofficial",
29
28
  "messaging",
30
29
  "webhooks",
31
30
  "sdk"
@@ -33,17 +32,16 @@
33
32
  "homepage": "https://wuapi.dev/docs",
34
33
  "repository": {
35
34
  "type": "git",
36
- "url": "git+https://github.com/wuapidev/wuapi.git",
37
- "directory": "packages/wuapi-sdk"
35
+ "url": "git+https://github.com/wuapidev/wuapi-typescript.git"
38
36
  },
39
37
  "bugs": {
40
- "url": "https://github.com/wuapidev/wuapi/issues"
38
+ "url": "https://github.com/wuapidev/wuapi-typescript/issues"
41
39
  },
42
40
  "scripts": {
43
41
  "build": "rm -rf dist && tsc -p tsconfig.build.json",
44
42
  "typecheck": "tsc -p tsconfig.json --noEmit",
45
43
  "test": "vitest run",
46
- "prepublishOnly": "bun run typecheck && bun run test && bun run build"
44
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build"
47
45
  },
48
46
  "devDependencies": {
49
47
  "@types/node": "^22.10.0",