@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 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; Kirim cannot show it again.
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": "Kirim Public API",
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 Kirim org."
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 Kirim's internal model."
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": "Kirim Public API key. Format: `kdv_live_<24-char base64url>`. Issue keys in Settings → API Keys."
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; Kirim cannot show it again.",
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.0.2",
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
+ }