@kirimdev/sdk 3.0.2 → 3.1.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 +98 -98
- package/dist/generated/schema.d.ts +74 -3
- package/openapi.json +209 -8
- package/package.json +63 -63
package/README.md
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
# @kirimdev/sdk
|
|
2
|
-
|
|
3
|
-
Official TypeScript SDK for the [Kirimdev](https://kirimdev.com) Public API.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @kirimdev/sdk
|
|
9
|
-
# or
|
|
10
|
-
bun add @kirimdev/sdk
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Quickstart
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { Kirim } from '@kirimdev/sdk'
|
|
17
|
-
|
|
18
|
-
const kirim = new Kirim({ apiKey: process.env.KIRIM_API_KEY! })
|
|
19
|
-
|
|
20
|
-
// Scope to a WhatsApp phone number (Meta `business_phone_number_id`).
|
|
21
|
-
// Look it up via `kirim.accounts.list()` if you don't have it handy.
|
|
22
|
-
const phone = kirim.phoneNumbers('106540352242922')
|
|
23
|
-
|
|
24
|
-
// Send a message
|
|
25
|
-
const msg = await phone.messages.send({
|
|
26
|
-
messaging_product: 'whatsapp',
|
|
27
|
-
to: '628123456789',
|
|
28
|
-
type: 'text',
|
|
29
|
-
text: { body: 'Halo dari SDK!' },
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// Paginate
|
|
33
|
-
for await (const m of phone.messages.list({ limit: 50 })) {
|
|
34
|
-
console.log(m.id, m.status)
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Webhook verification
|
|
39
|
-
|
|
40
|
-
`verifyWebhookSignature` parses the `X-Kirim-Signature` header (Stripe-style
|
|
41
|
-
`t=<unix>,v1=<hex>` format), checks the timestamp against a tolerance window,
|
|
42
|
-
verifies the HMAC-SHA256 against one or more active secrets (supports rotation),
|
|
43
|
-
and returns the parsed JSON body. It **throws** on every failure mode — never
|
|
44
|
-
returns `false`. Uses Web Crypto so it runs unchanged on Node 18+, Bun, Deno,
|
|
45
|
-
and edge runtimes.
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
import { verifyWebhookSignature, InvalidSignatureError } from '@kirimdev/sdk/webhooks'
|
|
49
|
-
|
|
50
|
-
export async function POST(req: Request) {
|
|
51
|
-
const rawBody = await req.text()
|
|
52
|
-
try {
|
|
53
|
-
const event = await verifyWebhookSignature({
|
|
54
|
-
rawBody,
|
|
55
|
-
signatureHeader: req.headers.get('x-kirim-signature'),
|
|
56
|
-
secrets: [process.env.KIRIM_WEBHOOK_SECRET!],
|
|
57
|
-
})
|
|
58
|
-
// event is KirimWebhookEvent — narrow on event.type or event.object
|
|
59
|
-
return new Response('ok')
|
|
60
|
-
} catch (err) {
|
|
61
|
-
if (err instanceof InvalidSignatureError) return new Response('bad sig', { status: 401 })
|
|
62
|
-
throw err
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Errors thrown (all extend `KirimWebhookError`):
|
|
68
|
-
|
|
69
|
-
- `InvalidSignatureError` — header missing/malformed, or no `v1=` matched any provided secret
|
|
70
|
-
- `SignatureExpiredError` — `|now - t|` exceeds `toleranceSeconds` (default 300s)
|
|
71
|
-
- `MalformedPayloadError` — signature matched but body is not valid JSON
|
|
72
|
-
|
|
73
|
-
## Features
|
|
74
|
-
|
|
75
|
-
- Full coverage of the Kirimdev `/v1` API (~35 endpoints)
|
|
76
|
-
- Type-safe — generated from the live OpenAPI 3.1 spec
|
|
77
|
-
- Automatic retries with exponential backoff (429, 5xx, network errors)
|
|
78
|
-
- Automatic `Idempotency-Key` injection for POST requests
|
|
79
|
-
- Async iterator pagination (`for await ... of kirim.messages.list(...)`)
|
|
80
|
-
- Typed error class hierarchy keyed off stable API error codes
|
|
81
|
-
- Webhook HMAC-SHA256 verifier
|
|
82
|
-
- Zero Node-specific dependencies — works in Node 18+, Bun, Deno
|
|
83
|
-
|
|
84
|
-
## Configuration
|
|
85
|
-
|
|
86
|
-
```ts
|
|
87
|
-
new Kirim({
|
|
88
|
-
apiKey: 'kdv_live_...', // required
|
|
89
|
-
baseUrl: 'https://api.kirimdev.com/v1', // optional
|
|
90
|
-
timeout: 30_000, // ms, default 30s
|
|
91
|
-
maxRetries: 2, // default 2
|
|
92
|
-
fetch: globalThis.fetch, // injectable for testing
|
|
93
|
-
})
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## License
|
|
97
|
-
|
|
98
|
-
MIT
|
|
1
|
+
# @kirimdev/sdk
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for the [Kirimdev](https://kirimdev.com) Public API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kirimdev/sdk
|
|
9
|
+
# or
|
|
10
|
+
bun add @kirimdev/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Kirim } from '@kirimdev/sdk'
|
|
17
|
+
|
|
18
|
+
const kirim = new Kirim({ apiKey: process.env.KIRIM_API_KEY! })
|
|
19
|
+
|
|
20
|
+
// Scope to a WhatsApp phone number (Meta `business_phone_number_id`).
|
|
21
|
+
// Look it up via `kirim.accounts.list()` if you don't have it handy.
|
|
22
|
+
const phone = kirim.phoneNumbers('106540352242922')
|
|
23
|
+
|
|
24
|
+
// Send a message
|
|
25
|
+
const msg = await phone.messages.send({
|
|
26
|
+
messaging_product: 'whatsapp',
|
|
27
|
+
to: '628123456789',
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: { body: 'Halo dari SDK!' },
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Paginate
|
|
33
|
+
for await (const m of phone.messages.list({ limit: 50 })) {
|
|
34
|
+
console.log(m.id, m.status)
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Webhook verification
|
|
39
|
+
|
|
40
|
+
`verifyWebhookSignature` parses the `X-Kirim-Signature` header (Stripe-style
|
|
41
|
+
`t=<unix>,v1=<hex>` format), checks the timestamp against a tolerance window,
|
|
42
|
+
verifies the HMAC-SHA256 against one or more active secrets (supports rotation),
|
|
43
|
+
and returns the parsed JSON body. It **throws** on every failure mode — never
|
|
44
|
+
returns `false`. Uses Web Crypto so it runs unchanged on Node 18+, Bun, Deno,
|
|
45
|
+
and edge runtimes.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { verifyWebhookSignature, InvalidSignatureError } from '@kirimdev/sdk/webhooks'
|
|
49
|
+
|
|
50
|
+
export async function POST(req: Request) {
|
|
51
|
+
const rawBody = await req.text()
|
|
52
|
+
try {
|
|
53
|
+
const event = await verifyWebhookSignature({
|
|
54
|
+
rawBody,
|
|
55
|
+
signatureHeader: req.headers.get('x-kirim-signature'),
|
|
56
|
+
secrets: [process.env.KIRIM_WEBHOOK_SECRET!],
|
|
57
|
+
})
|
|
58
|
+
// event is KirimWebhookEvent — narrow on event.type or event.object
|
|
59
|
+
return new Response('ok')
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err instanceof InvalidSignatureError) return new Response('bad sig', { status: 401 })
|
|
62
|
+
throw err
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Errors thrown (all extend `KirimWebhookError`):
|
|
68
|
+
|
|
69
|
+
- `InvalidSignatureError` — header missing/malformed, or no `v1=` matched any provided secret
|
|
70
|
+
- `SignatureExpiredError` — `|now - t|` exceeds `toleranceSeconds` (default 300s)
|
|
71
|
+
- `MalformedPayloadError` — signature matched but body is not valid JSON
|
|
72
|
+
|
|
73
|
+
## Features
|
|
74
|
+
|
|
75
|
+
- Full coverage of the Kirimdev `/v1` API (~35 endpoints)
|
|
76
|
+
- Type-safe — generated from the live OpenAPI 3.1 spec
|
|
77
|
+
- Automatic retries with exponential backoff (429, 5xx, network errors)
|
|
78
|
+
- Automatic `Idempotency-Key` injection for POST requests
|
|
79
|
+
- Async iterator pagination (`for await ... of kirim.messages.list(...)`)
|
|
80
|
+
- Typed error class hierarchy keyed off stable API error codes
|
|
81
|
+
- Webhook HMAC-SHA256 verifier
|
|
82
|
+
- Zero Node-specific dependencies — works in Node 18+, Bun, Deno
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
new Kirim({
|
|
88
|
+
apiKey: 'kdv_live_...', // required
|
|
89
|
+
baseUrl: 'https://api.kirimdev.com/v1', // optional
|
|
90
|
+
timeout: 30_000, // ms, default 30s
|
|
91
|
+
maxRetries: 2, // default 2
|
|
92
|
+
fetch: globalThis.fetch, // injectable for testing
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -216,6 +216,7 @@ export interface paths {
|
|
|
216
216
|
};
|
|
217
217
|
header?: never;
|
|
218
218
|
path: {
|
|
219
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
219
220
|
phone_number_id: string;
|
|
220
221
|
};
|
|
221
222
|
cookie?: never;
|
|
@@ -295,14 +296,18 @@ export interface paths {
|
|
|
295
296
|
* **Outbound send** — body has a `type` field (`text`, `image`, `document`, `video`, `audio`, `template`, `interactive`). Body shape mirrors the Meta WhatsApp Cloud API; media variants accept either `link` (hosted URL) or `id` (Meta uploaded media). The sender is the WhatsApp account identified by `phone_number_id` in the URL path; there is no `from` field in the body. Pass `Idempotency-Key` to safely retry on network failure.
|
|
296
297
|
*
|
|
297
298
|
* **Read receipt** — body has `status: "read"` + `message_id` (the inbound wamid from your webhook). Sends a read receipt back to the sender so the double-tick turns blue on their phone. Optional `typing_indicator: { type: "text" }` shows a typing bubble alongside the receipt; Meta auto-dismisses after ~25 seconds or on first outbound message.
|
|
299
|
+
*
|
|
300
|
+
* **Pre-send validation** — the API performs compliance checks before queuing the send. A 422 response with `error.code` set to `marketing_opted_out` indicates the recipient has stopped marketing messages from your business (the customer did this via the WhatsApp app menu — webhook `user_preferences` notifies you of the change). `account_restricted` indicates Meta has restricted your WhatsApp account; check the account status via the dashboard. `consent_required` indicates the recipient has not opted in. `upstream_error` indicates the WhatsApp account is disconnected. None of these are retryable until the underlying condition changes.
|
|
298
301
|
*/
|
|
299
302
|
post: {
|
|
300
303
|
parameters: {
|
|
301
304
|
query?: never;
|
|
302
305
|
header?: {
|
|
306
|
+
/** @description Optional idempotency token. See /docs/idempotency. */
|
|
303
307
|
"idempotency-key"?: string;
|
|
304
308
|
};
|
|
305
309
|
path: {
|
|
310
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
306
311
|
phone_number_id: string;
|
|
307
312
|
};
|
|
308
313
|
cookie?: never;
|
|
@@ -395,7 +400,7 @@ export interface paths {
|
|
|
395
400
|
code: string;
|
|
396
401
|
policy?: string;
|
|
397
402
|
};
|
|
398
|
-
components?: {
|
|
403
|
+
components?: ({
|
|
399
404
|
/** @enum {string} */
|
|
400
405
|
type: "header" | "body" | "button";
|
|
401
406
|
/** @enum {string} */
|
|
@@ -404,7 +409,9 @@ export interface paths {
|
|
|
404
409
|
parameters?: {
|
|
405
410
|
[key: string]: unknown;
|
|
406
411
|
}[];
|
|
407
|
-
}
|
|
412
|
+
} & {
|
|
413
|
+
[key: string]: unknown;
|
|
414
|
+
})[];
|
|
408
415
|
};
|
|
409
416
|
} | {
|
|
410
417
|
/** @enum {string} */
|
|
@@ -503,6 +510,51 @@ export interface paths {
|
|
|
503
510
|
};
|
|
504
511
|
}[];
|
|
505
512
|
};
|
|
513
|
+
} | {
|
|
514
|
+
/** @enum {string} */
|
|
515
|
+
type: "reply_buttons";
|
|
516
|
+
header?: {
|
|
517
|
+
/** @enum {string} */
|
|
518
|
+
type: "text";
|
|
519
|
+
text: string;
|
|
520
|
+
} | {
|
|
521
|
+
/** @enum {string} */
|
|
522
|
+
type: "image";
|
|
523
|
+
image: {
|
|
524
|
+
/** Format: uri */
|
|
525
|
+
link: string;
|
|
526
|
+
};
|
|
527
|
+
} | {
|
|
528
|
+
/** @enum {string} */
|
|
529
|
+
type: "video";
|
|
530
|
+
video: {
|
|
531
|
+
/** Format: uri */
|
|
532
|
+
link: string;
|
|
533
|
+
};
|
|
534
|
+
} | {
|
|
535
|
+
/** @enum {string} */
|
|
536
|
+
type: "document";
|
|
537
|
+
document: {
|
|
538
|
+
/** Format: uri */
|
|
539
|
+
link: string;
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
body: {
|
|
543
|
+
text: string;
|
|
544
|
+
};
|
|
545
|
+
footer?: {
|
|
546
|
+
text: string;
|
|
547
|
+
};
|
|
548
|
+
action: {
|
|
549
|
+
buttons: {
|
|
550
|
+
/** @enum {string} */
|
|
551
|
+
type: "reply";
|
|
552
|
+
reply: {
|
|
553
|
+
id: string;
|
|
554
|
+
title: string;
|
|
555
|
+
};
|
|
556
|
+
}[];
|
|
557
|
+
};
|
|
506
558
|
};
|
|
507
559
|
} | {
|
|
508
560
|
/** @enum {string} */
|
|
@@ -616,6 +668,7 @@ export interface paths {
|
|
|
616
668
|
query?: never;
|
|
617
669
|
header?: never;
|
|
618
670
|
path: {
|
|
671
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
619
672
|
phone_number_id: string;
|
|
620
673
|
id: string;
|
|
621
674
|
};
|
|
@@ -717,6 +770,7 @@ export interface paths {
|
|
|
717
770
|
};
|
|
718
771
|
header?: never;
|
|
719
772
|
path: {
|
|
773
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
720
774
|
phone_number_id: string;
|
|
721
775
|
};
|
|
722
776
|
cookie?: never;
|
|
@@ -811,6 +865,7 @@ export interface paths {
|
|
|
811
865
|
};
|
|
812
866
|
header?: never;
|
|
813
867
|
path: {
|
|
868
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
814
869
|
phone_number_id: string;
|
|
815
870
|
name: string;
|
|
816
871
|
};
|
|
@@ -962,7 +1017,7 @@ export interface paths {
|
|
|
962
1017
|
put?: never;
|
|
963
1018
|
/**
|
|
964
1019
|
* Create a webhook subscription
|
|
965
|
-
* @description Create a webhook subscription. The response carries `initial_secret` ONCE — store it server-side immediately;
|
|
1020
|
+
* @description Create a webhook subscription. The response carries `initial_secret` ONCE — store it server-side immediately; Kirimdev cannot show it again.
|
|
966
1021
|
*/
|
|
967
1022
|
post: {
|
|
968
1023
|
parameters: {
|
|
@@ -1866,6 +1921,7 @@ export interface paths {
|
|
|
1866
1921
|
};
|
|
1867
1922
|
header?: never;
|
|
1868
1923
|
path: {
|
|
1924
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
1869
1925
|
phone_number_id: string;
|
|
1870
1926
|
};
|
|
1871
1927
|
cookie?: never;
|
|
@@ -1958,6 +2014,7 @@ export interface paths {
|
|
|
1958
2014
|
query?: never;
|
|
1959
2015
|
header?: never;
|
|
1960
2016
|
path: {
|
|
2017
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
1961
2018
|
phone_number_id: string;
|
|
1962
2019
|
id: string;
|
|
1963
2020
|
};
|
|
@@ -2044,6 +2101,7 @@ export interface paths {
|
|
|
2044
2101
|
query?: never;
|
|
2045
2102
|
header?: never;
|
|
2046
2103
|
path: {
|
|
2104
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2047
2105
|
phone_number_id: string;
|
|
2048
2106
|
id: string;
|
|
2049
2107
|
};
|
|
@@ -2147,6 +2205,7 @@ export interface paths {
|
|
|
2147
2205
|
};
|
|
2148
2206
|
header?: never;
|
|
2149
2207
|
path: {
|
|
2208
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2150
2209
|
phone_number_id: string;
|
|
2151
2210
|
};
|
|
2152
2211
|
cookie?: never;
|
|
@@ -2228,6 +2287,7 @@ export interface paths {
|
|
|
2228
2287
|
query?: never;
|
|
2229
2288
|
header?: never;
|
|
2230
2289
|
path: {
|
|
2290
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2231
2291
|
phone_number_id: string;
|
|
2232
2292
|
};
|
|
2233
2293
|
cookie?: never;
|
|
@@ -2330,6 +2390,7 @@ export interface paths {
|
|
|
2330
2390
|
query?: never;
|
|
2331
2391
|
header?: never;
|
|
2332
2392
|
path: {
|
|
2393
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2333
2394
|
phone_number_id: string;
|
|
2334
2395
|
id: string;
|
|
2335
2396
|
};
|
|
@@ -2413,6 +2474,7 @@ export interface paths {
|
|
|
2413
2474
|
query?: never;
|
|
2414
2475
|
header?: never;
|
|
2415
2476
|
path: {
|
|
2477
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2416
2478
|
phone_number_id: string;
|
|
2417
2479
|
id: string;
|
|
2418
2480
|
};
|
|
@@ -2496,6 +2558,7 @@ export interface paths {
|
|
|
2496
2558
|
query?: never;
|
|
2497
2559
|
header?: never;
|
|
2498
2560
|
path: {
|
|
2561
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2499
2562
|
phone_number_id: string;
|
|
2500
2563
|
id: string;
|
|
2501
2564
|
};
|
|
@@ -2596,6 +2659,7 @@ export interface paths {
|
|
|
2596
2659
|
query?: never;
|
|
2597
2660
|
header?: never;
|
|
2598
2661
|
path: {
|
|
2662
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2599
2663
|
phone_number_id: string;
|
|
2600
2664
|
id: string;
|
|
2601
2665
|
};
|
|
@@ -2694,6 +2758,7 @@ export interface paths {
|
|
|
2694
2758
|
query?: never;
|
|
2695
2759
|
header?: never;
|
|
2696
2760
|
path: {
|
|
2761
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2697
2762
|
phone_number_id: string;
|
|
2698
2763
|
id: string;
|
|
2699
2764
|
};
|
|
@@ -2794,6 +2859,7 @@ export interface paths {
|
|
|
2794
2859
|
query?: never;
|
|
2795
2860
|
header?: never;
|
|
2796
2861
|
path: {
|
|
2862
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2797
2863
|
phone_number_id: string;
|
|
2798
2864
|
id: string;
|
|
2799
2865
|
label_id: string;
|
|
@@ -2890,6 +2956,7 @@ export interface paths {
|
|
|
2890
2956
|
query?: never;
|
|
2891
2957
|
header?: never;
|
|
2892
2958
|
path: {
|
|
2959
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2893
2960
|
phone_number_id: string;
|
|
2894
2961
|
};
|
|
2895
2962
|
cookie?: never;
|
|
@@ -2991,6 +3058,7 @@ export interface paths {
|
|
|
2991
3058
|
query?: never;
|
|
2992
3059
|
header?: never;
|
|
2993
3060
|
path: {
|
|
3061
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
2994
3062
|
phone_number_id: string;
|
|
2995
3063
|
id: string;
|
|
2996
3064
|
};
|
|
@@ -3091,6 +3159,7 @@ export interface paths {
|
|
|
3091
3159
|
query?: never;
|
|
3092
3160
|
header?: never;
|
|
3093
3161
|
path: {
|
|
3162
|
+
/** @description Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row). */
|
|
3094
3163
|
phone_number_id: string;
|
|
3095
3164
|
id: string;
|
|
3096
3165
|
label_id: string;
|
|
@@ -3576,6 +3645,7 @@ export interface components {
|
|
|
3576
3645
|
conversation_id?: string;
|
|
3577
3646
|
message_id?: string;
|
|
3578
3647
|
error?: {
|
|
3648
|
+
/** @description Stable Kirim error code. Known values include `outside_24h_window`, `marketing_opted_out`, `marketing_blocked_by_user`, `recipient_unavailable`, `unsupported_message_type`, `account_restricted`, `account_locked`, `consent_required`, `permission_revoked`, `auth_expired`, `app_rate_limited`, `account_rate_limited`, `template_not_found`, `template_paused`, `template_policy_violation`, `flow_blocked`, `media_upload_failed`, `media_download_failed`, `undeliverable`, `policy_violation`, `upstream_error`. */
|
|
3579
3649
|
code: string;
|
|
3580
3650
|
message: string;
|
|
3581
3651
|
provider_code: number | null;
|
|
@@ -3750,6 +3820,7 @@ export interface components {
|
|
|
3750
3820
|
/** Format: date-time */
|
|
3751
3821
|
created_at: string;
|
|
3752
3822
|
error?: {
|
|
3823
|
+
/** @description Stable Kirim error code. Known values include `outside_24h_window`, `marketing_opted_out`, `marketing_blocked_by_user`, `recipient_unavailable`, `unsupported_message_type`, `account_restricted`, `account_locked`, `consent_required`, `permission_revoked`, `auth_expired`, `app_rate_limited`, `account_rate_limited`, `template_not_found`, `template_paused`, `template_policy_violation`, `flow_blocked`, `media_upload_failed`, `media_download_failed`, `undeliverable`, `policy_violation`, `upstream_error`. */
|
|
3753
3824
|
code: string;
|
|
3754
3825
|
message: string;
|
|
3755
3826
|
provider_code: number | null;
|
package/openapi.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
|
-
"title": "
|
|
4
|
+
"title": "Kirimdev Public API",
|
|
5
5
|
"version": "1.0.0",
|
|
6
6
|
"description": "Self-service REST API for sending WhatsApp messages, subscribing to events, and managing your inbox programmatically. See docs.kirimdev.com for guides and reference.",
|
|
7
7
|
"contact": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"name": "Templates",
|
|
33
|
-
"description": "List and inspect Meta-approved templates synced to your
|
|
33
|
+
"description": "List and inspect Meta-approved templates synced to your Kirimdev org."
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"name": "Conversations",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
"name": "Labels",
|
|
45
|
-
"description": "Coloured tags for contacts and conversations. Team-scoped per
|
|
45
|
+
"description": "Coloured tags for contacts and conversations. Team-scoped per Kirimdev's internal model."
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"name": "Webhook Subscriptions",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"type": "http",
|
|
60
60
|
"scheme": "bearer",
|
|
61
61
|
"bearerFormat": "API Key",
|
|
62
|
-
"description": "
|
|
62
|
+
"description": "Kirimdev Public API key. Format: `kdv_live_<24-char base64url>`. Issue keys in Settings → API Keys."
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"schemas": {
|
|
@@ -144,7 +144,8 @@
|
|
|
144
144
|
"type": "object",
|
|
145
145
|
"properties": {
|
|
146
146
|
"code": {
|
|
147
|
-
"type": "string"
|
|
147
|
+
"type": "string",
|
|
148
|
+
"description": "Stable Kirim error code. Known values include `outside_24h_window`, `marketing_opted_out`, `marketing_blocked_by_user`, `recipient_unavailable`, `unsupported_message_type`, `account_restricted`, `account_locked`, `consent_required`, `permission_revoked`, `auth_expired`, `app_rate_limited`, `account_rate_limited`, `template_not_found`, `template_paused`, `template_policy_violation`, `flow_blocked`, `media_upload_failed`, `media_download_failed`, `undeliverable`, `policy_violation`, `upstream_error`."
|
|
148
149
|
},
|
|
149
150
|
"message": {
|
|
150
151
|
"type": "string"
|
|
@@ -811,7 +812,8 @@
|
|
|
811
812
|
"type": "object",
|
|
812
813
|
"properties": {
|
|
813
814
|
"code": {
|
|
814
|
-
"type": "string"
|
|
815
|
+
"type": "string",
|
|
816
|
+
"description": "Stable Kirim error code. Known values include `outside_24h_window`, `marketing_opted_out`, `marketing_blocked_by_user`, `recipient_unavailable`, `unsupported_message_type`, `account_restricted`, `account_locked`, `consent_required`, `permission_revoked`, `auth_expired`, `app_rate_limited`, `account_rate_limited`, `template_not_found`, `template_paused`, `template_policy_violation`, `flow_blocked`, `media_upload_failed`, `media_download_failed`, `undeliverable`, `policy_violation`, `upstream_error`."
|
|
815
817
|
},
|
|
816
818
|
"message": {
|
|
817
819
|
"type": "string"
|
|
@@ -2001,7 +2003,7 @@
|
|
|
2001
2003
|
"Messages"
|
|
2002
2004
|
],
|
|
2003
2005
|
"summary": "Send a WhatsApp message or mark inbound as read",
|
|
2004
|
-
"description": "Meta-style messages endpoint. Two operations share the same path, distinguished by the request body:\n\n**Outbound send** — body has a `type` field (`text`, `image`, `document`, `video`, `audio`, `template`, `interactive`). Body shape mirrors the Meta WhatsApp Cloud API; media variants accept either `link` (hosted URL) or `id` (Meta uploaded media). The sender is the WhatsApp account identified by `phone_number_id` in the URL path; there is no `from` field in the body. Pass `Idempotency-Key` to safely retry on network failure.\n\n**Read receipt** — body has `status: \"read\"` + `message_id` (the inbound wamid from your webhook). Sends a read receipt back to the sender so the double-tick turns blue on their phone. Optional `typing_indicator: { type: \"text\" }` shows a typing bubble alongside the receipt; Meta auto-dismisses after ~25 seconds or on first outbound message.",
|
|
2006
|
+
"description": "Meta-style messages endpoint. Two operations share the same path, distinguished by the request body:\n\n**Outbound send** — body has a `type` field (`text`, `image`, `document`, `video`, `audio`, `template`, `interactive`). Body shape mirrors the Meta WhatsApp Cloud API; media variants accept either `link` (hosted URL) or `id` (Meta uploaded media). The sender is the WhatsApp account identified by `phone_number_id` in the URL path; there is no `from` field in the body. Pass `Idempotency-Key` to safely retry on network failure.\n\n**Read receipt** — body has `status: \"read\"` + `message_id` (the inbound wamid from your webhook). Sends a read receipt back to the sender so the double-tick turns blue on their phone. Optional `typing_indicator: { type: \"text\" }` shows a typing bubble alongside the receipt; Meta auto-dismisses after ~25 seconds or on first outbound message.\n\n**Pre-send validation** — the API performs compliance checks before queuing the send. A 422 response with `error.code` set to `marketing_opted_out` indicates the recipient has stopped marketing messages from your business (the customer did this via the WhatsApp app menu — webhook `user_preferences` notifies you of the change). `account_restricted` indicates Meta has restricted your WhatsApp account; check the account status via the dashboard. `consent_required` indicates the recipient has not opted in. `upstream_error` indicates the WhatsApp account is disconnected. None of these are retryable until the underlying condition changes.",
|
|
2005
2007
|
"security": [
|
|
2006
2008
|
{
|
|
2007
2009
|
"bearerAuth": []
|
|
@@ -2845,6 +2847,205 @@
|
|
|
2845
2847
|
"action"
|
|
2846
2848
|
],
|
|
2847
2849
|
"title": "Carousel"
|
|
2850
|
+
},
|
|
2851
|
+
{
|
|
2852
|
+
"type": "object",
|
|
2853
|
+
"properties": {
|
|
2854
|
+
"type": {
|
|
2855
|
+
"type": "string",
|
|
2856
|
+
"enum": [
|
|
2857
|
+
"reply_buttons"
|
|
2858
|
+
]
|
|
2859
|
+
},
|
|
2860
|
+
"header": {
|
|
2861
|
+
"oneOf": [
|
|
2862
|
+
{
|
|
2863
|
+
"type": "object",
|
|
2864
|
+
"properties": {
|
|
2865
|
+
"type": {
|
|
2866
|
+
"type": "string",
|
|
2867
|
+
"enum": [
|
|
2868
|
+
"text"
|
|
2869
|
+
]
|
|
2870
|
+
},
|
|
2871
|
+
"text": {
|
|
2872
|
+
"type": "string",
|
|
2873
|
+
"minLength": 1,
|
|
2874
|
+
"maxLength": 60
|
|
2875
|
+
}
|
|
2876
|
+
},
|
|
2877
|
+
"required": [
|
|
2878
|
+
"type",
|
|
2879
|
+
"text"
|
|
2880
|
+
],
|
|
2881
|
+
"title": "Text header"
|
|
2882
|
+
},
|
|
2883
|
+
{
|
|
2884
|
+
"type": "object",
|
|
2885
|
+
"properties": {
|
|
2886
|
+
"type": {
|
|
2887
|
+
"type": "string",
|
|
2888
|
+
"enum": [
|
|
2889
|
+
"image"
|
|
2890
|
+
]
|
|
2891
|
+
},
|
|
2892
|
+
"image": {
|
|
2893
|
+
"type": "object",
|
|
2894
|
+
"properties": {
|
|
2895
|
+
"link": {
|
|
2896
|
+
"type": "string",
|
|
2897
|
+
"format": "uri"
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2900
|
+
"required": [
|
|
2901
|
+
"link"
|
|
2902
|
+
]
|
|
2903
|
+
}
|
|
2904
|
+
},
|
|
2905
|
+
"required": [
|
|
2906
|
+
"type",
|
|
2907
|
+
"image"
|
|
2908
|
+
],
|
|
2909
|
+
"title": "Image header"
|
|
2910
|
+
},
|
|
2911
|
+
{
|
|
2912
|
+
"type": "object",
|
|
2913
|
+
"properties": {
|
|
2914
|
+
"type": {
|
|
2915
|
+
"type": "string",
|
|
2916
|
+
"enum": [
|
|
2917
|
+
"video"
|
|
2918
|
+
]
|
|
2919
|
+
},
|
|
2920
|
+
"video": {
|
|
2921
|
+
"type": "object",
|
|
2922
|
+
"properties": {
|
|
2923
|
+
"link": {
|
|
2924
|
+
"type": "string",
|
|
2925
|
+
"format": "uri"
|
|
2926
|
+
}
|
|
2927
|
+
},
|
|
2928
|
+
"required": [
|
|
2929
|
+
"link"
|
|
2930
|
+
]
|
|
2931
|
+
}
|
|
2932
|
+
},
|
|
2933
|
+
"required": [
|
|
2934
|
+
"type",
|
|
2935
|
+
"video"
|
|
2936
|
+
],
|
|
2937
|
+
"title": "Video header"
|
|
2938
|
+
},
|
|
2939
|
+
{
|
|
2940
|
+
"type": "object",
|
|
2941
|
+
"properties": {
|
|
2942
|
+
"type": {
|
|
2943
|
+
"type": "string",
|
|
2944
|
+
"enum": [
|
|
2945
|
+
"document"
|
|
2946
|
+
]
|
|
2947
|
+
},
|
|
2948
|
+
"document": {
|
|
2949
|
+
"type": "object",
|
|
2950
|
+
"properties": {
|
|
2951
|
+
"link": {
|
|
2952
|
+
"type": "string",
|
|
2953
|
+
"format": "uri"
|
|
2954
|
+
}
|
|
2955
|
+
},
|
|
2956
|
+
"required": [
|
|
2957
|
+
"link"
|
|
2958
|
+
]
|
|
2959
|
+
}
|
|
2960
|
+
},
|
|
2961
|
+
"required": [
|
|
2962
|
+
"type",
|
|
2963
|
+
"document"
|
|
2964
|
+
],
|
|
2965
|
+
"title": "Document header"
|
|
2966
|
+
}
|
|
2967
|
+
]
|
|
2968
|
+
},
|
|
2969
|
+
"body": {
|
|
2970
|
+
"type": "object",
|
|
2971
|
+
"properties": {
|
|
2972
|
+
"text": {
|
|
2973
|
+
"type": "string",
|
|
2974
|
+
"minLength": 1,
|
|
2975
|
+
"maxLength": 1024
|
|
2976
|
+
}
|
|
2977
|
+
},
|
|
2978
|
+
"required": [
|
|
2979
|
+
"text"
|
|
2980
|
+
]
|
|
2981
|
+
},
|
|
2982
|
+
"footer": {
|
|
2983
|
+
"type": "object",
|
|
2984
|
+
"properties": {
|
|
2985
|
+
"text": {
|
|
2986
|
+
"type": "string",
|
|
2987
|
+
"minLength": 1,
|
|
2988
|
+
"maxLength": 60
|
|
2989
|
+
}
|
|
2990
|
+
},
|
|
2991
|
+
"required": [
|
|
2992
|
+
"text"
|
|
2993
|
+
]
|
|
2994
|
+
},
|
|
2995
|
+
"action": {
|
|
2996
|
+
"type": "object",
|
|
2997
|
+
"properties": {
|
|
2998
|
+
"buttons": {
|
|
2999
|
+
"type": "array",
|
|
3000
|
+
"items": {
|
|
3001
|
+
"type": "object",
|
|
3002
|
+
"properties": {
|
|
3003
|
+
"type": {
|
|
3004
|
+
"type": "string",
|
|
3005
|
+
"enum": [
|
|
3006
|
+
"reply"
|
|
3007
|
+
]
|
|
3008
|
+
},
|
|
3009
|
+
"reply": {
|
|
3010
|
+
"type": "object",
|
|
3011
|
+
"properties": {
|
|
3012
|
+
"id": {
|
|
3013
|
+
"type": "string",
|
|
3014
|
+
"minLength": 1,
|
|
3015
|
+
"maxLength": 256
|
|
3016
|
+
},
|
|
3017
|
+
"title": {
|
|
3018
|
+
"type": "string",
|
|
3019
|
+
"minLength": 1,
|
|
3020
|
+
"maxLength": 20
|
|
3021
|
+
}
|
|
3022
|
+
},
|
|
3023
|
+
"required": [
|
|
3024
|
+
"id",
|
|
3025
|
+
"title"
|
|
3026
|
+
]
|
|
3027
|
+
}
|
|
3028
|
+
},
|
|
3029
|
+
"required": [
|
|
3030
|
+
"type",
|
|
3031
|
+
"reply"
|
|
3032
|
+
]
|
|
3033
|
+
},
|
|
3034
|
+
"minItems": 1,
|
|
3035
|
+
"maxItems": 3
|
|
3036
|
+
}
|
|
3037
|
+
},
|
|
3038
|
+
"required": [
|
|
3039
|
+
"buttons"
|
|
3040
|
+
]
|
|
3041
|
+
}
|
|
3042
|
+
},
|
|
3043
|
+
"required": [
|
|
3044
|
+
"type",
|
|
3045
|
+
"body",
|
|
3046
|
+
"action"
|
|
3047
|
+
],
|
|
3048
|
+
"title": "Reply buttons"
|
|
2848
3049
|
}
|
|
2849
3050
|
]
|
|
2850
3051
|
}
|
|
@@ -3534,7 +3735,7 @@
|
|
|
3534
3735
|
"Webhook Subscriptions"
|
|
3535
3736
|
],
|
|
3536
3737
|
"summary": "Create a webhook subscription",
|
|
3537
|
-
"description": "Create a webhook subscription. The response carries `initial_secret` ONCE — store it server-side immediately;
|
|
3738
|
+
"description": "Create a webhook subscription. The response carries `initial_secret` ONCE — store it server-side immediately; Kirimdev cannot show it again.",
|
|
3538
3739
|
"security": [
|
|
3539
3740
|
{
|
|
3540
3741
|
"bearerAuth": []
|
package/package.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@kirimdev/sdk",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Official TypeScript SDK for the Kirimdev Public API.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"publishConfig": {
|
|
8
|
-
"access": "public",
|
|
9
|
-
"registry": "https://registry.npmjs.org/"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"kirim",
|
|
13
|
-
"whatsapp",
|
|
14
|
-
"whatsapp-business",
|
|
15
|
-
"sdk",
|
|
16
|
-
"api-client"
|
|
17
|
-
],
|
|
18
|
-
"files": [
|
|
19
|
-
"dist",
|
|
20
|
-
"openapi.json",
|
|
21
|
-
"README.md",
|
|
22
|
-
"LICENSE"
|
|
23
|
-
],
|
|
24
|
-
"main": "./dist/index.js",
|
|
25
|
-
"module": "./dist/index.js",
|
|
26
|
-
"types": "./dist/index.d.ts",
|
|
27
|
-
"exports": {
|
|
28
|
-
".": {
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js"
|
|
31
|
-
},
|
|
32
|
-
"./webhooks": {
|
|
33
|
-
"types": "./dist/webhooks.d.ts",
|
|
34
|
-
"import": "./dist/webhooks.js"
|
|
35
|
-
},
|
|
36
|
-
"./package.json": "./package.json"
|
|
37
|
-
},
|
|
38
|
-
"engines": {
|
|
39
|
-
"node": ">=18"
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"prebuild": "bun scripts/ensure-types.ts",
|
|
43
|
-
"build": "tsc -p tsconfig.build.json && bun scripts/copy-generated.ts",
|
|
44
|
-
"pretypecheck": "bun scripts/ensure-types.ts",
|
|
45
|
-
"typecheck": "tsc --noEmit",
|
|
46
|
-
"pretest": "bun scripts/ensure-types.ts",
|
|
47
|
-
"test": "bun test",
|
|
48
|
-
"lint": "tsc --noEmit",
|
|
49
|
-
"sync": "bun scripts/sync-openapi.ts && bun scripts/generate-types.ts",
|
|
50
|
-
"generate-types": "bun scripts/generate-types.ts",
|
|
51
|
-
"check:drift": "bun scripts/check-drift.ts",
|
|
52
|
-
"prepublishOnly": "bun run typecheck && bun run test && bun run build && bun scripts/verify-dist.ts"
|
|
53
|
-
},
|
|
54
|
-
"dependencies": {
|
|
55
|
-
"openapi-fetch": "^0.13.0"
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@kirimdev/tsconfig": "workspace:*",
|
|
59
|
-
"@types/bun": "latest",
|
|
60
|
-
"openapi-typescript": "^7.4.0",
|
|
61
|
-
"typescript": "^5.8.0"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@kirimdev/sdk",
|
|
3
|
+
"version": "3.1.1",
|
|
4
|
+
"description": "Official TypeScript SDK for the Kirimdev Public API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"registry": "https://registry.npmjs.org/"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"kirim",
|
|
13
|
+
"whatsapp",
|
|
14
|
+
"whatsapp-business",
|
|
15
|
+
"sdk",
|
|
16
|
+
"api-client"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"openapi.json",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./webhooks": {
|
|
33
|
+
"types": "./dist/webhooks.d.ts",
|
|
34
|
+
"import": "./dist/webhooks.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"prebuild": "bun scripts/ensure-types.ts",
|
|
43
|
+
"build": "tsc -p tsconfig.build.json && bun scripts/copy-generated.ts",
|
|
44
|
+
"pretypecheck": "bun scripts/ensure-types.ts",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"pretest": "bun scripts/ensure-types.ts",
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"lint": "tsc --noEmit",
|
|
49
|
+
"sync": "bun scripts/sync-openapi.ts && bun scripts/generate-types.ts",
|
|
50
|
+
"generate-types": "bun scripts/generate-types.ts",
|
|
51
|
+
"check:drift": "bun scripts/check-drift.ts",
|
|
52
|
+
"prepublishOnly": "bun run typecheck && bun run test && bun run build && bun scripts/verify-dist.ts"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"openapi-fetch": "^0.13.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@kirimdev/tsconfig": "workspace:*",
|
|
59
|
+
"@types/bun": "latest",
|
|
60
|
+
"openapi-typescript": "^7.4.0",
|
|
61
|
+
"typescript": "^5.8.0"
|
|
62
|
+
}
|
|
63
|
+
}
|