@linqapp/sdk 0.1.5 → 0.4.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.
Files changed (189) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +31 -0
  3. package/client.d.mts +299 -7
  4. package/client.d.mts.map +1 -1
  5. package/client.d.ts +299 -7
  6. package/client.d.ts.map +1 -1
  7. package/client.js +294 -12
  8. package/client.js.map +1 -1
  9. package/client.mjs +294 -12
  10. package/client.mjs.map +1 -1
  11. package/core/pagination.d.mts +69 -0
  12. package/core/pagination.d.mts.map +1 -0
  13. package/core/pagination.d.ts +69 -0
  14. package/core/pagination.d.ts.map +1 -0
  15. package/core/pagination.js +125 -0
  16. package/core/pagination.js.map +1 -0
  17. package/core/pagination.mjs +118 -0
  18. package/core/pagination.mjs.map +1 -0
  19. package/index.d.mts +1 -0
  20. package/index.d.mts.map +1 -1
  21. package/index.d.ts +1 -0
  22. package/index.d.ts.map +1 -1
  23. package/index.js +3 -1
  24. package/index.js.map +1 -1
  25. package/index.mjs +1 -0
  26. package/index.mjs.map +1 -1
  27. package/internal/tslib.js +18 -18
  28. package/internal/utils/query.d.mts +5 -0
  29. package/internal/utils/query.d.mts.map +1 -0
  30. package/internal/utils/query.d.ts +5 -0
  31. package/internal/utils/query.d.ts.map +1 -0
  32. package/internal/utils/query.js +23 -0
  33. package/internal/utils/query.js.map +1 -0
  34. package/internal/utils/query.mjs +20 -0
  35. package/internal/utils/query.mjs.map +1 -0
  36. package/internal/utils.d.mts +1 -0
  37. package/internal/utils.d.ts +1 -0
  38. package/internal/utils.js +1 -0
  39. package/internal/utils.js.map +1 -1
  40. package/internal/utils.mjs +1 -0
  41. package/package.json +11 -1
  42. package/pagination.d.mts +2 -0
  43. package/pagination.d.mts.map +1 -0
  44. package/pagination.d.ts +2 -0
  45. package/pagination.d.ts.map +1 -0
  46. package/pagination.js +6 -0
  47. package/pagination.js.map +1 -0
  48. package/pagination.mjs +2 -0
  49. package/pagination.mjs.map +1 -0
  50. package/resources/attachments.d.mts +64 -0
  51. package/resources/attachments.d.mts.map +1 -1
  52. package/resources/attachments.d.ts +64 -0
  53. package/resources/attachments.d.ts.map +1 -1
  54. package/resources/attachments.js +64 -0
  55. package/resources/attachments.js.map +1 -1
  56. package/resources/attachments.mjs +64 -0
  57. package/resources/attachments.mjs.map +1 -1
  58. package/resources/capability.d.mts +12 -9
  59. package/resources/capability.d.mts.map +1 -1
  60. package/resources/capability.d.ts +12 -9
  61. package/resources/capability.d.ts.map +1 -1
  62. package/resources/capability.js +7 -4
  63. package/resources/capability.js.map +1 -1
  64. package/resources/capability.mjs +7 -4
  65. package/resources/capability.mjs.map +1 -1
  66. package/resources/chats/chats.d.mts +76 -97
  67. package/resources/chats/chats.d.mts.map +1 -1
  68. package/resources/chats/chats.d.ts +76 -97
  69. package/resources/chats/chats.d.ts.map +1 -1
  70. package/resources/chats/chats.js +8 -4
  71. package/resources/chats/chats.js.map +1 -1
  72. package/resources/chats/chats.mjs +9 -5
  73. package/resources/chats/chats.mjs.map +1 -1
  74. package/resources/chats/index.d.mts +2 -2
  75. package/resources/chats/index.d.mts.map +1 -1
  76. package/resources/chats/index.d.ts +2 -2
  77. package/resources/chats/index.d.ts.map +1 -1
  78. package/resources/chats/index.js.map +1 -1
  79. package/resources/chats/index.mjs.map +1 -1
  80. package/resources/chats/messages.d.mts +21 -25
  81. package/resources/chats/messages.d.mts.map +1 -1
  82. package/resources/chats/messages.d.ts +21 -25
  83. package/resources/chats/messages.d.ts.map +1 -1
  84. package/resources/chats/messages.js +16 -3
  85. package/resources/chats/messages.js.map +1 -1
  86. package/resources/chats/messages.mjs +16 -3
  87. package/resources/chats/messages.mjs.map +1 -1
  88. package/resources/chats/participants.d.mts +18 -0
  89. package/resources/chats/participants.d.mts.map +1 -1
  90. package/resources/chats/participants.d.ts +18 -0
  91. package/resources/chats/participants.d.ts.map +1 -1
  92. package/resources/chats/participants.js +18 -0
  93. package/resources/chats/participants.js.map +1 -1
  94. package/resources/chats/participants.mjs +18 -0
  95. package/resources/chats/participants.mjs.map +1 -1
  96. package/resources/chats/typing.d.mts +18 -0
  97. package/resources/chats/typing.d.mts.map +1 -1
  98. package/resources/chats/typing.d.ts +18 -0
  99. package/resources/chats/typing.d.ts.map +1 -1
  100. package/resources/chats/typing.js +18 -0
  101. package/resources/chats/typing.js.map +1 -1
  102. package/resources/chats/typing.mjs +18 -0
  103. package/resources/chats/typing.mjs.map +1 -1
  104. package/resources/index.d.mts +4 -3
  105. package/resources/index.d.mts.map +1 -1
  106. package/resources/index.d.ts +4 -3
  107. package/resources/index.d.ts.map +1 -1
  108. package/resources/index.js +3 -1
  109. package/resources/index.js.map +1 -1
  110. package/resources/index.mjs +1 -0
  111. package/resources/index.mjs.map +1 -1
  112. package/resources/messages.d.mts +37 -72
  113. package/resources/messages.d.mts.map +1 -1
  114. package/resources/messages.d.ts +37 -72
  115. package/resources/messages.d.ts.map +1 -1
  116. package/resources/messages.js +34 -4
  117. package/resources/messages.js.map +1 -1
  118. package/resources/messages.mjs +34 -4
  119. package/resources/messages.mjs.map +1 -1
  120. package/resources/phone-numbers.d.mts +9 -0
  121. package/resources/phone-numbers.d.mts.map +1 -1
  122. package/resources/phone-numbers.d.ts +9 -0
  123. package/resources/phone-numbers.d.ts.map +1 -1
  124. package/resources/phone-numbers.js +9 -0
  125. package/resources/phone-numbers.js.map +1 -1
  126. package/resources/phone-numbers.mjs +9 -0
  127. package/resources/phone-numbers.mjs.map +1 -1
  128. package/resources/phonenumbers.d.mts +9 -0
  129. package/resources/phonenumbers.d.mts.map +1 -1
  130. package/resources/phonenumbers.d.ts +9 -0
  131. package/resources/phonenumbers.d.ts.map +1 -1
  132. package/resources/phonenumbers.js +9 -0
  133. package/resources/phonenumbers.js.map +1 -1
  134. package/resources/phonenumbers.mjs +9 -0
  135. package/resources/phonenumbers.mjs.map +1 -1
  136. package/resources/shared.d.mts +51 -0
  137. package/resources/shared.d.mts.map +1 -1
  138. package/resources/shared.d.ts +51 -0
  139. package/resources/shared.d.ts.map +1 -1
  140. package/resources/webhook-events.d.mts +90 -1
  141. package/resources/webhook-events.d.mts.map +1 -1
  142. package/resources/webhook-events.d.ts +90 -1
  143. package/resources/webhook-events.d.ts.map +1 -1
  144. package/resources/webhook-events.js +89 -0
  145. package/resources/webhook-events.js.map +1 -1
  146. package/resources/webhook-events.mjs +89 -0
  147. package/resources/webhook-events.mjs.map +1 -1
  148. package/resources/webhook-subscriptions.d.mts +89 -0
  149. package/resources/webhook-subscriptions.d.mts.map +1 -1
  150. package/resources/webhook-subscriptions.d.ts +89 -0
  151. package/resources/webhook-subscriptions.d.ts.map +1 -1
  152. package/resources/webhook-subscriptions.js +89 -0
  153. package/resources/webhook-subscriptions.js.map +1 -1
  154. package/resources/webhook-subscriptions.mjs +89 -0
  155. package/resources/webhook-subscriptions.mjs.map +1 -1
  156. package/resources/webhooks.d.mts +2506 -0
  157. package/resources/webhooks.d.mts.map +1 -0
  158. package/resources/webhooks.d.ts +2506 -0
  159. package/resources/webhooks.d.ts.map +1 -0
  160. package/resources/webhooks.js +12 -0
  161. package/resources/webhooks.js.map +1 -0
  162. package/resources/webhooks.mjs +8 -0
  163. package/resources/webhooks.mjs.map +1 -0
  164. package/src/client.ts +443 -37
  165. package/src/core/pagination.ts +212 -0
  166. package/src/index.ts +1 -0
  167. package/src/internal/utils/query.ts +23 -0
  168. package/src/internal/utils.ts +1 -0
  169. package/src/pagination.ts +2 -0
  170. package/src/resources/attachments.ts +64 -0
  171. package/src/resources/capability.ts +17 -14
  172. package/src/resources/chats/chats.ts +86 -115
  173. package/src/resources/chats/index.ts +4 -3
  174. package/src/resources/chats/messages.ts +30 -30
  175. package/src/resources/chats/participants.ts +18 -0
  176. package/src/resources/chats/typing.ts +18 -0
  177. package/src/resources/index.ts +55 -10
  178. package/src/resources/messages.ts +49 -90
  179. package/src/resources/phone-numbers.ts +9 -0
  180. package/src/resources/phonenumbers.ts +9 -0
  181. package/src/resources/shared.ts +62 -0
  182. package/src/resources/webhook-events.ts +90 -0
  183. package/src/resources/webhook-subscriptions.ts +89 -0
  184. package/src/resources/webhooks.ts +3089 -0
  185. package/src/version.ts +1 -1
  186. package/version.d.mts +1 -1
  187. package/version.d.ts +1 -1
  188. package/version.js +1 -1
  189. package/version.mjs +1 -1
package/src/client.ts CHANGED
@@ -11,8 +11,17 @@ import type { APIResponseProps } from './internal/parse';
11
11
  import { getPlatformHeaders } from './internal/detect-platform';
12
12
  import * as Shims from './internal/shims';
13
13
  import * as Opts from './internal/request-options';
14
+ import { stringifyQuery } from './internal/utils/query';
14
15
  import { VERSION } from './version';
15
16
  import * as Errors from './core/error';
17
+ import * as Pagination from './core/pagination';
18
+ import {
19
+ AbstractPage,
20
+ type ListChatsPaginationParams,
21
+ ListChatsPaginationResponse,
22
+ type ListMessagesPaginationParams,
23
+ ListMessagesPaginationResponse,
24
+ } from './core/pagination';
16
25
  import * as Uploads from './core/uploads';
17
26
  import * as API from './resources/index';
18
27
  import { APIPromise } from './core/api-promise';
@@ -25,26 +34,25 @@ import {
25
34
  } from './resources/attachments';
26
35
  import {
27
36
  Capability,
28
- CapabilityCheckImessageParams,
29
- CapabilityCheckImessageResponse,
30
- CapabilityCheckRcsParams,
31
- CapabilityCheckRcsResponse,
37
+ CapabilityCheckRCSParams,
38
+ CapabilityCheckRCSResponse,
39
+ CapabilityCheckiMessageParams,
40
+ CapabilityCheckiMessageResponse,
32
41
  } from './resources/capability';
33
42
  import {
34
43
  ChatHandle,
35
- MediaPart,
36
44
  Message,
37
45
  MessageAddReactionParams,
38
46
  MessageAddReactionResponse,
39
47
  MessageDeleteParams,
40
48
  MessageEffect,
41
- MessageRetrieveThreadParams,
42
- MessageRetrieveThreadResponse,
49
+ MessageListMessagesThreadParams,
50
+ MessageUpdateParams,
43
51
  Messages,
52
+ MessagesListMessagesPagination,
44
53
  Reaction,
45
54
  ReactionType,
46
55
  ReplyTo,
47
- TextPart,
48
56
  } from './resources/messages';
49
57
  import { PhoneNumberListResponse, PhoneNumbers } from './resources/phone-numbers';
50
58
  import { PhonenumberListResponse, Phonenumbers } from './resources/phonenumbers';
@@ -57,17 +65,63 @@ import {
57
65
  WebhookSubscriptionUpdateParams,
58
66
  WebhookSubscriptions,
59
67
  } from './resources/webhook-subscriptions';
68
+ import {
69
+ ChatCreatedV2025WebhookEvent,
70
+ ChatCreatedV2026WebhookEvent,
71
+ ChatGroupIconUpdateFailedV2025WebhookEvent,
72
+ ChatGroupIconUpdateFailedV2026WebhookEvent,
73
+ ChatGroupIconUpdatedV2025WebhookEvent,
74
+ ChatGroupIconUpdatedV2026WebhookEvent,
75
+ ChatGroupNameUpdateFailedV2025WebhookEvent,
76
+ ChatGroupNameUpdateFailedV2026WebhookEvent,
77
+ ChatGroupNameUpdatedV2025WebhookEvent,
78
+ ChatGroupNameUpdatedV2026WebhookEvent,
79
+ ChatTypingIndicatorStartedV2025WebhookEvent,
80
+ ChatTypingIndicatorStartedV2026WebhookEvent,
81
+ ChatTypingIndicatorStoppedV2025WebhookEvent,
82
+ ChatTypingIndicatorStoppedV2026WebhookEvent,
83
+ EventsWebhookEvent,
84
+ MessageDeliveredV2025WebhookEvent,
85
+ MessageDeliveredV2026WebhookEvent,
86
+ MessageEventV2,
87
+ MessageFailedV2025WebhookEvent,
88
+ MessageFailedV2026WebhookEvent,
89
+ MessagePayload,
90
+ MessageReadV2025WebhookEvent,
91
+ MessageReadV2026WebhookEvent,
92
+ MessageReceivedV2025WebhookEvent,
93
+ MessageReceivedV2026WebhookEvent,
94
+ MessageSentV2025WebhookEvent,
95
+ MessageSentV2026WebhookEvent,
96
+ ParticipantAddedV2025WebhookEvent,
97
+ ParticipantAddedV2026WebhookEvent,
98
+ ParticipantRemovedV2025WebhookEvent,
99
+ ParticipantRemovedV2026WebhookEvent,
100
+ PhoneNumberStatusUpdatedV2025WebhookEvent,
101
+ PhoneNumberStatusUpdatedV2026WebhookEvent,
102
+ ReactionAddedV2025WebhookEvent,
103
+ ReactionAddedV2026WebhookEvent,
104
+ ReactionEventBase,
105
+ ReactionRemovedV2025WebhookEvent,
106
+ ReactionRemovedV2026WebhookEvent,
107
+ SchemasMediaPartResponse,
108
+ SchemasMessageEffect,
109
+ SchemasTextPartResponse,
110
+ Webhooks,
111
+ } from './resources/webhooks';
60
112
  import {
61
113
  Chat,
62
114
  ChatCreateParams,
63
115
  ChatCreateResponse,
64
- ChatListParams,
65
- ChatListResponse,
116
+ ChatListChatsParams,
66
117
  ChatSendVoicememoParams,
67
118
  ChatSendVoicememoResponse,
68
119
  ChatUpdateParams,
69
120
  Chats,
121
+ ChatsListChatsPagination,
122
+ MediaPart,
70
123
  MessageContent,
124
+ TextPart,
71
125
  } from './resources/chats/chats';
72
126
  import { type Fetch } from './internal/builtin-types';
73
127
  import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
@@ -268,21 +322,8 @@ export class LinqAPIV3 {
268
322
  /**
269
323
  * Basic re-implementation of `qs.stringify` for primitive types.
270
324
  */
271
- protected stringifyQuery(query: Record<string, unknown>): string {
272
- return Object.entries(query)
273
- .filter(([_, value]) => typeof value !== 'undefined')
274
- .map(([key, value]) => {
275
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
276
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
277
- }
278
- if (value === null) {
279
- return `${encodeURIComponent(key)}=`;
280
- }
281
- throw new Errors.LinqAPIV3Error(
282
- `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
283
- );
284
- })
285
- .join('&');
325
+ protected stringifyQuery(query: object | Record<string, unknown>): string {
326
+ return stringifyQuery(query);
286
327
  }
287
328
 
288
329
  private getUserAgent(): string {
@@ -319,7 +360,7 @@ export class LinqAPIV3 {
319
360
  }
320
361
 
321
362
  if (typeof query === 'object' && query && !Array.isArray(query)) {
322
- url.search = this.stringifyQuery(query as Record<string, unknown>);
363
+ url.search = this.stringifyQuery(query);
323
364
  }
324
365
 
325
366
  return url.toString();
@@ -537,6 +578,30 @@ export class LinqAPIV3 {
537
578
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
538
579
  }
539
580
 
581
+ getAPIList<Item, PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>>(
582
+ path: string,
583
+ Page: new (...args: any[]) => PageClass,
584
+ opts?: PromiseOrValue<RequestOptions>,
585
+ ): Pagination.PagePromise<PageClass, Item> {
586
+ return this.requestAPIList(
587
+ Page,
588
+ opts && 'then' in opts ?
589
+ opts.then((opts) => ({ method: 'get', path, ...opts }))
590
+ : { method: 'get', path, ...opts },
591
+ );
592
+ }
593
+
594
+ requestAPIList<
595
+ Item = unknown,
596
+ PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>,
597
+ >(
598
+ Page: new (...args: ConstructorParameters<typeof Pagination.AbstractPage>) => PageClass,
599
+ options: PromiseOrValue<FinalRequestOptions>,
600
+ ): Pagination.PagePromise<PageClass, Item> {
601
+ const request = this.makeRequest(options, null, undefined);
602
+ return new Pagination.PagePromise<PageClass, Item>(this as any as LinqAPIV3, request, Page);
603
+ }
604
+
540
605
  async fetchWithTimeout(
541
606
  url: RequestInfo,
542
607
  init: RequestInit | undefined,
@@ -758,7 +823,7 @@ export class LinqAPIV3 {
758
823
  ) {
759
824
  return {
760
825
  bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
761
- body: this.stringifyQuery(body as Record<string, unknown>),
826
+ body: this.stringifyQuery(body),
762
827
  };
763
828
  } else {
764
829
  return this.#encoder({ body, headers });
@@ -785,13 +850,293 @@ export class LinqAPIV3 {
785
850
  static toFile = Uploads.toFile;
786
851
 
787
852
  chats: API.Chats = new API.Chats(this);
853
+ /**
854
+ * Messages are individual text or multimedia communications within a chat thread.
855
+ *
856
+ * Messages can include text, attachments, special effects (like confetti or fireworks),
857
+ * and reactions. All messages are associated with a specific chat and sent from a
858
+ * phone number you own.
859
+ *
860
+ * Messages support delivery status tracking, read receipts, and editing capabilities.
861
+ *
862
+ */
788
863
  messages: API.Messages = new API.Messages(this);
864
+ /**
865
+ * Send files (images, videos, documents, audio) with messages by providing a URL in a media part.
866
+ * Pre-uploading via `POST /v3/attachments` is **optional** and only needed for specific optimization scenarios.
867
+ *
868
+ * ## Sending Media via URL (up to 10MB)
869
+ *
870
+ * Provide a publicly accessible HTTPS URL with a [supported media type](#supported-file-types) in the `url` field of a media part.
871
+ *
872
+ * ```json
873
+ * {
874
+ * "parts": [
875
+ * { "type": "media", "url": "https://your-cdn.com/images/photo.jpg" }
876
+ * ]
877
+ * }
878
+ * ```
879
+ *
880
+ * This works with any URL you already host — no pre-upload step required. **Maximum file size: 10MB.**
881
+ *
882
+ * ## Pre-Upload (required for files over 10MB)
883
+ *
884
+ * Use `POST /v3/attachments` when you want to:
885
+ * - **Send files larger than 10MB** (up to 100MB) — URL-based downloads are limited to 10MB
886
+ * - **Send the same file to many recipients** — upload once, reuse the `attachment_id` without re-downloading each time
887
+ * - **Reduce message send latency** — the file is already stored, so sending is faster
888
+ *
889
+ * **How it works:**
890
+ * 1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a permanent `attachment_id`
891
+ * 2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
892
+ * 3. Reference the `attachment_id` in your media part when sending messages (no expiration)
893
+ *
894
+ * **Key difference:** When you provide an external `url`, we download and process the file on every send.
895
+ * When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
896
+ *
897
+ * ## Domain Allowlisting
898
+ *
899
+ * Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
900
+ * - `url` fields in media and voice memo message parts
901
+ * - `download_url` fields in attachment and upload response objects
902
+ *
903
+ * If your application enforces domain allowlists (e.g., for SSRF protection), add:
904
+ *
905
+ * ```
906
+ * cdn.linqapp.com
907
+ * ```
908
+ *
909
+ * ## Supported File Types
910
+ *
911
+ * - **Images:** JPEG, PNG, GIF, HEIC, HEIF, TIFF, BMP
912
+ * - **Videos:** MP4, MOV, M4V
913
+ * - **Audio:** M4A, AAC, MP3, WAV, AIFF, CAF, AMR
914
+ * - **Documents:** PDF, TXT, RTF, CSV, Office formats, ZIP
915
+ * - **Contact & Calendar:** VCF, ICS
916
+ *
917
+ * ## Audio: Attachment vs Voice Memo
918
+ *
919
+ * Audio files sent as media parts appear as **downloadable file attachments** in iMessage.
920
+ * To send audio as an **iMessage voice memo bubble** (with native inline playback UI),
921
+ * use the dedicated `POST /v3/chats/{chatId}/voicememo` endpoint instead.
922
+ *
923
+ * ## File Size Limits
924
+ *
925
+ * - **URL-based (`url` field):** 10MB maximum
926
+ * - **Pre-upload (`attachment_id`):** 100MB maximum
927
+ *
928
+ */
789
929
  attachments: API.Attachments = new API.Attachments(this);
930
+ /**
931
+ * Phone Numbers represent the phone numbers assigned to your partner account.
932
+ *
933
+ * Use the list phone numbers endpoint to discover which phone numbers are available
934
+ * for sending messages.
935
+ *
936
+ * When creating chats, listing chats, or sending a voice memo, use one of your assigned phone numbers
937
+ * in the `from` field.
938
+ *
939
+ */
790
940
  phonenumbers: API.Phonenumbers = new API.Phonenumbers(this);
941
+ /**
942
+ * Phone Numbers represent the phone numbers assigned to your partner account.
943
+ *
944
+ * Use the list phone numbers endpoint to discover which phone numbers are available
945
+ * for sending messages.
946
+ *
947
+ * When creating chats, listing chats, or sending a voice memo, use one of your assigned phone numbers
948
+ * in the `from` field.
949
+ *
950
+ */
791
951
  phoneNumbers: API.PhoneNumbers = new API.PhoneNumbers(this);
952
+ /**
953
+ * Webhook Subscriptions allow you to receive real-time notifications when events
954
+ * occur on your account.
955
+ *
956
+ * Configure webhook endpoints to receive events such as messages sent/received,
957
+ * delivery status changes, reactions, typing indicators, and more.
958
+ *
959
+ * Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
960
+ * ~2 hours with exponential backoff. Each event includes a unique ID for
961
+ * deduplication.
962
+ *
963
+ * ## Webhook Headers
964
+ *
965
+ * Each webhook request includes the following headers:
966
+ *
967
+ * | Header | Description |
968
+ * |--------|-------------|
969
+ * | `X-Webhook-Event` | The event type (e.g., `message.sent`, `message.received`) |
970
+ * | `X-Webhook-Subscription-ID` | Your webhook subscription ID |
971
+ * | `X-Webhook-Timestamp` | Unix timestamp (seconds) when the webhook was sent |
972
+ * | `X-Webhook-Signature` | HMAC-SHA256 signature for verification |
973
+ *
974
+ * ## Verifying Webhook Signatures
975
+ *
976
+ * All webhooks are signed using HMAC-SHA256. You should always verify the signature
977
+ * to ensure the webhook originated from Linq and hasn't been tampered with.
978
+ *
979
+ * **Signature Construction:**
980
+ *
981
+ * The signature is computed over a concatenation of the timestamp and payload:
982
+ *
983
+ * ```
984
+ * {timestamp}.{payload}
985
+ * ```
986
+ *
987
+ * Where:
988
+ * - `timestamp` is the value from the `X-Webhook-Timestamp` header
989
+ * - `payload` is the raw JSON request body (exact bytes, not re-serialized)
990
+ *
991
+ * **Verification Steps:**
992
+ *
993
+ * 1. Extract the `X-Webhook-Timestamp` and `X-Webhook-Signature` headers
994
+ * 2. Get the raw request body bytes (do not parse and re-serialize)
995
+ * 3. Concatenate: `"{timestamp}.{payload}"`
996
+ * 4. Compute HMAC-SHA256 using your signing secret as the key
997
+ * 5. Hex-encode the result and compare with `X-Webhook-Signature`
998
+ * 6. Use constant-time comparison to prevent timing attacks
999
+ *
1000
+ * **Example (Python):**
1001
+ *
1002
+ * ```python
1003
+ * import hmac
1004
+ * import hashlib
1005
+ *
1006
+ * def verify_webhook(signing_secret, payload, timestamp, signature):
1007
+ * message = f"{timestamp}.{payload.decode('utf-8')}"
1008
+ * expected = hmac.new(
1009
+ * signing_secret.encode('utf-8'),
1010
+ * message.encode('utf-8'),
1011
+ * hashlib.sha256
1012
+ * ).hexdigest()
1013
+ * return hmac.compare_digest(expected, signature)
1014
+ * ```
1015
+ *
1016
+ * **Example (Node.js):**
1017
+ *
1018
+ * ```javascript
1019
+ * const crypto = require('crypto');
1020
+ *
1021
+ * function verifyWebhook(signingSecret, payload, timestamp, signature) {
1022
+ * const message = `${timestamp}.${payload}`;
1023
+ * const expected = crypto
1024
+ * .createHmac('sha256', signingSecret)
1025
+ * .update(message)
1026
+ * .digest('hex');
1027
+ * return crypto.timingSafeEqual(
1028
+ * Buffer.from(expected),
1029
+ * Buffer.from(signature)
1030
+ * );
1031
+ * }
1032
+ * ```
1033
+ *
1034
+ * **Security Best Practices:**
1035
+ *
1036
+ * - Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
1037
+ * - Always use constant-time comparison for signature verification
1038
+ * - Store your signing secret securely (e.g., environment variable, secrets manager)
1039
+ * - Return a 2xx status code quickly, then process the webhook asynchronously
1040
+ *
1041
+ */
792
1042
  webhookEvents: API.WebhookEvents = new API.WebhookEvents(this);
1043
+ /**
1044
+ * Webhook Subscriptions allow you to receive real-time notifications when events
1045
+ * occur on your account.
1046
+ *
1047
+ * Configure webhook endpoints to receive events such as messages sent/received,
1048
+ * delivery status changes, reactions, typing indicators, and more.
1049
+ *
1050
+ * Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
1051
+ * ~2 hours with exponential backoff. Each event includes a unique ID for
1052
+ * deduplication.
1053
+ *
1054
+ * ## Webhook Headers
1055
+ *
1056
+ * Each webhook request includes the following headers:
1057
+ *
1058
+ * | Header | Description |
1059
+ * |--------|-------------|
1060
+ * | `X-Webhook-Event` | The event type (e.g., `message.sent`, `message.received`) |
1061
+ * | `X-Webhook-Subscription-ID` | Your webhook subscription ID |
1062
+ * | `X-Webhook-Timestamp` | Unix timestamp (seconds) when the webhook was sent |
1063
+ * | `X-Webhook-Signature` | HMAC-SHA256 signature for verification |
1064
+ *
1065
+ * ## Verifying Webhook Signatures
1066
+ *
1067
+ * All webhooks are signed using HMAC-SHA256. You should always verify the signature
1068
+ * to ensure the webhook originated from Linq and hasn't been tampered with.
1069
+ *
1070
+ * **Signature Construction:**
1071
+ *
1072
+ * The signature is computed over a concatenation of the timestamp and payload:
1073
+ *
1074
+ * ```
1075
+ * {timestamp}.{payload}
1076
+ * ```
1077
+ *
1078
+ * Where:
1079
+ * - `timestamp` is the value from the `X-Webhook-Timestamp` header
1080
+ * - `payload` is the raw JSON request body (exact bytes, not re-serialized)
1081
+ *
1082
+ * **Verification Steps:**
1083
+ *
1084
+ * 1. Extract the `X-Webhook-Timestamp` and `X-Webhook-Signature` headers
1085
+ * 2. Get the raw request body bytes (do not parse and re-serialize)
1086
+ * 3. Concatenate: `"{timestamp}.{payload}"`
1087
+ * 4. Compute HMAC-SHA256 using your signing secret as the key
1088
+ * 5. Hex-encode the result and compare with `X-Webhook-Signature`
1089
+ * 6. Use constant-time comparison to prevent timing attacks
1090
+ *
1091
+ * **Example (Python):**
1092
+ *
1093
+ * ```python
1094
+ * import hmac
1095
+ * import hashlib
1096
+ *
1097
+ * def verify_webhook(signing_secret, payload, timestamp, signature):
1098
+ * message = f"{timestamp}.{payload.decode('utf-8')}"
1099
+ * expected = hmac.new(
1100
+ * signing_secret.encode('utf-8'),
1101
+ * message.encode('utf-8'),
1102
+ * hashlib.sha256
1103
+ * ).hexdigest()
1104
+ * return hmac.compare_digest(expected, signature)
1105
+ * ```
1106
+ *
1107
+ * **Example (Node.js):**
1108
+ *
1109
+ * ```javascript
1110
+ * const crypto = require('crypto');
1111
+ *
1112
+ * function verifyWebhook(signingSecret, payload, timestamp, signature) {
1113
+ * const message = `${timestamp}.${payload}`;
1114
+ * const expected = crypto
1115
+ * .createHmac('sha256', signingSecret)
1116
+ * .update(message)
1117
+ * .digest('hex');
1118
+ * return crypto.timingSafeEqual(
1119
+ * Buffer.from(expected),
1120
+ * Buffer.from(signature)
1121
+ * );
1122
+ * }
1123
+ * ```
1124
+ *
1125
+ * **Security Best Practices:**
1126
+ *
1127
+ * - Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
1128
+ * - Always use constant-time comparison for signature verification
1129
+ * - Store your signing secret securely (e.g., environment variable, secrets manager)
1130
+ * - Return a 2xx status code quickly, then process the webhook asynchronously
1131
+ *
1132
+ */
793
1133
  webhookSubscriptions: API.WebhookSubscriptions = new API.WebhookSubscriptions(this);
1134
+ /**
1135
+ * Check whether a recipient address supports iMessage or RCS before sending a message.
1136
+ *
1137
+ */
794
1138
  capability: API.Capability = new API.Capability(this);
1139
+ webhooks: API.Webhooks = new API.Webhooks(this);
795
1140
  }
796
1141
 
797
1142
  LinqAPIV3.Chats = Chats;
@@ -802,38 +1147,52 @@ LinqAPIV3.PhoneNumbers = PhoneNumbers;
802
1147
  LinqAPIV3.WebhookEvents = WebhookEvents;
803
1148
  LinqAPIV3.WebhookSubscriptions = WebhookSubscriptions;
804
1149
  LinqAPIV3.Capability = Capability;
1150
+ LinqAPIV3.Webhooks = Webhooks;
805
1151
 
806
1152
  export declare namespace LinqAPIV3 {
807
1153
  export type RequestOptions = Opts.RequestOptions;
808
1154
 
1155
+ export import ListChatsPagination = Pagination.ListChatsPagination;
1156
+ export {
1157
+ type ListChatsPaginationParams as ListChatsPaginationParams,
1158
+ type ListChatsPaginationResponse as ListChatsPaginationResponse,
1159
+ };
1160
+
1161
+ export import ListMessagesPagination = Pagination.ListMessagesPagination;
1162
+ export {
1163
+ type ListMessagesPaginationParams as ListMessagesPaginationParams,
1164
+ type ListMessagesPaginationResponse as ListMessagesPaginationResponse,
1165
+ };
1166
+
809
1167
  export {
810
1168
  Chats as Chats,
811
1169
  type Chat as Chat,
1170
+ type MediaPart as MediaPart,
812
1171
  type MessageContent as MessageContent,
1172
+ type TextPart as TextPart,
813
1173
  type ChatCreateResponse as ChatCreateResponse,
814
- type ChatListResponse as ChatListResponse,
815
1174
  type ChatSendVoicememoResponse as ChatSendVoicememoResponse,
1175
+ type ChatsListChatsPagination as ChatsListChatsPagination,
816
1176
  type ChatCreateParams as ChatCreateParams,
817
1177
  type ChatUpdateParams as ChatUpdateParams,
818
- type ChatListParams as ChatListParams,
1178
+ type ChatListChatsParams as ChatListChatsParams,
819
1179
  type ChatSendVoicememoParams as ChatSendVoicememoParams,
820
1180
  };
821
1181
 
822
1182
  export {
823
1183
  Messages as Messages,
824
1184
  type ChatHandle as ChatHandle,
825
- type MediaPart as MediaPart,
826
1185
  type Message as Message,
827
1186
  type MessageEffect as MessageEffect,
828
1187
  type Reaction as Reaction,
829
1188
  type ReactionType as ReactionType,
830
1189
  type ReplyTo as ReplyTo,
831
- type TextPart as TextPart,
832
1190
  type MessageAddReactionResponse as MessageAddReactionResponse,
833
- type MessageRetrieveThreadResponse as MessageRetrieveThreadResponse,
1191
+ type MessagesListMessagesPagination as MessagesListMessagesPagination,
1192
+ type MessageUpdateParams as MessageUpdateParams,
834
1193
  type MessageDeleteParams as MessageDeleteParams,
835
1194
  type MessageAddReactionParams as MessageAddReactionParams,
836
- type MessageRetrieveThreadParams as MessageRetrieveThreadParams,
1195
+ type MessageListMessagesThreadParams as MessageListMessagesThreadParams,
837
1196
  };
838
1197
 
839
1198
  export {
@@ -865,11 +1224,58 @@ export declare namespace LinqAPIV3 {
865
1224
 
866
1225
  export {
867
1226
  Capability as Capability,
868
- type CapabilityCheckImessageResponse as CapabilityCheckImessageResponse,
869
- type CapabilityCheckRcsResponse as CapabilityCheckRcsResponse,
870
- type CapabilityCheckImessageParams as CapabilityCheckImessageParams,
871
- type CapabilityCheckRcsParams as CapabilityCheckRcsParams,
1227
+ type CapabilityCheckiMessageResponse as CapabilityCheckiMessageResponse,
1228
+ type CapabilityCheckRCSResponse as CapabilityCheckRCSResponse,
1229
+ type CapabilityCheckiMessageParams as CapabilityCheckiMessageParams,
1230
+ type CapabilityCheckRCSParams as CapabilityCheckRCSParams,
1231
+ };
1232
+
1233
+ export {
1234
+ Webhooks as Webhooks,
1235
+ type MessageEventV2 as MessageEventV2,
1236
+ type MessagePayload as MessagePayload,
1237
+ type ReactionEventBase as ReactionEventBase,
1238
+ type SchemasMediaPartResponse as SchemasMediaPartResponse,
1239
+ type SchemasMessageEffect as SchemasMessageEffect,
1240
+ type SchemasTextPartResponse as SchemasTextPartResponse,
1241
+ type MessageSentV2026WebhookEvent as MessageSentV2026WebhookEvent,
1242
+ type MessageReceivedV2026WebhookEvent as MessageReceivedV2026WebhookEvent,
1243
+ type MessageReadV2026WebhookEvent as MessageReadV2026WebhookEvent,
1244
+ type MessageDeliveredV2026WebhookEvent as MessageDeliveredV2026WebhookEvent,
1245
+ type MessageFailedV2026WebhookEvent as MessageFailedV2026WebhookEvent,
1246
+ type ReactionAddedV2026WebhookEvent as ReactionAddedV2026WebhookEvent,
1247
+ type ReactionRemovedV2026WebhookEvent as ReactionRemovedV2026WebhookEvent,
1248
+ type ParticipantAddedV2026WebhookEvent as ParticipantAddedV2026WebhookEvent,
1249
+ type ParticipantRemovedV2026WebhookEvent as ParticipantRemovedV2026WebhookEvent,
1250
+ type ChatGroupNameUpdatedV2026WebhookEvent as ChatGroupNameUpdatedV2026WebhookEvent,
1251
+ type ChatGroupIconUpdatedV2026WebhookEvent as ChatGroupIconUpdatedV2026WebhookEvent,
1252
+ type ChatGroupNameUpdateFailedV2026WebhookEvent as ChatGroupNameUpdateFailedV2026WebhookEvent,
1253
+ type ChatGroupIconUpdateFailedV2026WebhookEvent as ChatGroupIconUpdateFailedV2026WebhookEvent,
1254
+ type ChatCreatedV2026WebhookEvent as ChatCreatedV2026WebhookEvent,
1255
+ type ChatTypingIndicatorStartedV2026WebhookEvent as ChatTypingIndicatorStartedV2026WebhookEvent,
1256
+ type ChatTypingIndicatorStoppedV2026WebhookEvent as ChatTypingIndicatorStoppedV2026WebhookEvent,
1257
+ type PhoneNumberStatusUpdatedV2026WebhookEvent as PhoneNumberStatusUpdatedV2026WebhookEvent,
1258
+ type MessageSentV2025WebhookEvent as MessageSentV2025WebhookEvent,
1259
+ type MessageReceivedV2025WebhookEvent as MessageReceivedV2025WebhookEvent,
1260
+ type MessageReadV2025WebhookEvent as MessageReadV2025WebhookEvent,
1261
+ type MessageDeliveredV2025WebhookEvent as MessageDeliveredV2025WebhookEvent,
1262
+ type MessageFailedV2025WebhookEvent as MessageFailedV2025WebhookEvent,
1263
+ type ReactionAddedV2025WebhookEvent as ReactionAddedV2025WebhookEvent,
1264
+ type ReactionRemovedV2025WebhookEvent as ReactionRemovedV2025WebhookEvent,
1265
+ type ParticipantAddedV2025WebhookEvent as ParticipantAddedV2025WebhookEvent,
1266
+ type ParticipantRemovedV2025WebhookEvent as ParticipantRemovedV2025WebhookEvent,
1267
+ type ChatGroupNameUpdatedV2025WebhookEvent as ChatGroupNameUpdatedV2025WebhookEvent,
1268
+ type ChatGroupIconUpdatedV2025WebhookEvent as ChatGroupIconUpdatedV2025WebhookEvent,
1269
+ type ChatGroupNameUpdateFailedV2025WebhookEvent as ChatGroupNameUpdateFailedV2025WebhookEvent,
1270
+ type ChatGroupIconUpdateFailedV2025WebhookEvent as ChatGroupIconUpdateFailedV2025WebhookEvent,
1271
+ type ChatCreatedV2025WebhookEvent as ChatCreatedV2025WebhookEvent,
1272
+ type ChatTypingIndicatorStartedV2025WebhookEvent as ChatTypingIndicatorStartedV2025WebhookEvent,
1273
+ type ChatTypingIndicatorStoppedV2025WebhookEvent as ChatTypingIndicatorStoppedV2025WebhookEvent,
1274
+ type PhoneNumberStatusUpdatedV2025WebhookEvent as PhoneNumberStatusUpdatedV2025WebhookEvent,
1275
+ type EventsWebhookEvent as EventsWebhookEvent,
872
1276
  };
873
1277
 
1278
+ export type MediaPartResponse = API.MediaPartResponse;
874
1279
  export type ServiceType = API.ServiceType;
1280
+ export type TextPartResponse = API.TextPartResponse;
875
1281
  }