@wassist/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1626 @@
1
+ /**
2
+ * Common building-block types reused across every resource.
3
+ */
4
+ /** A UUID string. */
5
+ type UUID = string;
6
+ /** An ISO-8601 datetime string (`YYYY-MM-DDTHH:mm:ss.sssZ`). */
7
+ type ISODateTime = string;
8
+ /** A WhatsApp E.164-format phone number (e.g. `+447424845871`). */
9
+ type PhoneNumberString = string;
10
+ /**
11
+ * Standard offset/limit pagination parameters accepted by every list endpoint.
12
+ *
13
+ * @see https://docs.wassist.app/api-reference/introduction
14
+ */
15
+ interface PageParams {
16
+ /** Number of results to return per page. */
17
+ limit?: number;
18
+ /** Initial index from which to return results. */
19
+ offset?: number;
20
+ }
21
+ /**
22
+ * Raw paginated response envelope returned by the Wassist API.
23
+ *
24
+ * Most callers will never see this directly — list methods return a
25
+ * higher-level {@link AutoPaginatedList} that wraps it.
26
+ */
27
+ interface PaginatedResponse<T> {
28
+ count: number;
29
+ next: string | null;
30
+ previous: string | null;
31
+ results: T[];
32
+ }
33
+ /**
34
+ * Per-request options accepted by every method on the SDK.
35
+ */
36
+ interface RequestOptions {
37
+ /**
38
+ * If supplied, sent as the `Idempotency-Key` header so retried `POST`s
39
+ * do not double-charge or double-fire side effects.
40
+ *
41
+ * Generate a random UUID per logical operation and reuse it for retries.
42
+ */
43
+ idempotencyKey?: string;
44
+ /**
45
+ * Per-request timeout in milliseconds. Overrides the client default.
46
+ */
47
+ timeout?: number;
48
+ /**
49
+ * Per-request retry override. Overrides the client default.
50
+ */
51
+ maxRetries?: number;
52
+ /**
53
+ * Per-request abort signal. Aborting throws a {@link WassistConnectionError}.
54
+ */
55
+ signal?: AbortSignal;
56
+ /**
57
+ * Extra headers merged into the request.
58
+ */
59
+ headers?: Record<string, string>;
60
+ }
61
+
62
+ /**
63
+ * Low-level HTTP transport used by every resource module.
64
+ *
65
+ * Wraps `fetch` with:
66
+ * - `X-API-Key` authentication
67
+ * - `/api/v1/` path prefix handling
68
+ * - Per-request timeout (cancels via `AbortController`)
69
+ * - Exponential-backoff retries on `429` and `5xx` (honors `Retry-After`)
70
+ * - `Idempotency-Key` opt-in for safe `POST` retries
71
+ * - Typed error mapping via {@link errorFromResponse}
72
+ * - `requestId` extraction from the `X-Request-Id` response header
73
+ */
74
+
75
+ /**
76
+ * The minimal `fetch` signature this SDK depends on. Any spec-compliant
77
+ * implementation will satisfy it — Node 18+, edge runtimes, browsers, Bun.
78
+ */
79
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
80
+ /**
81
+ * Configuration for {@link Wassist}.
82
+ */
83
+ interface WassistClientConfig {
84
+ /**
85
+ * Your Wassist API key. Find it at
86
+ * https://wassist.app/settings → API Keys.
87
+ */
88
+ apiKey: string;
89
+ /**
90
+ * Base URL of the Wassist API.
91
+ *
92
+ * @default 'https://backend.wassist.app'
93
+ */
94
+ baseUrl?: string;
95
+ /**
96
+ * Default request timeout in milliseconds. Individual calls can override
97
+ * via the per-call `timeout` option.
98
+ *
99
+ * @default 60_000
100
+ */
101
+ timeout?: number;
102
+ /**
103
+ * Maximum number of retry attempts on `429` / `5xx` / network errors.
104
+ * The total number of requests is `maxRetries + 1`.
105
+ *
106
+ * @default 2
107
+ */
108
+ maxRetries?: number;
109
+ /**
110
+ * Custom `fetch` implementation. Useful for tests, mocking, or runtimes
111
+ * that don't expose `globalThis.fetch`.
112
+ *
113
+ * @default globalThis.fetch
114
+ */
115
+ fetch?: FetchLike;
116
+ }
117
+ interface RequestArgs {
118
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
119
+ path: string;
120
+ query?: object;
121
+ body?: unknown;
122
+ options?: RequestOptions;
123
+ }
124
+ /**
125
+ * @internal
126
+ */
127
+ declare class HttpClient {
128
+ private readonly apiKey;
129
+ private readonly baseUrl;
130
+ private readonly timeout;
131
+ private readonly maxRetries;
132
+ private readonly fetchImpl;
133
+ constructor(config: WassistClientConfig);
134
+ get<T>(path: string, args?: Omit<RequestArgs, 'method' | 'path' | 'body'>): Promise<T>;
135
+ post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
136
+ put<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
137
+ patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
138
+ delete<T>(path: string, options?: RequestOptions): Promise<T>;
139
+ private request;
140
+ private buildUrl;
141
+ private buildHeaders;
142
+ private doFetch;
143
+ }
144
+
145
+ /**
146
+ * The shape of a single fetched page, returned by {@link AutoPaginatedList.firstPage}.
147
+ */
148
+ interface Page<T> {
149
+ /** The items on this page. */
150
+ data: T[];
151
+ /** Total number of items across all pages. */
152
+ totalCount: number;
153
+ /** Whether there is at least one more page after this one. */
154
+ hasMore: boolean;
155
+ /** Offset to pass to the next call to continue from this page. */
156
+ nextOffset: number;
157
+ }
158
+ /**
159
+ * Lazy auto-paginating wrapper around any Wassist list endpoint.
160
+ *
161
+ * Iteration is lazy — pages are fetched on demand as you consume them, so
162
+ * `for await` over a million-item list never has the whole result set in
163
+ * memory.
164
+ *
165
+ * @example Iterate every item
166
+ * ```ts
167
+ * for await (const conv of wassist.conversations.list({ limit: 100 })) {
168
+ * console.log(conv.id);
169
+ * }
170
+ * ```
171
+ *
172
+ * @example Just the first page
173
+ * ```ts
174
+ * const { data, hasMore } = await wassist.conversations.list().firstPage();
175
+ * ```
176
+ *
177
+ * @example Collect everything into an array (small lists only)
178
+ * ```ts
179
+ * const all = await wassist.agents.list().all();
180
+ * ```
181
+ */
182
+ declare class AutoPaginatedList<T> implements AsyncIterable<T> {
183
+ private readonly fetchPage;
184
+ private readonly params;
185
+ private readonly options;
186
+ /** @internal */
187
+ constructor(fetchPage: (params: PageParams) => Promise<PaginatedResponse<T>>, params?: PageParams, options?: RequestOptions);
188
+ /**
189
+ * Async iterator over every item across every page, fetched lazily.
190
+ */
191
+ [Symbol.asyncIterator](): AsyncIterator<T>;
192
+ /**
193
+ * Fetch the first page only and return it as a {@link Page}.
194
+ */
195
+ firstPage(): Promise<Page<T>>;
196
+ /**
197
+ * Walk every page and collect every item into a single array.
198
+ *
199
+ * Convenient for small lists; for large ones prefer `for await`.
200
+ */
201
+ all(): Promise<T[]>;
202
+ }
203
+
204
+ /**
205
+ * A reference to a file uploaded into Wassist (used for agent documents
206
+ * and profile pictures).
207
+ */
208
+ interface FileInfo {
209
+ name: string;
210
+ path: string;
211
+ size: number;
212
+ url: string;
213
+ }
214
+ /** A reference to an image stored on Wassist. */
215
+ interface ImageInfo extends FileInfo {
216
+ width: number;
217
+ height: number;
218
+ }
219
+ /** Minimal user descriptor returned on agent owner/sharings fields. */
220
+ interface PublicUser {
221
+ phoneNumber: string;
222
+ whatsappName: string | null;
223
+ }
224
+ interface AgentTool {
225
+ id: UUID;
226
+ name: string;
227
+ description: string;
228
+ apiSchema: Record<string, unknown>;
229
+ active: boolean;
230
+ creditCost: number;
231
+ }
232
+ interface AgentDocument {
233
+ id: UUID;
234
+ name: string;
235
+ file: FileInfo;
236
+ status: 'pending' | 'processing' | 'ready' | 'error';
237
+ }
238
+ interface AgentMemoryKey {
239
+ id: UUID;
240
+ key: string;
241
+ type: 'string' | 'number' | 'boolean' | 'json';
242
+ initialValue: string;
243
+ whenToUpdate: string;
244
+ }
245
+ interface AgentWakeUpConfig {
246
+ id: UUID;
247
+ description: string;
248
+ enabled: boolean;
249
+ forceMessage: boolean;
250
+ }
251
+ interface AgentOutboundTrigger {
252
+ id: UUID;
253
+ url: string;
254
+ secret: string;
255
+ enabled: boolean;
256
+ templateId: string;
257
+ templateName: string;
258
+ }
259
+ interface AgentWebsiteTool {
260
+ id: UUID;
261
+ url: string;
262
+ prompt: string;
263
+ active: boolean;
264
+ }
265
+ interface AgentImageGenerateTool {
266
+ id: UUID;
267
+ name: string;
268
+ description: string;
269
+ prompt: string;
270
+ active: boolean;
271
+ creditCost: number;
272
+ }
273
+ interface AgentHandoffTool {
274
+ id: UUID;
275
+ parentAgentId: UUID;
276
+ childAgentId: UUID;
277
+ childAgentName: string;
278
+ description: string;
279
+ active: boolean;
280
+ }
281
+ interface AgentMcpConfig {
282
+ id: UUID;
283
+ connectorId: UUID;
284
+ connectorName: string;
285
+ toolWhitelist: string[];
286
+ }
287
+ interface AgentPaywallConfig {
288
+ id: UUID;
289
+ messageLimit: number | null;
290
+ paywallAction: 'none' | 'purchase_link' | 'subscribe' | 'terminal';
291
+ paywallUrl: string | null;
292
+ ctaButtonText: string;
293
+ terminalStateMessage: string;
294
+ subscriptionPricePerMonth: number | null;
295
+ }
296
+ interface AgentCreditSettings {
297
+ id: UUID;
298
+ initialCredits: number;
299
+ creditGrantPassword: string | null;
300
+ creditGrantAmount: number;
301
+ }
302
+ interface AgentWhatsAppPhoneNumber {
303
+ /** Meta's phone number ID — pass to the WhatsApp Business API. */
304
+ whatsappPhoneNumberId: string;
305
+ /** Meta's WABA ID, or `null` for sandbox numbers. */
306
+ whatsappBusinessAccountId: string | null;
307
+ /** Wassist's internal WABA UUID. */
308
+ wabaId: UUID | null;
309
+ /** Display number (E.164 without leading `+`). */
310
+ phoneNumber: string;
311
+ }
312
+ /**
313
+ * A fully-hydrated Wassist agent, as returned by `GET /agents/{id}/`.
314
+ */
315
+ interface Agent {
316
+ id: UUID;
317
+ name: string;
318
+ description: string;
319
+ systemPrompt: string;
320
+ firstMessage: string;
321
+ profilePicture: ImageInfo | null;
322
+ icebreakers: string[];
323
+ llmModel: string | null;
324
+ tools: AgentTool[];
325
+ documents: AgentDocument[];
326
+ memoryKeys: AgentMemoryKey[];
327
+ wakeUpConfigs: AgentWakeUpConfig[];
328
+ outboundTriggers: AgentOutboundTrigger[];
329
+ websiteTools: AgentWebsiteTool[];
330
+ imageGenerateTools: AgentImageGenerateTool[];
331
+ handoffTools: AgentHandoffTool[];
332
+ mcpConfigs: AgentMcpConfig[];
333
+ paywallConfig: AgentPaywallConfig | null;
334
+ creditSettings: AgentCreditSettings | null;
335
+ owner: PublicUser | null;
336
+ sharings: PublicUser[];
337
+ phoneNumbers: AgentWhatsAppPhoneNumber[];
338
+ totalMessages: number;
339
+ totalSessions: number;
340
+ /** Shareable URL that connects this agent to a new contact via WhatsApp. */
341
+ connectUrl: string;
342
+ ownerActive: boolean;
343
+ createdAt: ISODateTime;
344
+ }
345
+ /** Input for `POST /agents/`. */
346
+ interface CreateAgentInput {
347
+ /** Display name for the agent (max 255 characters). */
348
+ name: string;
349
+ }
350
+ /** Input for `POST /agents/byoa/` (Bring Your Own Agent). */
351
+ interface CreateBYOAAgentInput {
352
+ /** The webhook URL Wassist will forward inbound messages to. */
353
+ webhookUrl: string;
354
+ }
355
+ /**
356
+ * Input for `PATCH /agents/{id}/`.
357
+ *
358
+ * Every field is optional; only the fields you include are updated. Nested
359
+ * sub-resource arrays are fully replaced when supplied (Wassist diffs them
360
+ * server-side by `id`).
361
+ */
362
+ interface UpdateAgentInput {
363
+ name?: string;
364
+ description?: string;
365
+ systemPrompt?: string;
366
+ firstMessage?: string;
367
+ icebreakers?: string[];
368
+ llmModel?: string | null;
369
+ tools?: AgentToolInput[];
370
+ memoryKeys?: AgentMemoryKeyInput[];
371
+ wakeUpConfigs?: AgentWakeUpConfigInput[];
372
+ outboundTriggers?: AgentOutboundTriggerInput[];
373
+ websiteTools?: AgentWebsiteToolInput[];
374
+ imageGenerateTools?: AgentImageGenerateToolInput[];
375
+ handoffTools?: AgentHandoffToolInput[];
376
+ mcpConfigs?: AgentMcpConfigInput[];
377
+ paywallConfig?: AgentPaywallConfigInput | null;
378
+ creditSettings?: AgentCreditSettingsInput | null;
379
+ }
380
+ interface AgentToolInput {
381
+ id?: UUID;
382
+ name: string;
383
+ description: string;
384
+ apiSchema: Record<string, unknown>;
385
+ active?: boolean;
386
+ creditCost?: number;
387
+ }
388
+ interface AgentMemoryKeyInput {
389
+ id?: UUID;
390
+ key: string;
391
+ type: 'string' | 'number' | 'boolean' | 'json';
392
+ initialValue: string;
393
+ whenToUpdate: string;
394
+ }
395
+ interface AgentWakeUpConfigInput {
396
+ id?: UUID;
397
+ description: string;
398
+ enabled?: boolean;
399
+ forceMessage?: boolean;
400
+ }
401
+ interface AgentOutboundTriggerInput {
402
+ id?: UUID;
403
+ enabled?: boolean;
404
+ templateId: string;
405
+ templateName: string;
406
+ }
407
+ interface AgentWebsiteToolInput {
408
+ id?: UUID;
409
+ url: string;
410
+ prompt: string;
411
+ active?: boolean;
412
+ }
413
+ interface AgentImageGenerateToolInput {
414
+ id?: UUID;
415
+ name: string;
416
+ description: string;
417
+ prompt: string;
418
+ active?: boolean;
419
+ creditCost?: number;
420
+ }
421
+ interface AgentHandoffToolInput {
422
+ id?: UUID;
423
+ childAgentId: UUID;
424
+ description: string;
425
+ active?: boolean;
426
+ }
427
+ interface AgentMcpConfigInput {
428
+ id?: UUID;
429
+ connectorId: UUID;
430
+ toolWhitelist?: string[];
431
+ }
432
+ interface AgentPaywallConfigInput {
433
+ messageLimit?: number | null;
434
+ paywallAction?: 'none' | 'purchase_link' | 'subscribe' | 'terminal';
435
+ paywallUrl?: string | null;
436
+ ctaButtonText?: string;
437
+ terminalStateMessage?: string;
438
+ subscriptionPricePerMonth?: number | null;
439
+ }
440
+ interface AgentCreditSettingsInput {
441
+ initialCredits?: number;
442
+ creditGrantPassword?: string | null;
443
+ creditGrantAmount?: number;
444
+ }
445
+
446
+ /**
447
+ * Methods for managing agents — the AI personas you connect to WhatsApp.
448
+ *
449
+ * Documented at https://docs.wassist.app/api-reference/agents/list.
450
+ */
451
+ declare class AgentsResource {
452
+ private readonly http;
453
+ /** @internal */
454
+ constructor(http: HttpClient);
455
+ /**
456
+ * List every agent on your account.
457
+ *
458
+ * Returns a lazily-fetched paginated list. Use `for await` to walk all
459
+ * pages, or `.firstPage()` for just the first.
460
+ *
461
+ * `GET /agents/`
462
+ *
463
+ * @example
464
+ * ```ts
465
+ * for await (const agent of wassist.agents.list()) {
466
+ * console.log(agent.id, agent.name);
467
+ * }
468
+ * ```
469
+ */
470
+ list(params?: PageParams, options?: RequestOptions): AutoPaginatedList<Agent>;
471
+ /**
472
+ * Retrieve a single agent by ID.
473
+ *
474
+ * `GET /agents/{id}/`
475
+ */
476
+ get(id: UUID, options?: RequestOptions): Promise<Agent>;
477
+ /**
478
+ * Create a new agent with the given display name. Configure it further
479
+ * with {@link AgentsResource.update}.
480
+ *
481
+ * `POST /agents/`
482
+ */
483
+ create(input: CreateAgentInput, options?: RequestOptions): Promise<Agent>;
484
+ /**
485
+ * Create a Bring-Your-Own-Agent (BYOA) — Wassist forwards inbound
486
+ * messages to your webhook and posts back replies you author yourself.
487
+ *
488
+ * `POST /agents/byoa/`
489
+ */
490
+ createBYOA(input: CreateBYOAAgentInput, options?: RequestOptions): Promise<Agent>;
491
+ /**
492
+ * Partially update an agent. Only the fields you pass are modified.
493
+ *
494
+ * Nested sub-resource arrays (tools, memory keys, etc.) are diffed
495
+ * server-side by `id`: include an `id` to update an existing entry,
496
+ * omit it to create one.
497
+ *
498
+ * `PATCH /agents/{id}/`
499
+ */
500
+ update(id: UUID, input: UpdateAgentInput, options?: RequestOptions): Promise<Agent>;
501
+ /**
502
+ * Soft-delete an agent. The agent stops responding immediately;
503
+ * conversation history is retained.
504
+ *
505
+ * `DELETE /agents/{id}/`
506
+ */
507
+ delete(id: UUID, options?: RequestOptions): Promise<void>;
508
+ }
509
+
510
+ type MessageRole = 'user' | 'assistant' | 'system';
511
+ type MessageType = 'text' | 'image' | 'cta_button' | 'list_selection' | 'template' | 'unified' | 'quick_reply';
512
+ type MessageStatus = 'sent' | 'delivered' | 'read' | 'failed';
513
+ interface TextMessage {
514
+ id: UUID;
515
+ body: string;
516
+ }
517
+ interface ImageMessage {
518
+ id: UUID;
519
+ image: ImageInfo | null;
520
+ caption: string | null;
521
+ }
522
+ interface CTAButtonMessage {
523
+ id: UUID;
524
+ text: string;
525
+ url: string | null;
526
+ buttonText: string;
527
+ image: ImageInfo | null;
528
+ clicks: {
529
+ id: UUID;
530
+ createdAt: ISODateTime;
531
+ }[];
532
+ }
533
+ interface ListSelectionMessage {
534
+ id: UUID;
535
+ text: string;
536
+ buttonText: string;
537
+ sections: Record<string, unknown>[];
538
+ }
539
+ interface TemplateMessage {
540
+ id: UUID;
541
+ templateName: string;
542
+ variables: Record<string, unknown>;
543
+ components: Record<string, unknown>[];
544
+ }
545
+ type UnifiedMessageButtonType = 'url' | 'quick_reply';
546
+ interface UnifiedMessageButton {
547
+ type: UnifiedMessageButtonType;
548
+ text: string;
549
+ url?: string;
550
+ quickReplyId?: string;
551
+ }
552
+ interface UnifiedMessageMedia {
553
+ url: string;
554
+ mimeType: string;
555
+ }
556
+ interface UnifiedMessage {
557
+ body: string | null;
558
+ footer: string | null;
559
+ buttons: UnifiedMessageButton[];
560
+ media: UnifiedMessageMedia[];
561
+ }
562
+ interface QuickReplyMessage {
563
+ text: string;
564
+ quickReplyId: string;
565
+ }
566
+ /**
567
+ * A single message in a conversation. Exactly one of `text`, `image`,
568
+ * `ctaButton`, `listSelection`, `template`, `unified`, or `quickReply` will
569
+ * be populated based on `type`.
570
+ */
571
+ interface Message {
572
+ id: UUID;
573
+ role: MessageRole;
574
+ type: MessageType;
575
+ status: MessageStatus | null;
576
+ createdAt: ISODateTime;
577
+ replyTo: UUID | null;
578
+ text: TextMessage | null;
579
+ image: ImageMessage | null;
580
+ cta: CTAButtonMessage | null;
581
+ listSelection: ListSelectionMessage | null;
582
+ template: TemplateMessage | null;
583
+ unified: UnifiedMessage | null;
584
+ quickReply: QuickReplyMessage | null;
585
+ }
586
+ /** Template name + variables, used both for `messages.send` and `conversations.create`. */
587
+ interface SendMessageTemplateInput {
588
+ /** Approved WhatsApp template name. */
589
+ name: string;
590
+ /**
591
+ * Variable values, keyed by component. Each list is positional and
592
+ * matches the placeholder order in the approved template.
593
+ */
594
+ variables?: {
595
+ body?: string[];
596
+ header?: string[];
597
+ buttons?: string[];
598
+ };
599
+ }
600
+ interface SendMessageTextInput {
601
+ /** Plain-text body (max 1024 characters). */
602
+ body: string;
603
+ }
604
+ interface SendMessageCtaImageInput {
605
+ url: string;
606
+ }
607
+ interface SendMessageCtaInput {
608
+ /** Message body text (max 1024 characters). */
609
+ body: string;
610
+ /** Button label (max 20 characters). */
611
+ buttonText: string;
612
+ /** URL to open when the button is tapped. */
613
+ url: string;
614
+ image?: SendMessageCtaImageInput;
615
+ }
616
+ interface SendUnifiedMessageButtonInput {
617
+ type: UnifiedMessageButtonType;
618
+ text: string;
619
+ url?: string;
620
+ quickReplyId?: string;
621
+ }
622
+ interface SendUnifiedMessageMediaInput {
623
+ url: string;
624
+ }
625
+ interface SendUnifiedMessageInput {
626
+ text?: string;
627
+ /** Footer text (max 60 characters). */
628
+ footer?: string;
629
+ media?: SendUnifiedMessageMediaInput;
630
+ /** Up to 3 buttons of a single type. */
631
+ buttons?: SendUnifiedMessageButtonInput[];
632
+ }
633
+ /**
634
+ * Discriminated union input for `POST /conversations/{id}/messages/`.
635
+ *
636
+ * Set `type` and populate the corresponding sibling field.
637
+ */
638
+ type SendMessageInput = {
639
+ type: 'text';
640
+ text: SendMessageTextInput;
641
+ } | {
642
+ type: 'template';
643
+ template: SendMessageTemplateInput;
644
+ } | {
645
+ type: 'cta';
646
+ cta: SendMessageCtaInput;
647
+ } | {
648
+ type: 'unified';
649
+ unified: SendUnifiedMessageInput;
650
+ };
651
+ /** Input for `POST /conversations/{id}/prompt/`. */
652
+ interface PromptAgentInput {
653
+ /** Free-form instruction sent to the active agent. */
654
+ prompt: string;
655
+ }
656
+
657
+ /**
658
+ * Active routing modes for a phone number or conversation.
659
+ *
660
+ * "No routing" is represented as `null`, not the string `"none"`.
661
+ */
662
+ type PhoneNumberRoutingMode = 'agent' | 'webhook' | 'sandbox';
663
+ /**
664
+ * A WhatsApp phone number connected to your Wassist account.
665
+ *
666
+ * The `number` field is the resource identifier in the URL — pass it as the
667
+ * `number` argument to every `phoneNumbers.*` method.
668
+ */
669
+ interface PhoneNumber {
670
+ /** Wassist's internal UUID for this number. */
671
+ id: UUID;
672
+ /** The number itself, in E.164 without the leading `+`. Used in URLs. */
673
+ number: string;
674
+ /** Meta's phone number ID — pass to the WhatsApp Business API. */
675
+ whatsappPhoneNumberId: string;
676
+ whatsappBusinessAccount: {
677
+ id: UUID;
678
+ name: string | null;
679
+ waId: string;
680
+ } | null;
681
+ activeAgent: {
682
+ id: UUID;
683
+ name: string;
684
+ icebreakers: string[];
685
+ } | null;
686
+ /**
687
+ * How inbound messages on this number are handled by default.
688
+ *
689
+ * - `'agent'` / `'webhook'` — run the corresponding pipeline.
690
+ * - `'sandbox'` — system-managed; not user-settable.
691
+ * - `null` — no routing. Messages are stored but nothing else happens.
692
+ */
693
+ defaultRouting: PhoneNumberRoutingMode | null;
694
+ /** Webhook used when `defaultRouting === 'webhook'`. */
695
+ defaultWebhook: {
696
+ id: UUID;
697
+ name: string;
698
+ url: string;
699
+ } | null;
700
+ /** `true` for shared sandbox numbers (no WhatsApp Business Account). */
701
+ isSandbox: boolean;
702
+ }
703
+ /**
704
+ * The WhatsApp Business Profile for a number, returned by
705
+ * `GET /phone-numbers/{number}/business-profile/`.
706
+ */
707
+ interface PhoneNumberBusinessProfile {
708
+ about?: string;
709
+ description?: string;
710
+ address?: string;
711
+ email?: string;
712
+ profilePictureUrl?: string;
713
+ websites?: string[];
714
+ vertical?: string;
715
+ /** `true` when the profile is still using Wassist's default branding. */
716
+ isStarterBranded: boolean;
717
+ }
718
+ /**
719
+ * Input for `POST /phone-numbers/{number}/subscribe/`.
720
+ *
721
+ * Routes the number to the given webhook (sets `defaultRouting='webhook'`,
722
+ * `defaultWebhook=W`). Any agent previously connected to the number is
723
+ * dropped.
724
+ */
725
+ interface SubscribePhoneNumberInput {
726
+ /** Webhook to route inbound messages to. */
727
+ webhookId: UUID;
728
+ /**
729
+ * When `true` (default), every existing conversation on this number is
730
+ * updated so the new routing takes effect for in-flight chats:
731
+ * `activeAgent` is cleared and any open session is dropped.
732
+ *
733
+ * Phone-number routing changes do **not** fire `subscription.activated`
734
+ * / `.revoked` webhook events — those are reserved for per-conversation
735
+ * subscribe/unsubscribe.
736
+ */
737
+ applyToExisting?: boolean;
738
+ }
739
+ /**
740
+ * Input for `POST /phone-numbers/{number}/connect-agent/`.
741
+ *
742
+ * Sets `defaultRouting='agent'` and assigns the given agent. Any webhook
743
+ * subscribed to the number is dropped. The agent must already be owned by
744
+ * or shared with the caller.
745
+ */
746
+ interface ConnectAgentInput {
747
+ /** Agent to connect to this number. */
748
+ agentId: UUID;
749
+ /** See {@link SubscribePhoneNumberInput.applyToExisting}. */
750
+ applyToExisting?: boolean;
751
+ }
752
+ /**
753
+ * Input for `POST /phone-numbers/{number}/unsubscribe/`.
754
+ *
755
+ * Clears default routing entirely (sets `defaultRouting=null`) and drops
756
+ * both the agent and the default webhook.
757
+ */
758
+ interface UnsubscribePhoneNumberInput {
759
+ applyToExisting?: boolean;
760
+ }
761
+
762
+ interface ConversationContact {
763
+ phoneNumber: string;
764
+ name: string | null;
765
+ }
766
+ interface ConversationLastMessage {
767
+ body: string;
768
+ createdAt: ISODateTime;
769
+ role: MessageRole;
770
+ }
771
+ /**
772
+ * A Wassist conversation between one of your phone numbers and a contact.
773
+ */
774
+ interface Conversation {
775
+ id: UUID;
776
+ contact: ConversationContact;
777
+ activeAgent: {
778
+ id: UUID;
779
+ name: string;
780
+ } | null;
781
+ whatsappNumber: {
782
+ id: UUID;
783
+ number: string;
784
+ /** `true` for shared sandbox numbers (no WhatsApp Business Account). */
785
+ isSandbox: boolean;
786
+ } | null;
787
+ /** Seconds left in the WhatsApp 24-hour reply window. */
788
+ chatWindowRemainingTime: number;
789
+ lastMessage: ConversationLastMessage | null;
790
+ isHumanTakeover: boolean;
791
+ active: boolean;
792
+ /**
793
+ * Resolved routing mode. Inherits from the phone number's default when
794
+ * no per-conversation override is set. `sandbox` for any conversation on
795
+ * a sandbox number. `null` = message is stored but nothing else happens.
796
+ */
797
+ routing: PhoneNumberRoutingMode | null;
798
+ /** Webhook currently subscribed to this conversation, or `null`. */
799
+ webhookId: UUID | null;
800
+ /**
801
+ * `true` when this conversation has a per-conversation routing override
802
+ * rather than inheriting from the phone number's default routing.
803
+ */
804
+ routingOverride: boolean;
805
+ }
806
+ /**
807
+ * Filters and ordering for `GET /conversations/`.
808
+ */
809
+ interface ListConversationsParams {
810
+ /** Filter by agent ID. */
811
+ agent?: UUID;
812
+ /** Filter by your WhatsApp number (substring match on `number`). */
813
+ whatsappNumber?: string;
814
+ /** Filter by contact phone number. */
815
+ contact?: string;
816
+ /** `active` = had inbound message in last 24h, `closed` = otherwise. */
817
+ status?: 'active' | 'closed';
818
+ /** Only return conversations with unread inbound messages. */
819
+ hasUnread?: boolean;
820
+ /** ISO datetime — only return conversations with messages after this time. */
821
+ lastMessageAfter?: ISODateTime;
822
+ /** ISO datetime — only return conversations with messages before this time. */
823
+ lastMessageBefore?: ISODateTime;
824
+ ordering?: 'last_message_time' | '-last_message_time' | 'created_at' | '-created_at' | 'updated_at' | '-updated_at';
825
+ /** Pagination. */
826
+ limit?: number;
827
+ offset?: number;
828
+ }
829
+ /** Optional first-template message included with `POST /conversations/`. */
830
+ interface CreateConversationMessageInput {
831
+ type: 'template';
832
+ template?: SendMessageTemplateInput;
833
+ }
834
+ /** Input for `POST /conversations/`. */
835
+ interface CreateConversationInput {
836
+ /** The recipient's WhatsApp number in E.164 format (e.g. `+447700900100`). */
837
+ toNumber: string;
838
+ /**
839
+ * Your sending number. Optional — when omitted, the agent's primary number
840
+ * is used.
841
+ */
842
+ fromNumber?: string;
843
+ /** Agent to start the conversation with. */
844
+ agentId?: UUID;
845
+ /**
846
+ * Optional first message to send. Required if the WhatsApp 24-hour
847
+ * reply window is closed.
848
+ */
849
+ message?: CreateConversationMessageInput;
850
+ }
851
+ /** Input for `POST /conversations/{id}/subscribe/`. */
852
+ interface SubscribeConversationInput {
853
+ /** Webhook to route this conversation to. */
854
+ webhookId: UUID;
855
+ }
856
+
857
+ /**
858
+ * Messages within a conversation. Reached via `wassist.conversations.messages`.
859
+ *
860
+ * Documented at https://docs.wassist.app/api-reference/conversations/messages/list
861
+ * and https://docs.wassist.app/api-reference/conversations/messages/send.
862
+ */
863
+ declare class MessagesResource {
864
+ private readonly http;
865
+ /** @internal */
866
+ constructor(http: HttpClient);
867
+ /**
868
+ * List messages in a conversation, newest first.
869
+ *
870
+ * `GET /conversations/{id}/messages/`
871
+ */
872
+ list(conversationId: UUID, params?: PageParams, options?: RequestOptions): AutoPaginatedList<Message>;
873
+ /**
874
+ * Send a message in a conversation.
875
+ *
876
+ * The input is a discriminated union — set `type` and populate the
877
+ * matching field (`text`, `template`, `cta`, or `unified`).
878
+ *
879
+ * `POST /conversations/{id}/messages/`
880
+ *
881
+ * @example Plain text
882
+ * ```ts
883
+ * await wassist.conversations.messages.send(conv.id, {
884
+ * type: 'text',
885
+ * text: { body: 'Hello!' },
886
+ * });
887
+ * ```
888
+ *
889
+ * @example Approved template
890
+ * ```ts
891
+ * await wassist.conversations.messages.send(conv.id, {
892
+ * type: 'template',
893
+ * template: { name: 'order_update', variables: { body: ['Alex', '#1234'] } },
894
+ * });
895
+ * ```
896
+ */
897
+ send(conversationId: UUID, input: SendMessageInput, options?: RequestOptions): Promise<Message>;
898
+ }
899
+
900
+ /**
901
+ * Methods for managing conversations — ongoing WhatsApp chats between
902
+ * your numbers and a contact.
903
+ *
904
+ * Nested namespace: `wassist.conversations.messages` (see {@link MessagesResource}).
905
+ */
906
+ declare class ConversationsResource {
907
+ private readonly http;
908
+ /** Send and list messages within a conversation. */
909
+ readonly messages: MessagesResource;
910
+ /** @internal */
911
+ constructor(http: HttpClient);
912
+ /**
913
+ * List conversations on your account with rich filtering.
914
+ *
915
+ * `GET /conversations/`
916
+ *
917
+ * @example
918
+ * ```ts
919
+ * const recent = await wassist.conversations
920
+ * .list({ ordering: '-last_message_time', limit: 20 })
921
+ * .firstPage();
922
+ * ```
923
+ */
924
+ list(params?: ListConversationsParams, options?: RequestOptions): AutoPaginatedList<Conversation>;
925
+ /**
926
+ * Retrieve a single conversation by ID.
927
+ *
928
+ * `GET /conversations/{id}/`
929
+ */
930
+ get(id: UUID, options?: RequestOptions): Promise<Conversation>;
931
+ /**
932
+ * Create a new conversation with a contact.
933
+ *
934
+ * If the WhatsApp 24-hour reply window is closed for this contact, you
935
+ * must include a `template` message to open it.
936
+ *
937
+ * `POST /conversations/`
938
+ */
939
+ create(input: CreateConversationInput, options?: RequestOptions): Promise<Conversation>;
940
+ /**
941
+ * Prompt the agent in this conversation with a custom instruction.
942
+ * Equivalent to "wake the agent up and have it say this" — useful for
943
+ * outbound triggers and follow-ups.
944
+ *
945
+ * `POST /conversations/{id}/prompt/`
946
+ */
947
+ prompt(id: UUID, input: PromptAgentInput, options?: RequestOptions): Promise<void>;
948
+ /**
949
+ * Send a WhatsApp read receipt for the most recent inbound message.
950
+ *
951
+ * `POST /conversations/{id}/read/`
952
+ */
953
+ read(id: UUID, options?: RequestOptions): Promise<Conversation>;
954
+ /**
955
+ * Display the WhatsApp typing indicator on the contact's device.
956
+ *
957
+ * Note: WhatsApp also marks the most recent inbound message as read as
958
+ * a side effect — this is a platform limitation.
959
+ *
960
+ * `POST /conversations/{id}/typing/`
961
+ */
962
+ typing(id: UUID, options?: RequestOptions): Promise<Conversation>;
963
+ /**
964
+ * Route this conversation to a webhook. The agent pipeline is skipped
965
+ * while the override is active.
966
+ *
967
+ * Fires a `subscription.activated` event on the target webhook.
968
+ *
969
+ * `POST /conversations/{id}/subscribe/`
970
+ */
971
+ subscribe(id: UUID, input: SubscribeConversationInput, options?: RequestOptions): Promise<Conversation>;
972
+ /**
973
+ * Clear the per-conversation routing override and fall back to the
974
+ * phone number's default routing.
975
+ *
976
+ * Fires a `subscription.revoked` event on the previously-subscribed
977
+ * webhook (if any).
978
+ *
979
+ * `POST /conversations/{id}/unsubscribe/`
980
+ */
981
+ unsubscribe(id: UUID, options?: RequestOptions): Promise<Conversation>;
982
+ }
983
+
984
+ /**
985
+ * Methods for managing your connected WhatsApp phone numbers and their
986
+ * default routing.
987
+ *
988
+ * The `number` argument throughout is the E.164-format number without a
989
+ * leading `+` (matches the {@link PhoneNumber.number} field).
990
+ */
991
+ declare class PhoneNumbersResource {
992
+ private readonly http;
993
+ /** @internal */
994
+ constructor(http: HttpClient);
995
+ /**
996
+ * List every WhatsApp number on your account.
997
+ *
998
+ * `GET /phone-numbers/`
999
+ */
1000
+ list(params?: PageParams, options?: RequestOptions): AutoPaginatedList<PhoneNumber>;
1001
+ /**
1002
+ * View the WhatsApp Business Profile (about, address, websites, etc.)
1003
+ * attached to this number.
1004
+ *
1005
+ * `GET /phone-numbers/{number}/business-profile/`
1006
+ */
1007
+ getBusinessProfile(number: string, options?: RequestOptions): Promise<PhoneNumberBusinessProfile>;
1008
+ /**
1009
+ * Route inbound messages on this number to a webhook by default. Drops
1010
+ * any agent previously connected to the number.
1011
+ *
1012
+ * Phone-number routing changes do **not** fire
1013
+ * `subscription.activated` / `.revoked` webhook events — those are
1014
+ * reserved for per-conversation
1015
+ * {@link ConversationsResource.subscribe} /
1016
+ * {@link ConversationsResource.unsubscribe}.
1017
+ *
1018
+ * `POST /phone-numbers/{number}/subscribe/`
1019
+ */
1020
+ subscribe(number: string, input: SubscribePhoneNumberInput, options?: RequestOptions): Promise<PhoneNumber>;
1021
+ /**
1022
+ * Assign an agent as the default for this number. Drops any subscribed
1023
+ * webhook.
1024
+ *
1025
+ * The agent must already be owned by or shared with the authenticated
1026
+ * user.
1027
+ *
1028
+ * `POST /phone-numbers/{number}/connect-agent/`
1029
+ */
1030
+ connectAgent(number: string, input: ConnectAgentInput, options?: RequestOptions): Promise<PhoneNumber>;
1031
+ /**
1032
+ * Clear default routing on this number entirely. Drops both the agent
1033
+ * and the webhook.
1034
+ *
1035
+ * `POST /phone-numbers/{number}/unsubscribe/`
1036
+ */
1037
+ unsubscribe(number: string, input?: UnsubscribePhoneNumberInput, options?: RequestOptions): Promise<PhoneNumber>;
1038
+ }
1039
+
1040
+ /**
1041
+ * A WhatsApp Business Account (WABA) linked to your Wassist account.
1042
+ */
1043
+ interface WhatsAppAccount {
1044
+ id: UUID;
1045
+ name: string | null;
1046
+ /** Meta's WABA ID. */
1047
+ waId: string;
1048
+ phoneNumbers: WhatsAppAccountPhoneNumber[];
1049
+ /** URL to the WhatsApp Business Manager templates page for this WABA. */
1050
+ templatesUrl: string;
1051
+ }
1052
+ interface WhatsAppAccountPhoneNumber {
1053
+ id: UUID;
1054
+ number: string;
1055
+ bot: {
1056
+ id: UUID;
1057
+ name: string;
1058
+ } | null;
1059
+ waba: {
1060
+ id: UUID;
1061
+ name: string | null;
1062
+ } | null;
1063
+ }
1064
+ /**
1065
+ * Input for `POST /whatsapp-accounts/{id}/add-number/`.
1066
+ *
1067
+ * Adds a pre-verified phone number (purchased via Meta's embedded signup
1068
+ * flow) to an existing WhatsApp Business Account.
1069
+ */
1070
+ interface AddNumberInput {
1071
+ /** The pre-verified Twilio phone number ID. */
1072
+ id: string;
1073
+ /** Verified business name to display to WhatsApp recipients. */
1074
+ name: string;
1075
+ }
1076
+ /**
1077
+ * A single available phone number returned by `GET /available-numbers/`.
1078
+ */
1079
+ interface AvailableNumber {
1080
+ id: string;
1081
+ phone_number: string;
1082
+ }
1083
+ /**
1084
+ * Response shape of `GET /available-numbers/`.
1085
+ */
1086
+ interface AvailableNumbersResponse {
1087
+ available_numbers: AvailableNumber[];
1088
+ }
1089
+
1090
+ /**
1091
+ * Methods for managing WhatsApp Business Accounts (WABAs) connected to
1092
+ * your Wassist account.
1093
+ */
1094
+ declare class WhatsAppAccountsResource {
1095
+ private readonly http;
1096
+ /** @internal */
1097
+ constructor(http: HttpClient);
1098
+ /**
1099
+ * List every WhatsApp Business Account on your Wassist account.
1100
+ *
1101
+ * `GET /whatsapp-accounts/`
1102
+ */
1103
+ list(params?: PageParams, options?: RequestOptions): AutoPaginatedList<WhatsAppAccount>;
1104
+ /**
1105
+ * Retrieve a single WhatsApp Business Account by ID.
1106
+ *
1107
+ * `GET /whatsapp-accounts/{id}/`
1108
+ */
1109
+ get(id: UUID, options?: RequestOptions): Promise<WhatsAppAccount>;
1110
+ /**
1111
+ * Add a pre-verified phone number (purchased via Meta's embedded
1112
+ * signup flow) to a WhatsApp Business Account.
1113
+ *
1114
+ * `POST /whatsapp-accounts/{id}/add-number/`
1115
+ */
1116
+ addNumber(id: UUID, input: AddNumberInput, options?: RequestOptions): Promise<WhatsAppAccount>;
1117
+ /**
1118
+ * List Twilio phone numbers available for purchase + verification.
1119
+ *
1120
+ * `GET /available-numbers/`
1121
+ */
1122
+ availableNumbers(options?: RequestOptions): Promise<AvailableNumbersResponse>;
1123
+ }
1124
+
1125
+ type WhatsAppLinkSessionStatus = 'PENDING' | 'EXPIRED' | 'SUCCESS' | 'FAILED';
1126
+ /**
1127
+ * A WhatsApp account-linking session — used to embed Meta's signup flow
1128
+ * for a customer into your own product.
1129
+ */
1130
+ interface WhatsAppLinkSession {
1131
+ id: UUID;
1132
+ successUrl: string;
1133
+ returnUrl: string;
1134
+ status: WhatsAppLinkSessionStatus;
1135
+ /** Hosted URL to direct the user to start linking their WhatsApp account. */
1136
+ linkUrl: string;
1137
+ }
1138
+ /** Input for `POST /whatsapp-link-sessions/`. */
1139
+ interface CreateWhatsAppLinkSessionInput {
1140
+ /** Where to redirect the user after a successful link. */
1141
+ successUrl: string;
1142
+ /** Where to redirect the user if they cancel or fail. */
1143
+ returnUrl: string;
1144
+ }
1145
+
1146
+ /**
1147
+ * Methods for managing WhatsApp account-linking sessions — the hosted
1148
+ * flow that lets your customers connect their own WABA to your platform.
1149
+ */
1150
+ declare class WhatsAppLinkSessionsResource {
1151
+ private readonly http;
1152
+ /** @internal */
1153
+ constructor(http: HttpClient);
1154
+ /**
1155
+ * List every link session you've created.
1156
+ *
1157
+ * `GET /whatsapp-link-sessions/`
1158
+ */
1159
+ list(params?: PageParams, options?: RequestOptions): AutoPaginatedList<WhatsAppLinkSession>;
1160
+ /**
1161
+ * Retrieve a single link session by ID.
1162
+ *
1163
+ * `GET /whatsapp-link-sessions/{id}/`
1164
+ */
1165
+ get(id: UUID, options?: RequestOptions): Promise<WhatsAppLinkSession>;
1166
+ /**
1167
+ * Create a new link session. Direct the user to the returned `linkUrl`.
1168
+ *
1169
+ * `POST /whatsapp-link-sessions/`
1170
+ */
1171
+ create(input: CreateWhatsAppLinkSessionInput, options?: RequestOptions): Promise<WhatsAppLinkSession>;
1172
+ /**
1173
+ * Expire a pending link session early. Useful for invalidating stale
1174
+ * URLs you've handed out to customers.
1175
+ *
1176
+ * `POST /whatsapp-link-sessions/{id}/expire/`
1177
+ */
1178
+ expire(id: UUID, options?: RequestOptions): Promise<WhatsAppLinkSession>;
1179
+ }
1180
+
1181
+ type WhatsAppTemplateCategory = 'UTILITY' | 'MARKETING' | 'AUTHENTICATION';
1182
+ type WhatsAppTemplateStatus = 'DRAFT' | 'PENDING' | 'APPROVED' | 'REJECTED' | 'PAUSED';
1183
+ type WhatsAppTemplateQuality = 'GREEN' | 'YELLOW' | 'RED' | 'UNKNOWN';
1184
+ type WhatsAppTemplateParameterFormat = 'POSITIONAL' | 'NAMED';
1185
+ type WhatsAppTemplateButtonType = 'QUICK_REPLY' | 'URL' | 'PHONE_NUMBER' | 'COPY_CODE' | 'FLOW' | 'OTP';
1186
+ interface WhatsAppTemplateButton {
1187
+ type: WhatsAppTemplateButtonType;
1188
+ text: string;
1189
+ url?: string;
1190
+ phone_number?: string;
1191
+ example?: string[];
1192
+ }
1193
+ interface WhatsAppTemplateNamedParam {
1194
+ param_name: string;
1195
+ example: string;
1196
+ }
1197
+ interface WhatsAppTemplateComponentExample {
1198
+ body_text?: string[][];
1199
+ header_text?: string[];
1200
+ body_text_named_params?: WhatsAppTemplateNamedParam[];
1201
+ header_text_named_params?: WhatsAppTemplateNamedParam[];
1202
+ header_handle?: string[];
1203
+ header_url?: string[];
1204
+ }
1205
+ interface WhatsAppTemplateComponent {
1206
+ type: 'HEADER' | 'BODY' | 'FOOTER' | 'BUTTONS';
1207
+ format?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'DOCUMENT';
1208
+ text?: string;
1209
+ example?: WhatsAppTemplateComponentExample;
1210
+ buttons?: WhatsAppTemplateButton[];
1211
+ }
1212
+ /**
1213
+ * The result of publishing a template to a WABA — one entry per account.
1214
+ */
1215
+ interface WhatsAppTemplateAccountLink {
1216
+ accountId: UUID;
1217
+ accountName: string | null;
1218
+ wabaId: string;
1219
+ metaTemplateId: string | null;
1220
+ status: WhatsAppTemplateStatus;
1221
+ qualityScore: WhatsAppTemplateQuality;
1222
+ rejectionReason: string | null;
1223
+ }
1224
+ /**
1225
+ * A Wassist-managed WhatsApp template, returned by every endpoint under
1226
+ * `/whatsapp-templates/`.
1227
+ */
1228
+ interface WhatsAppTemplate {
1229
+ id: UUID;
1230
+ name: string;
1231
+ category: WhatsAppTemplateCategory;
1232
+ language: string;
1233
+ parameterFormat: WhatsAppTemplateParameterFormat;
1234
+ components: WhatsAppTemplateComponent[];
1235
+ /** One entry per WABA this template has been published to. */
1236
+ accountLinks: WhatsAppTemplateAccountLink[];
1237
+ createdAt: ISODateTime;
1238
+ updatedAt: ISODateTime;
1239
+ }
1240
+ /** Input for `POST /whatsapp-templates/`. */
1241
+ interface CreateWhatsAppTemplateInput {
1242
+ name: string;
1243
+ category: WhatsAppTemplateCategory;
1244
+ language?: string;
1245
+ parameterFormat?: WhatsAppTemplateParameterFormat;
1246
+ components?: WhatsAppTemplateComponent[];
1247
+ }
1248
+ /** Input for `PATCH /whatsapp-templates/{id}/`. */
1249
+ interface UpdateWhatsAppTemplateInput {
1250
+ name?: string;
1251
+ category?: WhatsAppTemplateCategory;
1252
+ language?: string;
1253
+ parameterFormat?: WhatsAppTemplateParameterFormat;
1254
+ components?: WhatsAppTemplateComponent[];
1255
+ }
1256
+ /** Input for `POST /whatsapp-templates/{id}/publish/`. */
1257
+ interface PublishWhatsAppTemplateInput {
1258
+ /** WABA IDs to publish this template to (must be at least one). */
1259
+ accountIds: UUID[];
1260
+ }
1261
+ /** Input for `POST /whatsapp-templates/{id}/unpublish/`. */
1262
+ interface UnpublishWhatsAppTemplateInput {
1263
+ /** WABA IDs to unpublish this template from (must be at least one). */
1264
+ accountIds: UUID[];
1265
+ }
1266
+ interface WhatsAppTemplatePublishResult {
1267
+ accountId: UUID;
1268
+ metaTemplateId?: string;
1269
+ status?: string;
1270
+ error?: string;
1271
+ }
1272
+ interface WhatsAppTemplateUnpublishResult {
1273
+ accountId: UUID;
1274
+ unpublished: boolean;
1275
+ }
1276
+ /**
1277
+ * Extended response from publish/unpublish endpoints — same shape as a
1278
+ * regular `WhatsAppTemplate` plus the per-account result arrays.
1279
+ */
1280
+ interface WhatsAppTemplateWithPublishResults extends WhatsAppTemplate {
1281
+ publishResults?: WhatsAppTemplatePublishResult[];
1282
+ publishErrors?: WhatsAppTemplatePublishResult[];
1283
+ unpublishResults?: WhatsAppTemplateUnpublishResult[];
1284
+ unpublishErrors?: WhatsAppTemplatePublishResult[];
1285
+ }
1286
+
1287
+ /**
1288
+ * Methods for managing Wassist-side WhatsApp templates and publishing them
1289
+ * to your connected WABAs.
1290
+ */
1291
+ declare class WhatsAppTemplatesResource {
1292
+ private readonly http;
1293
+ /** @internal */
1294
+ constructor(http: HttpClient);
1295
+ /**
1296
+ * List every template you've created in Wassist.
1297
+ *
1298
+ * `GET /whatsapp-templates/`
1299
+ */
1300
+ list(params?: PageParams, options?: RequestOptions): AutoPaginatedList<WhatsAppTemplate>;
1301
+ /**
1302
+ * Retrieve a single template by ID.
1303
+ *
1304
+ * `GET /whatsapp-templates/{id}/`
1305
+ */
1306
+ get(id: UUID, options?: RequestOptions): Promise<WhatsAppTemplate>;
1307
+ /**
1308
+ * Create a new template. Published per-WABA separately via {@link publish}.
1309
+ *
1310
+ * `POST /whatsapp-templates/`
1311
+ */
1312
+ create(input: CreateWhatsAppTemplateInput, options?: RequestOptions): Promise<WhatsAppTemplate>;
1313
+ /**
1314
+ * Update an existing template's metadata and components.
1315
+ *
1316
+ * `PATCH /whatsapp-templates/{id}/`
1317
+ */
1318
+ update(id: UUID, input: UpdateWhatsAppTemplateInput, options?: RequestOptions): Promise<WhatsAppTemplate>;
1319
+ /**
1320
+ * Delete a template (and unpublish from every WABA it was published to).
1321
+ *
1322
+ * `DELETE /whatsapp-templates/{id}/`
1323
+ */
1324
+ delete(id: UUID, options?: RequestOptions): Promise<void>;
1325
+ /**
1326
+ * Submit this template to one or more WABAs for approval.
1327
+ *
1328
+ * Returns the updated template, plus per-account `publishResults` /
1329
+ * `publishErrors`.
1330
+ *
1331
+ * `POST /whatsapp-templates/{id}/publish/`
1332
+ */
1333
+ publish(id: UUID, input: PublishWhatsAppTemplateInput, options?: RequestOptions): Promise<WhatsAppTemplateWithPublishResults>;
1334
+ /**
1335
+ * Remove this template from one or more WABAs.
1336
+ *
1337
+ * `POST /whatsapp-templates/{id}/unpublish/`
1338
+ */
1339
+ unpublish(id: UUID, input: UnpublishWhatsAppTemplateInput, options?: RequestOptions): Promise<WhatsAppTemplateWithPublishResults>;
1340
+ }
1341
+
1342
+ /**
1343
+ * The base shape every webhook event shares.
1344
+ */
1345
+ interface WassistEventBase<TEvent extends string = string> {
1346
+ /** The event name (e.g. `"message.received"`). */
1347
+ event: TEvent;
1348
+ /** Server-side timestamp the event was emitted (ISO-8601 UTC). */
1349
+ timestamp: ISODateTime;
1350
+ }
1351
+ interface MessageReceivedMessage {
1352
+ id: UUID;
1353
+ /** Meta's `wamid.` ID for the inbound WhatsApp message. */
1354
+ waId: string;
1355
+ body: string;
1356
+ media: {
1357
+ url: string;
1358
+ mimeType: string;
1359
+ }[];
1360
+ buttons: {
1361
+ type: 'url' | 'quick_reply';
1362
+ text: string;
1363
+ url?: string;
1364
+ quickReplyId?: string;
1365
+ }[];
1366
+ }
1367
+ interface MessageReceivedEvent extends WassistEventBase<'message.received'> {
1368
+ /** Your phone number that received the message. */
1369
+ phoneNumber: PhoneNumberString;
1370
+ /** The contact's phone number. */
1371
+ from: PhoneNumberString;
1372
+ contact: {
1373
+ name: string | null;
1374
+ phoneNumber: PhoneNumberString;
1375
+ };
1376
+ message: MessageReceivedMessage;
1377
+ conversationId: UUID;
1378
+ }
1379
+ interface SubscriptionActivatedEvent extends WassistEventBase<'subscription.activated'> {
1380
+ webhookId: UUID;
1381
+ conversationId: UUID;
1382
+ phoneNumber: PhoneNumberString;
1383
+ contact: {
1384
+ name: string | null;
1385
+ phoneNumber: PhoneNumberString;
1386
+ };
1387
+ }
1388
+ interface SubscriptionRevokedEvent extends WassistEventBase<'subscription.revoked'> {
1389
+ webhookId: UUID;
1390
+ conversationId: UUID;
1391
+ phoneNumber: PhoneNumberString;
1392
+ contact: {
1393
+ name: string | null;
1394
+ phoneNumber: PhoneNumberString;
1395
+ };
1396
+ }
1397
+ interface TestPingEvent extends WassistEventBase<'test.ping'> {
1398
+ /** Stub payload — used by the dashboard "Send test event" button. */
1399
+ message: string;
1400
+ }
1401
+ /**
1402
+ * Discriminated union of every documented Wassist webhook event.
1403
+ *
1404
+ * Unknown future events are still typed (as the `unknown` fallback) so a
1405
+ * runtime call to {@link Wassist.webhooks.constructEvent} never throws on
1406
+ * an unrecognized `event` name.
1407
+ */
1408
+ type WassistEvent = MessageReceivedEvent | SubscriptionActivatedEvent | SubscriptionRevokedEvent | TestPingEvent | (WassistEventBase<string> & Record<string, unknown>);
1409
+
1410
+ /**
1411
+ * Webhook signature verification.
1412
+ *
1413
+ * Implements the Stripe-style `t=<unix>,v1=<hex hmac sha256>` scheme
1414
+ * documented at https://docs.wassist.app/concepts/webhooks. Compute the HMAC of
1415
+ * `<timestamp>.<raw body>` with your webhook's signing secret and compare
1416
+ * it (in constant time) to the `v1` component of `X-Wassist-Signature`.
1417
+ *
1418
+ * This module exposes two helpers:
1419
+ *
1420
+ * - {@link Webhooks.constructEvent} — synchronous, uses `node:crypto` when
1421
+ * available (Node 18+).
1422
+ * - {@link Webhooks.constructEventAsync} — uses Web Crypto (`crypto.subtle`)
1423
+ * for runtimes that lack `node:crypto` (Cloudflare Workers, Deno, the
1424
+ * browser).
1425
+ */
1426
+
1427
+ interface VerifyOptions {
1428
+ /**
1429
+ * Maximum allowed difference between the server timestamp and `now`, in
1430
+ * seconds. Pass `0` to disable replay protection (not recommended).
1431
+ *
1432
+ * @default 300
1433
+ */
1434
+ tolerance?: number;
1435
+ /**
1436
+ * Override `now` for testing — defaults to `Date.now() / 1000`.
1437
+ * @internal
1438
+ */
1439
+ currentTimestamp?: number;
1440
+ }
1441
+ /**
1442
+ * Stripe-style webhook helpers.
1443
+ *
1444
+ * Use via the SDK class:
1445
+ *
1446
+ * ```ts
1447
+ * import { Wassist } from '@wassist/sdk';
1448
+ *
1449
+ * const wassist = new Wassist({ apiKey: process.env.WASSIST_API_KEY! });
1450
+ * const event = wassist.webhooks.constructEvent(rawBody, sigHeader, secret);
1451
+ * ```
1452
+ *
1453
+ * Or statically — no instance required for verification:
1454
+ *
1455
+ * ```ts
1456
+ * import { Wassist } from '@wassist/sdk';
1457
+ * const event = Wassist.webhooks.constructEvent(rawBody, sigHeader, secret);
1458
+ * ```
1459
+ */
1460
+ declare class Webhooks {
1461
+ /**
1462
+ * Verify the signature on a webhook delivery, parse the body, and return
1463
+ * the typed event.
1464
+ *
1465
+ * @param payload The raw request body, exactly as received — `string`,
1466
+ * `Buffer`, or `Uint8Array`. **Do not parse it first;**
1467
+ * even whitespace differences will break verification.
1468
+ * @param header The `X-Wassist-Signature` header value.
1469
+ * @param secret Your webhook signing secret. Find it in the
1470
+ * [Wassist dashboard](https://wassist.app/developers/webhooks).
1471
+ * @param options.tolerance Replay-protection window in seconds (default 300).
1472
+ * @throws {WassistSignatureVerificationError} When the header is malformed,
1473
+ * the HMAC doesn't match, or the timestamp is outside the tolerance window.
1474
+ */
1475
+ constructEvent(payload: string | Uint8Array, header: string | null | undefined, secret: string, options?: VerifyOptions): WassistEvent;
1476
+ /**
1477
+ * Async variant of {@link constructEvent} that uses Web Crypto, for
1478
+ * runtimes that don't expose `node:crypto` (Cloudflare Workers, Deno,
1479
+ * the browser).
1480
+ */
1481
+ constructEventAsync(payload: string | Uint8Array, header: string | null | undefined, secret: string, options?: VerifyOptions): Promise<WassistEvent>;
1482
+ /**
1483
+ * Compute the v1 signature for a `t.<body>` payload — exported as a
1484
+ * convenience for testing.
1485
+ */
1486
+ signSync(signedPayload: string, secret: string): string;
1487
+ /**
1488
+ * Web Crypto variant of {@link signSync}.
1489
+ */
1490
+ signAsync(signedPayload: string, secret: string): Promise<string>;
1491
+ private prepare;
1492
+ private assertValid;
1493
+ private parseEvent;
1494
+ }
1495
+
1496
+ /**
1497
+ * The Wassist API client.
1498
+ *
1499
+ * @example
1500
+ * ```ts
1501
+ * import { Wassist } from '@wassist/sdk';
1502
+ *
1503
+ * const wassist = new Wassist({ apiKey: process.env.WASSIST_API_KEY! });
1504
+ *
1505
+ * const agent = await wassist.agents.create({ name: 'Sales Assistant' });
1506
+ *
1507
+ * for await (const conv of wassist.conversations.list()) {
1508
+ * console.log(conv.id);
1509
+ * }
1510
+ * ```
1511
+ */
1512
+ declare class Wassist {
1513
+ /** Create and manage AI agents. */
1514
+ readonly agents: AgentsResource;
1515
+ /** Send messages and manage conversations (with nested `messages` resource). */
1516
+ readonly conversations: ConversationsResource;
1517
+ /** Manage your connected WhatsApp phone numbers and their routing. */
1518
+ readonly phoneNumbers: PhoneNumbersResource;
1519
+ /** Manage WhatsApp Business Accounts. */
1520
+ readonly whatsappAccounts: WhatsAppAccountsResource;
1521
+ /** Manage hosted WhatsApp account-linking sessions. */
1522
+ readonly whatsappLinkSessions: WhatsAppLinkSessionsResource;
1523
+ /** Manage WhatsApp message templates. */
1524
+ readonly whatsappTemplates: WhatsAppTemplatesResource;
1525
+ /** Verify inbound webhook signatures. */
1526
+ readonly webhooks: Webhooks;
1527
+ /**
1528
+ * Webhook helpers — usable without instantiating a client.
1529
+ *
1530
+ * @example
1531
+ * ```ts
1532
+ * const event = Wassist.webhooks.constructEvent(body, header, secret);
1533
+ * ```
1534
+ */
1535
+ static readonly webhooks: Webhooks;
1536
+ constructor(config: WassistClientConfig);
1537
+ }
1538
+
1539
+ /**
1540
+ * Error hierarchy for the Wassist SDK.
1541
+ *
1542
+ * Every network response and webhook signature failure surfaces as a subclass
1543
+ * of {@link WassistError}, so consumers can branch on `instanceof` (Stripe
1544
+ * convention) and read `statusCode`, `code`, `requestId`, and the raw body.
1545
+ */
1546
+ interface WassistErrorOptions {
1547
+ message: string;
1548
+ statusCode?: number;
1549
+ code?: string;
1550
+ requestId?: string;
1551
+ raw?: unknown;
1552
+ cause?: unknown;
1553
+ }
1554
+ declare class WassistError extends Error {
1555
+ /** HTTP status code if this error originated from an API response. */
1556
+ readonly statusCode?: number;
1557
+ /** Machine-readable error code (e.g. `not_found`) when the API provides one. */
1558
+ readonly code?: string;
1559
+ /**
1560
+ * Request ID surfaced by the Wassist API in the `X-Request-Id` response
1561
+ * header. Include this when filing support tickets.
1562
+ */
1563
+ readonly requestId?: string;
1564
+ /** Raw response body, parsed as JSON when possible. */
1565
+ readonly raw?: unknown;
1566
+ constructor(opts: WassistErrorOptions);
1567
+ }
1568
+ /** 401 Unauthorized — the API key was missing, malformed, or revoked. */
1569
+ declare class WassistAuthenticationError extends WassistError {
1570
+ }
1571
+ /** 403 Forbidden — the API key lacks permission for this resource. */
1572
+ declare class WassistPermissionError extends WassistError {
1573
+ }
1574
+ /** 400 / 422 — the request body or parameters were invalid. */
1575
+ declare class WassistInvalidRequestError extends WassistError {
1576
+ }
1577
+ /** 404 Not Found — the requested resource does not exist. */
1578
+ declare class WassistNotFoundError extends WassistError {
1579
+ }
1580
+ /** 409 Conflict — the request conflicts with the current state. */
1581
+ declare class WassistConflictError extends WassistError {
1582
+ }
1583
+ /** 429 Too Many Requests — slow down or wait `retryAfter` seconds. */
1584
+ declare class WassistRateLimitError extends WassistError {
1585
+ /** Suggested wait in seconds, from the `Retry-After` response header. */
1586
+ readonly retryAfter?: number;
1587
+ constructor(opts: WassistErrorOptions & {
1588
+ retryAfter?: number;
1589
+ });
1590
+ }
1591
+ /** 5xx — something is wrong on Wassist's side. The SDK retries these automatically. */
1592
+ declare class WassistAPIError extends WassistError {
1593
+ }
1594
+ /** A network-level failure (DNS, TCP, TLS, abort, etc.) — never made it to the server. */
1595
+ declare class WassistConnectionError extends WassistError {
1596
+ }
1597
+ /** The request exceeded the configured `timeout`. */
1598
+ declare class WassistTimeoutError extends WassistError {
1599
+ }
1600
+ /**
1601
+ * Webhook signature could not be verified.
1602
+ *
1603
+ * Thrown by {@link Wassist.webhooks.constructEvent} when the header is
1604
+ * malformed, the HMAC doesn't match, or the timestamp falls outside the
1605
+ * tolerance window.
1606
+ */
1607
+ declare class WassistSignatureVerificationError extends WassistError {
1608
+ /** The raw `X-Wassist-Signature` header value as received. */
1609
+ readonly header?: string;
1610
+ /** The payload that was verified, as the SDK saw it. */
1611
+ readonly payload?: string;
1612
+ constructor(opts: WassistErrorOptions & {
1613
+ header?: string;
1614
+ payload?: string;
1615
+ });
1616
+ }
1617
+
1618
+ /**
1619
+ * The package version, embedded into the `User-Agent` header on every
1620
+ * outbound request so Wassist can correlate API traffic with SDK versions.
1621
+ *
1622
+ * Updated in lockstep with `package.json`'s `version` field.
1623
+ */
1624
+ declare const SDK_VERSION = "0.1.0";
1625
+
1626
+ export { type AddNumberInput, type Agent, type AgentCreditSettings, type AgentCreditSettingsInput, type AgentDocument, type AgentHandoffTool, type AgentHandoffToolInput, type AgentImageGenerateTool, type AgentImageGenerateToolInput, type AgentMcpConfig, type AgentMcpConfigInput, type AgentMemoryKey, type AgentMemoryKeyInput, type AgentOutboundTrigger, type AgentOutboundTriggerInput, type AgentPaywallConfig, type AgentPaywallConfigInput, type AgentTool, type AgentToolInput, type AgentWakeUpConfig, type AgentWakeUpConfigInput, type AgentWebsiteTool, type AgentWebsiteToolInput, type AgentWhatsAppPhoneNumber, AgentsResource, AutoPaginatedList, type AvailableNumber, type AvailableNumbersResponse, type CTAButtonMessage, type ConnectAgentInput, type Conversation, type ConversationContact, type ConversationLastMessage, ConversationsResource, type CreateAgentInput, type CreateBYOAAgentInput, type CreateConversationInput, type CreateConversationMessageInput, type CreateWhatsAppLinkSessionInput, type CreateWhatsAppTemplateInput, type FetchLike, type FileInfo, type ISODateTime, type ImageInfo, type ImageMessage, type ListConversationsParams, type ListSelectionMessage, type Message, type MessageReceivedEvent, type MessageReceivedMessage, type MessageRole, type MessageStatus, type MessageType, MessagesResource, type Page, type PageParams, type PaginatedResponse, type PhoneNumber, type PhoneNumberBusinessProfile, type PhoneNumberRoutingMode, type PhoneNumberString, PhoneNumbersResource, type PromptAgentInput, type PublicUser, type PublishWhatsAppTemplateInput, type QuickReplyMessage, type RequestOptions, SDK_VERSION, type SendMessageCtaImageInput, type SendMessageCtaInput, type SendMessageInput, type SendMessageTemplateInput, type SendMessageTextInput, type SendUnifiedMessageButtonInput, type SendUnifiedMessageInput, type SendUnifiedMessageMediaInput, type SubscribeConversationInput, type SubscribePhoneNumberInput, type SubscriptionActivatedEvent, type SubscriptionRevokedEvent, type TemplateMessage, type TestPingEvent, type TextMessage, type UUID, type UnifiedMessage, type UnifiedMessageButton, type UnifiedMessageButtonType, type UnifiedMessageMedia, type UnpublishWhatsAppTemplateInput, type UnsubscribePhoneNumberInput, type UpdateAgentInput, type UpdateWhatsAppTemplateInput, Wassist, WassistAPIError, WassistAuthenticationError, type WassistClientConfig, WassistConflictError, WassistConnectionError, WassistError, type WassistErrorOptions, type WassistEvent, type WassistEventBase, WassistInvalidRequestError, WassistNotFoundError, WassistPermissionError, WassistRateLimitError, WassistSignatureVerificationError, WassistTimeoutError, Webhooks, type WhatsAppAccount, type WhatsAppAccountPhoneNumber, WhatsAppAccountsResource, type WhatsAppLinkSession, type WhatsAppLinkSessionStatus, WhatsAppLinkSessionsResource, type WhatsAppTemplate, type WhatsAppTemplateAccountLink, type WhatsAppTemplateButton, type WhatsAppTemplateButtonType, type WhatsAppTemplateCategory, type WhatsAppTemplateComponent, type WhatsAppTemplateComponentExample, type WhatsAppTemplateNamedParam, type WhatsAppTemplateParameterFormat, type WhatsAppTemplatePublishResult, type WhatsAppTemplateQuality, type WhatsAppTemplateStatus, type WhatsAppTemplateUnpublishResult, type WhatsAppTemplateWithPublishResults, WhatsAppTemplatesResource };