@kerabie/sdk 0.0.0-stage → 1.0.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.
- package/README.md +344 -3
- package/dist/index.d.mts +1292 -0
- package/dist/index.d.ts +1292 -0
- package/dist/index.js +537 -0
- package/dist/index.mjs +507 -0
- package/package.json +30 -4
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1292 @@
|
|
|
1
|
+
interface KerAbieClientConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
orgId?: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
}
|
|
7
|
+
interface PaginationMeta {
|
|
8
|
+
total: number;
|
|
9
|
+
page: number;
|
|
10
|
+
limit: number;
|
|
11
|
+
hasMore?: boolean;
|
|
12
|
+
/** Total pages (conversation lists). */
|
|
13
|
+
pages?: number;
|
|
14
|
+
/** Organisation-wide totals per status — ignores the list filters (conversation lists). */
|
|
15
|
+
counts?: ConversationCounts;
|
|
16
|
+
}
|
|
17
|
+
type ConversationStatus = 'WAITING' | 'ACTIVE' | 'RESOLVED' | 'CLOSED';
|
|
18
|
+
type ConversationChannel = 'WEBSITE' | 'WHATSAPP' | 'INSTAGRAM' | 'EMAIL' | 'API';
|
|
19
|
+
interface Conversation {
|
|
20
|
+
id: number;
|
|
21
|
+
status: ConversationStatus;
|
|
22
|
+
channel: ConversationChannel;
|
|
23
|
+
subject?: string | null;
|
|
24
|
+
customerId?: number | null;
|
|
25
|
+
customer?: {
|
|
26
|
+
id: number;
|
|
27
|
+
name: string | null;
|
|
28
|
+
email: string | null;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
};
|
|
31
|
+
/** Team-member id of the assignee, if any. */
|
|
32
|
+
assignedTeamMemberId?: number | null;
|
|
33
|
+
assignedAgent?: {
|
|
34
|
+
id: number;
|
|
35
|
+
userId: number;
|
|
36
|
+
user: {
|
|
37
|
+
fname: string | null;
|
|
38
|
+
lname: string | null;
|
|
39
|
+
email: string;
|
|
40
|
+
avatar?: string | null;
|
|
41
|
+
};
|
|
42
|
+
} | null;
|
|
43
|
+
rating?: number | null;
|
|
44
|
+
ratingComment?: string | null;
|
|
45
|
+
/** Text of the most recent message (list responses). */
|
|
46
|
+
lastMessage?: string | null;
|
|
47
|
+
lastMessageAt?: string | null;
|
|
48
|
+
/** First few tags (list responses); `get` returns all of them. */
|
|
49
|
+
tags?: {
|
|
50
|
+
tag: string;
|
|
51
|
+
}[];
|
|
52
|
+
/** True while the AI bot is handling the conversation alone: still open, no human reply, not handed off. */
|
|
53
|
+
aiHandling?: boolean;
|
|
54
|
+
/** AI recap written when the bot hands off to a human. */
|
|
55
|
+
handoffSummary?: string | null;
|
|
56
|
+
/** Unread message count, under `_count.messages` (list responses). */
|
|
57
|
+
_count?: {
|
|
58
|
+
messages: number;
|
|
59
|
+
};
|
|
60
|
+
createdAt: string;
|
|
61
|
+
updatedAt: string;
|
|
62
|
+
}
|
|
63
|
+
/** Organisation-wide conversation totals per status. */
|
|
64
|
+
interface ConversationCounts {
|
|
65
|
+
all: number;
|
|
66
|
+
WAITING: number;
|
|
67
|
+
ACTIVE: number;
|
|
68
|
+
RESOLVED: number;
|
|
69
|
+
CLOSED: number;
|
|
70
|
+
}
|
|
71
|
+
/** An earlier conversation with the same customer. */
|
|
72
|
+
interface PreviousConversation {
|
|
73
|
+
id: number;
|
|
74
|
+
status: ConversationStatus;
|
|
75
|
+
channel: ConversationChannel;
|
|
76
|
+
subject: string | null;
|
|
77
|
+
isTicket: boolean;
|
|
78
|
+
createdAt: string;
|
|
79
|
+
lastMessageAt: string | null;
|
|
80
|
+
handoffSummary: string | null;
|
|
81
|
+
}
|
|
82
|
+
interface TakeOverParams {
|
|
83
|
+
/** Organisation team-member id the conversation is assigned to if nobody holds it yet. */
|
|
84
|
+
agentId: number;
|
|
85
|
+
}
|
|
86
|
+
interface ListConversationsParams {
|
|
87
|
+
status?: ConversationStatus;
|
|
88
|
+
channel?: ConversationChannel;
|
|
89
|
+
page?: number;
|
|
90
|
+
limit?: number;
|
|
91
|
+
search?: string;
|
|
92
|
+
assignedTo?: number;
|
|
93
|
+
}
|
|
94
|
+
interface CreateConversationParams {
|
|
95
|
+
customerId?: number;
|
|
96
|
+
customerEmail?: string;
|
|
97
|
+
subject?: string;
|
|
98
|
+
channel?: ConversationChannel;
|
|
99
|
+
metadata?: Record<string, any>;
|
|
100
|
+
}
|
|
101
|
+
interface UpdateConversationParams {
|
|
102
|
+
status?: ConversationStatus;
|
|
103
|
+
assignedTeamMemberId?: number;
|
|
104
|
+
rating?: number;
|
|
105
|
+
ratingComment?: string;
|
|
106
|
+
}
|
|
107
|
+
type MessageType = 'text' | 'image' | 'file' | 'audio' | 'video' | 'system';
|
|
108
|
+
type SenderType = 'agent' | 'visitor' | 'bot';
|
|
109
|
+
interface Message {
|
|
110
|
+
id: number;
|
|
111
|
+
conversationId: number;
|
|
112
|
+
body: string;
|
|
113
|
+
type: MessageType;
|
|
114
|
+
senderType: SenderType;
|
|
115
|
+
senderName?: string;
|
|
116
|
+
agentId?: number;
|
|
117
|
+
metadata?: Record<string, any>;
|
|
118
|
+
attachments?: Attachment[];
|
|
119
|
+
createdAt: string;
|
|
120
|
+
}
|
|
121
|
+
interface Attachment {
|
|
122
|
+
id: string;
|
|
123
|
+
url: string;
|
|
124
|
+
type: 'image' | 'file' | 'audio' | 'video';
|
|
125
|
+
name?: string;
|
|
126
|
+
size?: number;
|
|
127
|
+
mimeType?: string;
|
|
128
|
+
}
|
|
129
|
+
interface SendMessageParams {
|
|
130
|
+
body: string;
|
|
131
|
+
type?: MessageType;
|
|
132
|
+
metadata?: Record<string, any>;
|
|
133
|
+
}
|
|
134
|
+
interface ListMessagesParams {
|
|
135
|
+
limit?: number;
|
|
136
|
+
before?: number;
|
|
137
|
+
}
|
|
138
|
+
interface Customer {
|
|
139
|
+
id: number;
|
|
140
|
+
name?: string;
|
|
141
|
+
email?: string;
|
|
142
|
+
phone?: string;
|
|
143
|
+
avatar?: string;
|
|
144
|
+
externalSource?: string;
|
|
145
|
+
externalRef?: string;
|
|
146
|
+
customAttributes?: Record<string, string>;
|
|
147
|
+
conversationCount?: number;
|
|
148
|
+
createdAt: string;
|
|
149
|
+
updatedAt: string;
|
|
150
|
+
}
|
|
151
|
+
interface UpsertCustomerParams {
|
|
152
|
+
email?: string;
|
|
153
|
+
name?: string;
|
|
154
|
+
phone?: string;
|
|
155
|
+
externalSource?: string;
|
|
156
|
+
externalRef?: string;
|
|
157
|
+
customAttributes?: Record<string, string>;
|
|
158
|
+
}
|
|
159
|
+
type VisitorStatus = 'online' | 'offline' | 'blocked' | 'allowed';
|
|
160
|
+
/** A visitor from the last few days — on the site now or recently gone. */
|
|
161
|
+
interface Visitor {
|
|
162
|
+
/** The widget's anonymous session id. */
|
|
163
|
+
sessionId: string;
|
|
164
|
+
/** From the contact record if they have chatted, otherwise as identified to the widget. */
|
|
165
|
+
name: string | null;
|
|
166
|
+
email: string | null;
|
|
167
|
+
phone: string | null;
|
|
168
|
+
/** ISO 3166-1 alpha-2 code, e.g. "NG". */
|
|
169
|
+
country: string | null;
|
|
170
|
+
city: string | null;
|
|
171
|
+
/** null when the organisation hides visitor IPs in its privacy settings. */
|
|
172
|
+
ip: string | null;
|
|
173
|
+
userAgent: string | null;
|
|
174
|
+
/** The page they are on now (online) or were last on. */
|
|
175
|
+
currentPage: string | null;
|
|
176
|
+
/** Visits so far. Coming back after 30+ minutes away counts as a new visit. */
|
|
177
|
+
visitCount: number;
|
|
178
|
+
firstSeenAt: string;
|
|
179
|
+
lastSeenAt: string;
|
|
180
|
+
/** Their most recent conversation, if they have chatted. */
|
|
181
|
+
conversationId: number | null;
|
|
182
|
+
/** Blocked / allowed come from your IP rules and win over online / offline. */
|
|
183
|
+
status: VisitorStatus;
|
|
184
|
+
}
|
|
185
|
+
interface ListVisitorsParams {
|
|
186
|
+
status?: 'all' | VisitorStatus;
|
|
187
|
+
/** Matches name, email, IP, city or page, case-insensitively. */
|
|
188
|
+
search?: string;
|
|
189
|
+
/** Two-letter country code. */
|
|
190
|
+
country?: string;
|
|
191
|
+
/** How far back to look: default 7, max 30 (visitor history is kept for 30 days). */
|
|
192
|
+
days?: number;
|
|
193
|
+
page?: number;
|
|
194
|
+
limit?: number;
|
|
195
|
+
}
|
|
196
|
+
interface VisitorsOverview {
|
|
197
|
+
/** On the site right now. */
|
|
198
|
+
online: number;
|
|
199
|
+
/** Distinct countries in the last 24 hours. */
|
|
200
|
+
countries: number;
|
|
201
|
+
/** Visitors in the last 24 hours who have visited more than once. */
|
|
202
|
+
returning: number;
|
|
203
|
+
/** Active IP block rules. */
|
|
204
|
+
blockedIps: number;
|
|
205
|
+
topCountries: {
|
|
206
|
+
country: string;
|
|
207
|
+
count: number;
|
|
208
|
+
}[];
|
|
209
|
+
}
|
|
210
|
+
interface VisitorsExport {
|
|
211
|
+
/** e.g. visitors-2026-10-05.csv */
|
|
212
|
+
filename: string;
|
|
213
|
+
csv: string;
|
|
214
|
+
count: number;
|
|
215
|
+
/** True when more than 5,000 matched and the file was cut at 5,000. */
|
|
216
|
+
truncated: boolean;
|
|
217
|
+
}
|
|
218
|
+
interface BlockVisitorParams {
|
|
219
|
+
reason?: string;
|
|
220
|
+
blockIp?: boolean;
|
|
221
|
+
}
|
|
222
|
+
type CampaignStatus = 'active' | 'paused' | 'draft';
|
|
223
|
+
type CampaignTrigger = 'page_load' | 'time_on_page' | 'scroll_depth' | 'exit_intent';
|
|
224
|
+
type CampaignAction = 'open_chat' | 'open_kb' | 'open_link';
|
|
225
|
+
type CampaignAudience = 'all' | 'new' | 'returning' | 'not_chatted' | 'country';
|
|
226
|
+
type CampaignFrequency = 'once_per_visitor' | 'once_per_day' | 'every_session';
|
|
227
|
+
interface Campaign {
|
|
228
|
+
id: number;
|
|
229
|
+
name: string;
|
|
230
|
+
/** What the visitor sees. */
|
|
231
|
+
message: string;
|
|
232
|
+
/** Button text; no button when null. */
|
|
233
|
+
ctaLabel: string | null;
|
|
234
|
+
ctaAction: CampaignAction;
|
|
235
|
+
/** Only for `open_link`. */
|
|
236
|
+
ctaUrl: string | null;
|
|
237
|
+
trigger: CampaignTrigger;
|
|
238
|
+
/** Seconds for `time_on_page`, percent for `scroll_depth`, otherwise null. */
|
|
239
|
+
triggerValue: string | null;
|
|
240
|
+
/** Comma-separated URL patterns (`*` wildcards); null = every page. */
|
|
241
|
+
pages: string | null;
|
|
242
|
+
audience: CampaignAudience;
|
|
243
|
+
/** ISO country code (e.g. `NG`), only for audience `country`. */
|
|
244
|
+
audienceCountry: string | null;
|
|
245
|
+
frequency: CampaignFrequency;
|
|
246
|
+
isActive: boolean;
|
|
247
|
+
/** `draft` = never launched, `paused` = launched before but off. */
|
|
248
|
+
status: CampaignStatus;
|
|
249
|
+
launchedAt: string | null;
|
|
250
|
+
/** Times it was shown to a visitor. */
|
|
251
|
+
sentCount: number;
|
|
252
|
+
/** Visitors who opened the chat from it. */
|
|
253
|
+
openedCount: number;
|
|
254
|
+
/** Visitors who pressed its button. */
|
|
255
|
+
clickCount: number;
|
|
256
|
+
/** Visitors who wrote back after opening it. */
|
|
257
|
+
repliedCount: number;
|
|
258
|
+
createdAt: string;
|
|
259
|
+
}
|
|
260
|
+
interface ListCampaignsParams {
|
|
261
|
+
status?: CampaignStatus;
|
|
262
|
+
/** Matches name or message, case-insensitively. */
|
|
263
|
+
search?: string;
|
|
264
|
+
page?: number;
|
|
265
|
+
limit?: number;
|
|
266
|
+
}
|
|
267
|
+
interface CreateCampaignParams {
|
|
268
|
+
name: string;
|
|
269
|
+
message: string;
|
|
270
|
+
ctaLabel?: string;
|
|
271
|
+
ctaAction?: CampaignAction;
|
|
272
|
+
ctaUrl?: string;
|
|
273
|
+
trigger?: CampaignTrigger;
|
|
274
|
+
triggerValue?: string | number;
|
|
275
|
+
pages?: string;
|
|
276
|
+
audience?: CampaignAudience;
|
|
277
|
+
/** Required when audience is `country`. */
|
|
278
|
+
audienceCountry?: string;
|
|
279
|
+
frequency?: CampaignFrequency;
|
|
280
|
+
/** `true` launches it straight away (counts against your plan's live-campaign limit). Default: saved as a draft. */
|
|
281
|
+
isActive?: boolean;
|
|
282
|
+
}
|
|
283
|
+
type UpdateCampaignParams = Partial<CreateCampaignParams>;
|
|
284
|
+
interface CampaignStats {
|
|
285
|
+
total: number;
|
|
286
|
+
active: number;
|
|
287
|
+
paused: number;
|
|
288
|
+
draft: number;
|
|
289
|
+
sent: number;
|
|
290
|
+
opened: number;
|
|
291
|
+
clicked: number;
|
|
292
|
+
replied: number;
|
|
293
|
+
/** Most campaigns your plan lets you run at once; 0 = unlimited. */
|
|
294
|
+
limit: number;
|
|
295
|
+
}
|
|
296
|
+
type ContactType = 'LEAD' | 'CUSTOMER' | 'VIP';
|
|
297
|
+
interface Contact {
|
|
298
|
+
id: number;
|
|
299
|
+
name: string | null;
|
|
300
|
+
email: string | null;
|
|
301
|
+
phone: string | null;
|
|
302
|
+
company: string | null;
|
|
303
|
+
notes: string | null;
|
|
304
|
+
contactType: ContactType;
|
|
305
|
+
/** Team-member id of the owner, if any. */
|
|
306
|
+
ownerId: number | null;
|
|
307
|
+
owner: {
|
|
308
|
+
id: number;
|
|
309
|
+
user: {
|
|
310
|
+
fname: string | null;
|
|
311
|
+
lname: string | null;
|
|
312
|
+
email: string;
|
|
313
|
+
avatar?: string | null;
|
|
314
|
+
};
|
|
315
|
+
} | null;
|
|
316
|
+
tagLinks: {
|
|
317
|
+
tag: {
|
|
318
|
+
id: number;
|
|
319
|
+
name: string;
|
|
320
|
+
color: string | null;
|
|
321
|
+
};
|
|
322
|
+
}[];
|
|
323
|
+
/** Two-letter country code, from the visitor's IP when they chatted in. */
|
|
324
|
+
visitorCountry: string | null;
|
|
325
|
+
/** 'manual', 'import', or null for contacts who wrote in themselves. */
|
|
326
|
+
externalSource: string | null;
|
|
327
|
+
/** Last message in either direction; falls back to the latest conversation for older contacts. */
|
|
328
|
+
lastContactAt: string | null;
|
|
329
|
+
createdAt: string;
|
|
330
|
+
_count: {
|
|
331
|
+
conversations: number;
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
interface ListContactsParams {
|
|
335
|
+
/** Matches name, email, phone, company or a tag name, case-insensitively. */
|
|
336
|
+
search?: string;
|
|
337
|
+
type?: ContactType;
|
|
338
|
+
tagId?: number;
|
|
339
|
+
/** Team-member id. */
|
|
340
|
+
ownerId?: number;
|
|
341
|
+
/** 'recent' (default) = last contact first, contacts never messaged last. */
|
|
342
|
+
sort?: 'recent' | 'newest' | 'name';
|
|
343
|
+
page?: number;
|
|
344
|
+
limit?: number;
|
|
345
|
+
}
|
|
346
|
+
interface CreateContactParams {
|
|
347
|
+
name?: string;
|
|
348
|
+
email?: string;
|
|
349
|
+
phone?: string;
|
|
350
|
+
company?: string;
|
|
351
|
+
notes?: string;
|
|
352
|
+
contactType?: ContactType;
|
|
353
|
+
ownerId?: number | null;
|
|
354
|
+
}
|
|
355
|
+
type UpdateContactParams = CreateContactParams;
|
|
356
|
+
interface ContactStats {
|
|
357
|
+
total: number;
|
|
358
|
+
/** Added in the last 7 days. */
|
|
359
|
+
newThisWeek: number;
|
|
360
|
+
leads: number;
|
|
361
|
+
vip: number;
|
|
362
|
+
}
|
|
363
|
+
interface ImportContactRow {
|
|
364
|
+
name?: string;
|
|
365
|
+
email?: string;
|
|
366
|
+
phone?: string;
|
|
367
|
+
company?: string;
|
|
368
|
+
/** lead, customer or vip (any case). Defaults to lead. */
|
|
369
|
+
type?: string;
|
|
370
|
+
}
|
|
371
|
+
interface ImportContactsResult {
|
|
372
|
+
created: number;
|
|
373
|
+
/** Rows skipped because the email already belongs to a contact. */
|
|
374
|
+
duplicates: number;
|
|
375
|
+
/** Rows that could not be imported. `row` is 1-based, not counting the header. */
|
|
376
|
+
invalid: {
|
|
377
|
+
row: number;
|
|
378
|
+
error: string;
|
|
379
|
+
}[];
|
|
380
|
+
total: number;
|
|
381
|
+
}
|
|
382
|
+
interface Agent {
|
|
383
|
+
id: number;
|
|
384
|
+
fname: string;
|
|
385
|
+
lname: string;
|
|
386
|
+
email: string;
|
|
387
|
+
avatar?: string;
|
|
388
|
+
availability?: 'online' | 'away' | 'offline';
|
|
389
|
+
role?: string;
|
|
390
|
+
}
|
|
391
|
+
interface InviteAgentParams {
|
|
392
|
+
email: string;
|
|
393
|
+
accessLevel?: 'ADMIN' | 'CHAT_ONLY' | 'READ_ONLY';
|
|
394
|
+
teamId?: number;
|
|
395
|
+
}
|
|
396
|
+
type KbArticleType = 'faq' | 'article' | 'news' | 'information';
|
|
397
|
+
type KbArticleStatus = 'draft' | 'published' | 'archived';
|
|
398
|
+
interface KbArticle {
|
|
399
|
+
id: number;
|
|
400
|
+
title: string;
|
|
401
|
+
content: string;
|
|
402
|
+
category: string;
|
|
403
|
+
type: KbArticleType;
|
|
404
|
+
status: KbArticleStatus;
|
|
405
|
+
imageUrl?: string;
|
|
406
|
+
views: number;
|
|
407
|
+
/** Share of widget visitors who found it helpful (0-100); null until at least 3 have voted. */
|
|
408
|
+
helpfulPct: number | null;
|
|
409
|
+
/** How many visitors have voted. */
|
|
410
|
+
votes: number;
|
|
411
|
+
/** Times the AI chatbot cited it in an answer. */
|
|
412
|
+
aiCitations: number;
|
|
413
|
+
createdAt: string;
|
|
414
|
+
updatedAt: string;
|
|
415
|
+
}
|
|
416
|
+
interface KbStats {
|
|
417
|
+
total: number;
|
|
418
|
+
published: number;
|
|
419
|
+
drafts: number;
|
|
420
|
+
views: number;
|
|
421
|
+
/** The most viewed published article; null until something has been viewed. */
|
|
422
|
+
top: {
|
|
423
|
+
title: string;
|
|
424
|
+
views: number;
|
|
425
|
+
} | null;
|
|
426
|
+
/** Categories in use. */
|
|
427
|
+
categories: string[];
|
|
428
|
+
}
|
|
429
|
+
interface KbInsights {
|
|
430
|
+
mostViewed: {
|
|
431
|
+
id: number;
|
|
432
|
+
title: string;
|
|
433
|
+
views: number;
|
|
434
|
+
pct: number;
|
|
435
|
+
}[];
|
|
436
|
+
/** Customer questions the AI had no article to answer from in the last 30 days: what to write next. */
|
|
437
|
+
gaps: {
|
|
438
|
+
question: string;
|
|
439
|
+
count: number;
|
|
440
|
+
}[];
|
|
441
|
+
/** Published articles with the lowest helpfulness, lowest first (needs 3 votes). */
|
|
442
|
+
lowestRated: {
|
|
443
|
+
id: number;
|
|
444
|
+
title: string;
|
|
445
|
+
helpfulPct: number;
|
|
446
|
+
votes: number;
|
|
447
|
+
}[];
|
|
448
|
+
/** Published articles not updated in 90 days. */
|
|
449
|
+
stale: {
|
|
450
|
+
id: number;
|
|
451
|
+
title: string;
|
|
452
|
+
age: string;
|
|
453
|
+
}[];
|
|
454
|
+
}
|
|
455
|
+
interface CreateArticleParams {
|
|
456
|
+
title: string;
|
|
457
|
+
content: string;
|
|
458
|
+
category?: string;
|
|
459
|
+
type?: KbArticleType;
|
|
460
|
+
status?: KbArticleStatus;
|
|
461
|
+
}
|
|
462
|
+
type TicketPriority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
|
|
463
|
+
interface Ticket {
|
|
464
|
+
id: number;
|
|
465
|
+
status: ConversationStatus;
|
|
466
|
+
priority: TicketPriority;
|
|
467
|
+
subject?: string;
|
|
468
|
+
slaDueAt?: string;
|
|
469
|
+
customerId?: number;
|
|
470
|
+
createdAt: string;
|
|
471
|
+
updatedAt: string;
|
|
472
|
+
}
|
|
473
|
+
/** KPI numbers for the tickets overview. */
|
|
474
|
+
interface TicketStats {
|
|
475
|
+
/** Tickets that are new or active. */
|
|
476
|
+
open: number;
|
|
477
|
+
/** Open tickets nobody owns. */
|
|
478
|
+
unassigned: number;
|
|
479
|
+
/** Open tickets past their SLA due time. */
|
|
480
|
+
breachingSla: number;
|
|
481
|
+
/** Average open→resolved time in minutes over the last 7 days; null when none were resolved. */
|
|
482
|
+
avgResolutionMinutes: number | null;
|
|
483
|
+
/** % change vs the 7 days before; negative = faster. Null when there is nothing to compare. */
|
|
484
|
+
resolutionDeltaPct: number | null;
|
|
485
|
+
}
|
|
486
|
+
interface ExportTicketsParams {
|
|
487
|
+
status?: ConversationStatus;
|
|
488
|
+
priority?: TicketPriority;
|
|
489
|
+
/** Matches requester name or email, subject, or a ticket reference such as KB-2041. */
|
|
490
|
+
search?: string;
|
|
491
|
+
/** User id of the assigned agent. */
|
|
492
|
+
assignedTo?: number;
|
|
493
|
+
}
|
|
494
|
+
interface TicketExport {
|
|
495
|
+
/** e.g. tickets-2026-10-05.csv */
|
|
496
|
+
filename: string;
|
|
497
|
+
csv: string;
|
|
498
|
+
count: number;
|
|
499
|
+
/** True when more than 5,000 tickets matched and the file was cut at 5,000. */
|
|
500
|
+
truncated: boolean;
|
|
501
|
+
}
|
|
502
|
+
interface CreateTicketParams {
|
|
503
|
+
/** A stable identifier for this end user in your own system — repeated calls with the same externalRef land on the same ticket. */
|
|
504
|
+
externalRef: string;
|
|
505
|
+
message: string;
|
|
506
|
+
subject?: string;
|
|
507
|
+
priority?: TicketPriority;
|
|
508
|
+
name?: string;
|
|
509
|
+
email?: string;
|
|
510
|
+
}
|
|
511
|
+
interface UpdateTicketParams {
|
|
512
|
+
status?: ConversationStatus;
|
|
513
|
+
priority?: TicketPriority;
|
|
514
|
+
}
|
|
515
|
+
interface TicketMessage {
|
|
516
|
+
id: number;
|
|
517
|
+
body: string;
|
|
518
|
+
senderRole: 'agent' | 'customer';
|
|
519
|
+
senderName?: string;
|
|
520
|
+
createdAt: string;
|
|
521
|
+
}
|
|
522
|
+
interface StoreProduct {
|
|
523
|
+
id: number;
|
|
524
|
+
name: string;
|
|
525
|
+
description?: string;
|
|
526
|
+
price: number;
|
|
527
|
+
currency: string;
|
|
528
|
+
imageUrl?: string;
|
|
529
|
+
category?: string;
|
|
530
|
+
stock?: number;
|
|
531
|
+
sku?: string;
|
|
532
|
+
isActive: boolean;
|
|
533
|
+
createdAt: string;
|
|
534
|
+
updatedAt: string;
|
|
535
|
+
}
|
|
536
|
+
type WebhookEvent = 'message.sent.customer' | 'message.sent.agent' | 'conversation.created' | 'conversation.resolved' | 'conversation.assigned' | 'visitor.new' | 'rating.submitted';
|
|
537
|
+
interface Webhook {
|
|
538
|
+
id: number;
|
|
539
|
+
url: string;
|
|
540
|
+
events: WebhookEvent[];
|
|
541
|
+
isActive: boolean;
|
|
542
|
+
secret?: string;
|
|
543
|
+
createdAt: string;
|
|
544
|
+
}
|
|
545
|
+
interface CreateWebhookParams {
|
|
546
|
+
url: string;
|
|
547
|
+
events: WebhookEvent[];
|
|
548
|
+
secret?: string;
|
|
549
|
+
}
|
|
550
|
+
interface AnalyticsSummary {
|
|
551
|
+
period: {
|
|
552
|
+
days: number;
|
|
553
|
+
since: string;
|
|
554
|
+
};
|
|
555
|
+
/** Currently open (new + active) conversations. */
|
|
556
|
+
openConversations: number;
|
|
557
|
+
/** Conversations resolved or closed since midnight. */
|
|
558
|
+
resolvedToday: number;
|
|
559
|
+
/** Average first-response time in seconds (0 when there is no data). */
|
|
560
|
+
avgResponseTime: number;
|
|
561
|
+
/** Customer satisfaction 0–100 (average rating × 20). */
|
|
562
|
+
satisfactionScore: number;
|
|
563
|
+
/** Visitors on the website right now. */
|
|
564
|
+
activeVisitors: number;
|
|
565
|
+
totals: {
|
|
566
|
+
conversations: number;
|
|
567
|
+
resolved: number;
|
|
568
|
+
closed: number;
|
|
569
|
+
messages: number;
|
|
570
|
+
visitors: number;
|
|
571
|
+
aiChats: number;
|
|
572
|
+
/** Tickets created in the period. */
|
|
573
|
+
tickets: number;
|
|
574
|
+
/** Contacts added (someone with a name, email or phone). */
|
|
575
|
+
contacts: number;
|
|
576
|
+
/** Website visitor sessions that started in the period (history is kept 30 days, so longer windows count that far back). */
|
|
577
|
+
siteVisitors: number;
|
|
578
|
+
};
|
|
579
|
+
rates: {
|
|
580
|
+
resolution: number;
|
|
581
|
+
};
|
|
582
|
+
satisfaction: {
|
|
583
|
+
avgRating: number | null;
|
|
584
|
+
totalRatings: number;
|
|
585
|
+
};
|
|
586
|
+
/** % change vs the previous period of the same length; null = nothing to compare. For responseTime, negative is an improvement. */
|
|
587
|
+
deltas: {
|
|
588
|
+
conversations: number | null;
|
|
589
|
+
resolved: number | null;
|
|
590
|
+
responseTime: number | null;
|
|
591
|
+
satisfaction: number | null;
|
|
592
|
+
aiChats: number | null;
|
|
593
|
+
};
|
|
594
|
+
/** The AI assistant's share of the work. */
|
|
595
|
+
ai: {
|
|
596
|
+
/** Conversations the AI handled alone (no human ever replied). */
|
|
597
|
+
resolvedAlone: number;
|
|
598
|
+
resolvedAlonePct: number;
|
|
599
|
+
/** Share of conversations handed off to a human. */
|
|
600
|
+
handedOffPct: number;
|
|
601
|
+
/** Estimate: AI-only conversations × the average time agents spent on human-handled ones. */
|
|
602
|
+
agentHoursSaved: number;
|
|
603
|
+
};
|
|
604
|
+
channels: {
|
|
605
|
+
channel: string;
|
|
606
|
+
count: number;
|
|
607
|
+
}[];
|
|
608
|
+
aiEscalations: {
|
|
609
|
+
reason: string;
|
|
610
|
+
count: number;
|
|
611
|
+
}[];
|
|
612
|
+
/** Daily buckets (up to 30), oldest first. `ai` + `human` = `count`. */
|
|
613
|
+
trend: {
|
|
614
|
+
date: string;
|
|
615
|
+
count: number;
|
|
616
|
+
ai: number;
|
|
617
|
+
human: number;
|
|
618
|
+
}[];
|
|
619
|
+
}
|
|
620
|
+
interface AnalyticsParams {
|
|
621
|
+
/** Window in days (default 30, max 365). */
|
|
622
|
+
days?: number;
|
|
623
|
+
/** Alternative to `days`, e.g. '7d' or '30d'. */
|
|
624
|
+
period?: string;
|
|
625
|
+
}
|
|
626
|
+
interface AgentStat {
|
|
627
|
+
agentId: number;
|
|
628
|
+
/** Full name, falling back to the email's local part for agents who haven't set one. */
|
|
629
|
+
name: string;
|
|
630
|
+
avatar?: string | null;
|
|
631
|
+
availability: 'online' | 'away' | 'busy' | 'offline' | string;
|
|
632
|
+
messages: number;
|
|
633
|
+
assigned: number;
|
|
634
|
+
resolved: number;
|
|
635
|
+
resolutionRate: number;
|
|
636
|
+
avgRating: number | null;
|
|
637
|
+
}
|
|
638
|
+
/** An agent in {@link AnalyticsInsights}: the usual stats plus first-response time. */
|
|
639
|
+
interface AgentInsight extends AgentStat {
|
|
640
|
+
/** Average time to this agent's first reply on conversations they answered first; null when there are none. */
|
|
641
|
+
firstResponseSeconds: number | null;
|
|
642
|
+
}
|
|
643
|
+
interface QuestionInsight {
|
|
644
|
+
/** The wording customers used most. */
|
|
645
|
+
question: string;
|
|
646
|
+
asked: number;
|
|
647
|
+
/** Share of these conversations the AI handled without a person stepping in. */
|
|
648
|
+
aiResolvedPct: number;
|
|
649
|
+
/** Average customer rating (1-5) of these conversations; null when none were rated. */
|
|
650
|
+
avgRating: number | null;
|
|
651
|
+
/** The page most of them started on. */
|
|
652
|
+
page: string | null;
|
|
653
|
+
/** % change in how often it was asked vs the previous period; null when it is new. */
|
|
654
|
+
trendPct: number | null;
|
|
655
|
+
}
|
|
656
|
+
/** The deeper numbers behind the dashboard's Analytics page. */
|
|
657
|
+
interface AnalyticsInsights {
|
|
658
|
+
period: {
|
|
659
|
+
days: number;
|
|
660
|
+
since: string;
|
|
661
|
+
};
|
|
662
|
+
/** Median time from a customer's first message to a person's first reply. `deltaPct` is vs the previous period (negative = faster). */
|
|
663
|
+
firstResponse: {
|
|
664
|
+
medianSeconds: number | null;
|
|
665
|
+
deltaPct: number | null;
|
|
666
|
+
sample: number;
|
|
667
|
+
};
|
|
668
|
+
agents: AgentInsight[];
|
|
669
|
+
channels: {
|
|
670
|
+
channel: string;
|
|
671
|
+
count: number;
|
|
672
|
+
pct: number;
|
|
673
|
+
firstResponseSeconds: number | null;
|
|
674
|
+
avgRating: number | null;
|
|
675
|
+
}[];
|
|
676
|
+
ai: {
|
|
677
|
+
csatOnAiChats: {
|
|
678
|
+
avg: number | null;
|
|
679
|
+
count: number;
|
|
680
|
+
};
|
|
681
|
+
/** The most frequently asked questions (top 20), grouped by wording. */
|
|
682
|
+
questions: QuestionInsight[];
|
|
683
|
+
/** Questions handed to a person because nothing in the knowledge base matched. */
|
|
684
|
+
unanswered: {
|
|
685
|
+
question: string;
|
|
686
|
+
count: number;
|
|
687
|
+
}[];
|
|
688
|
+
outcomes: {
|
|
689
|
+
resolvedByAi: number;
|
|
690
|
+
handedOff: number;
|
|
691
|
+
other: number;
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
customers: {
|
|
695
|
+
active: number;
|
|
696
|
+
new: number;
|
|
697
|
+
returning: number;
|
|
698
|
+
perCustomer: number | null;
|
|
699
|
+
deltas: {
|
|
700
|
+
active: number | null;
|
|
701
|
+
new: number | null;
|
|
702
|
+
returning: number | null;
|
|
703
|
+
};
|
|
704
|
+
/** One row per star, 5 first. */
|
|
705
|
+
csat: {
|
|
706
|
+
stars: number;
|
|
707
|
+
count: number;
|
|
708
|
+
pct: number;
|
|
709
|
+
}[];
|
|
710
|
+
csatResponses: number;
|
|
711
|
+
countries: {
|
|
712
|
+
country: string;
|
|
713
|
+
count: number;
|
|
714
|
+
}[];
|
|
715
|
+
newPct: number;
|
|
716
|
+
returningPct: number;
|
|
717
|
+
top: {
|
|
718
|
+
id: number;
|
|
719
|
+
name: string;
|
|
720
|
+
company: string | null;
|
|
721
|
+
conversations: number;
|
|
722
|
+
lastSeenAt: string | null;
|
|
723
|
+
avgRating: number | null;
|
|
724
|
+
}[];
|
|
725
|
+
/** Customer messages by weekday (Monday first) and two-hour block (0, 2, … 22), in the organisation's timezone. */
|
|
726
|
+
heatmap: {
|
|
727
|
+
days: string[];
|
|
728
|
+
cells: number[][];
|
|
729
|
+
timezone: string;
|
|
730
|
+
};
|
|
731
|
+
};
|
|
732
|
+
/** Pages that start the most conversations. `askRate` is null until the page has recorded views. */
|
|
733
|
+
pages: {
|
|
734
|
+
page: string;
|
|
735
|
+
views: number;
|
|
736
|
+
questions: number;
|
|
737
|
+
askRate: number | null;
|
|
738
|
+
topQuestion: string | null;
|
|
739
|
+
}[];
|
|
740
|
+
}
|
|
741
|
+
/** Open tickets by priority and how many are still inside their SLA. */
|
|
742
|
+
interface TicketSla {
|
|
743
|
+
total: number;
|
|
744
|
+
withinSlaPct: number;
|
|
745
|
+
byPriority: {
|
|
746
|
+
priority: 'URGENT' | 'HIGH' | 'NORMAL' | 'LOW';
|
|
747
|
+
count: number;
|
|
748
|
+
oldestMinutes: number | null;
|
|
749
|
+
}[];
|
|
750
|
+
}
|
|
751
|
+
/** Which first-run steps are done. */
|
|
752
|
+
interface SetupStatus {
|
|
753
|
+
channel: boolean;
|
|
754
|
+
ai: boolean;
|
|
755
|
+
automation: boolean;
|
|
756
|
+
}
|
|
757
|
+
interface WebhookPayload<T = any> {
|
|
758
|
+
event: WebhookEvent;
|
|
759
|
+
orgId: number;
|
|
760
|
+
timestamp: string;
|
|
761
|
+
data: T;
|
|
762
|
+
}
|
|
763
|
+
type AiToolMethod = 'GET' | 'POST' | 'PUT' | 'PATCH';
|
|
764
|
+
type AiToolAuthType = 'none' | 'bearer' | 'api_key' | 'basic';
|
|
765
|
+
interface AiToolParameter {
|
|
766
|
+
/** Letters, numbers and underscores. */
|
|
767
|
+
name: string;
|
|
768
|
+
type: 'string' | 'number' | 'boolean';
|
|
769
|
+
/** What the AI should put here, e.g. "Product SKU the customer mentioned". */
|
|
770
|
+
description?: string;
|
|
771
|
+
/** Default `true`: the AI collects it before calling your API. */
|
|
772
|
+
required?: boolean;
|
|
773
|
+
}
|
|
774
|
+
interface AiToolUsage {
|
|
775
|
+
/** Calls in the last 30 days. */
|
|
776
|
+
calls: number;
|
|
777
|
+
/** Calls that failed (error or HTTP 4xx/5xx) in the last 30 days. */
|
|
778
|
+
failures: number;
|
|
779
|
+
lastUsedAt: string | null;
|
|
780
|
+
}
|
|
781
|
+
interface AiTool {
|
|
782
|
+
id: number;
|
|
783
|
+
/** The snake_case function name the AI calls. */
|
|
784
|
+
name: string;
|
|
785
|
+
displayName: string;
|
|
786
|
+
/** The AI reads this to decide when to call the tool. */
|
|
787
|
+
description: string;
|
|
788
|
+
parameters: Required<AiToolParameter>[];
|
|
789
|
+
endpoint: string;
|
|
790
|
+
method: AiToolMethod;
|
|
791
|
+
authType: AiToolAuthType;
|
|
792
|
+
/** Dot-notation path into the JSON response; null = the whole response. */
|
|
793
|
+
responsePath: string | null;
|
|
794
|
+
enabled: boolean;
|
|
795
|
+
createdAt: string;
|
|
796
|
+
updatedAt: string;
|
|
797
|
+
usage: AiToolUsage;
|
|
798
|
+
}
|
|
799
|
+
/** One tool as returned by `get`: secrets are never returned, `hasSecret` says whether one is stored. */
|
|
800
|
+
interface AiToolDetail extends Omit<AiTool, 'usage'> {
|
|
801
|
+
/** Names and headers only; secret values come back empty. */
|
|
802
|
+
authConfig: Record<string, string> | null;
|
|
803
|
+
headers: Record<string, string> | null;
|
|
804
|
+
hasSecret: boolean;
|
|
805
|
+
}
|
|
806
|
+
interface AiToolStats {
|
|
807
|
+
total: number;
|
|
808
|
+
active: number;
|
|
809
|
+
/** Calls in the last 30 days. */
|
|
810
|
+
calls: number;
|
|
811
|
+
/** Percent of calls that succeeded; null when there were none. */
|
|
812
|
+
successRate: number | null;
|
|
813
|
+
/** How many tools your plan allows: -1 = not on your plan, 0 = unlimited. */
|
|
814
|
+
limit: number;
|
|
815
|
+
}
|
|
816
|
+
interface CreateAiToolParams {
|
|
817
|
+
/** snake_case, unique in your organisation. */
|
|
818
|
+
name: string;
|
|
819
|
+
displayName: string;
|
|
820
|
+
/** 10-500 characters. Say when the AI should use the tool. */
|
|
821
|
+
description: string;
|
|
822
|
+
parameters?: AiToolParameter[];
|
|
823
|
+
/** A public https:// or http:// address. Private and local addresses are rejected. */
|
|
824
|
+
endpoint: string;
|
|
825
|
+
/** Default `POST`. GET sends parameters in the query string, the others as a JSON body. */
|
|
826
|
+
method?: AiToolMethod;
|
|
827
|
+
/** Default `none`. */
|
|
828
|
+
authType?: AiToolAuthType;
|
|
829
|
+
/** bearer: `{ token }` | api_key: `{ header, value }` | basic: `{ username, password }`. Write-only. */
|
|
830
|
+
authConfig?: Record<string, string>;
|
|
831
|
+
/** Extra static headers sent on every call (10 at most). */
|
|
832
|
+
headers?: Record<string, string>;
|
|
833
|
+
responsePath?: string;
|
|
834
|
+
/** Default `true`. */
|
|
835
|
+
enabled?: boolean;
|
|
836
|
+
}
|
|
837
|
+
/** Send only what you want to change. Leave a secret out of `authConfig` to keep the stored one. */
|
|
838
|
+
type UpdateAiToolParams = Partial<CreateAiToolParams>;
|
|
839
|
+
interface AiToolTestResult {
|
|
840
|
+
success: boolean;
|
|
841
|
+
/** What the AI would see, when the call succeeded. */
|
|
842
|
+
result?: string;
|
|
843
|
+
error?: string;
|
|
844
|
+
statusCode?: number;
|
|
845
|
+
durationMs: number;
|
|
846
|
+
}
|
|
847
|
+
interface McpServerTool {
|
|
848
|
+
name: string;
|
|
849
|
+
description: string;
|
|
850
|
+
/** The tool's input as JSON Schema. */
|
|
851
|
+
inputSchema: Record<string, unknown>;
|
|
852
|
+
}
|
|
853
|
+
interface McpServer {
|
|
854
|
+
id: number;
|
|
855
|
+
name: string;
|
|
856
|
+
/** What the server is for and when the chatbot should use it. */
|
|
857
|
+
description: string;
|
|
858
|
+
url: string;
|
|
859
|
+
authType: 'none' | 'bearer' | 'api_key';
|
|
860
|
+
/** Header names and the like; secret values come back empty. */
|
|
861
|
+
authConfig: Record<string, string> | null;
|
|
862
|
+
/** Whether a secret is stored. */
|
|
863
|
+
hasSecret: boolean;
|
|
864
|
+
/** `false` disconnects the whole server from the chatbot. */
|
|
865
|
+
enabled: boolean;
|
|
866
|
+
/** What the server offered at the last sync. */
|
|
867
|
+
tools: McpServerTool[];
|
|
868
|
+
/** Names of the tools the chatbot may use. */
|
|
869
|
+
enabledTools: string[];
|
|
870
|
+
lastSyncedAt: string | null;
|
|
871
|
+
/** Why the last sync failed, if it did. */
|
|
872
|
+
lastError: string | null;
|
|
873
|
+
/** Calls the chatbot made to this server, and how many failed. */
|
|
874
|
+
callCount: number;
|
|
875
|
+
failureCount: number;
|
|
876
|
+
createdAt: string;
|
|
877
|
+
}
|
|
878
|
+
interface CreateMcpServerParams {
|
|
879
|
+
name: string;
|
|
880
|
+
/**
|
|
881
|
+
* 10-300 characters: what this server is for and when the chatbot should use it, e.g.
|
|
882
|
+
* "Order and stock lookups for our shop. Use when a customer asks about an order or an item."
|
|
883
|
+
* The chatbot reads it with each of the server's tools to choose the right one.
|
|
884
|
+
*/
|
|
885
|
+
description: string;
|
|
886
|
+
/** The server's Streamable HTTP endpoint, a public address. */
|
|
887
|
+
url: string;
|
|
888
|
+
authType?: 'none' | 'bearer' | 'api_key';
|
|
889
|
+
/** bearer: `{ token }` | api_key: `{ header, value }`. Write-only. */
|
|
890
|
+
authConfig?: Record<string, string>;
|
|
891
|
+
}
|
|
892
|
+
interface UpdateMcpServerParams {
|
|
893
|
+
name?: string;
|
|
894
|
+
description?: string;
|
|
895
|
+
enabled?: boolean;
|
|
896
|
+
/** Tool names to switch on (the rest are switched off). Counts against your plan's AI tool limit. */
|
|
897
|
+
enabledTools?: string[];
|
|
898
|
+
authType?: 'none' | 'bearer' | 'api_key';
|
|
899
|
+
/** Leave a secret out to keep the stored one. */
|
|
900
|
+
authConfig?: Record<string, string>;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
declare class HttpError extends Error {
|
|
904
|
+
readonly status: number;
|
|
905
|
+
readonly body?: unknown | undefined;
|
|
906
|
+
constructor(status: number, message: string, body?: unknown | undefined);
|
|
907
|
+
}
|
|
908
|
+
interface RequestOptions {
|
|
909
|
+
method?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
910
|
+
path: string;
|
|
911
|
+
params?: Record<string, string | number | undefined>;
|
|
912
|
+
body?: unknown;
|
|
913
|
+
}
|
|
914
|
+
declare class HttpClient {
|
|
915
|
+
private baseUrl;
|
|
916
|
+
private apiKey;
|
|
917
|
+
private orgId?;
|
|
918
|
+
private timeout;
|
|
919
|
+
constructor(baseUrl: string, apiKey: string, orgId?: string, timeout?: number);
|
|
920
|
+
request<T>(opts: RequestOptions): Promise<T>;
|
|
921
|
+
get<T>(path: string, params?: RequestOptions['params']): Promise<T>;
|
|
922
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
923
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
924
|
+
delete<T>(path: string): Promise<T>;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
declare class ConversationsResource {
|
|
928
|
+
private readonly http;
|
|
929
|
+
constructor(http: HttpClient);
|
|
930
|
+
list(params?: ListConversationsParams): Promise<{
|
|
931
|
+
data: Conversation[];
|
|
932
|
+
meta: PaginationMeta;
|
|
933
|
+
}>;
|
|
934
|
+
get(id: number): Promise<Conversation>;
|
|
935
|
+
create(params: CreateConversationParams): Promise<Conversation>;
|
|
936
|
+
update(id: number, params: UpdateConversationParams): Promise<Conversation>;
|
|
937
|
+
resolve(id: number): Promise<Conversation>;
|
|
938
|
+
close(id: number): Promise<Conversation>;
|
|
939
|
+
assign(id: number, agentId: number): Promise<Conversation>;
|
|
940
|
+
/** The same customer's earlier conversations, newest first (default 5, max 20). */
|
|
941
|
+
getHistory(id: number, limit?: number): Promise<{
|
|
942
|
+
data: PreviousConversation[];
|
|
943
|
+
}>;
|
|
944
|
+
/**
|
|
945
|
+
* Hand a conversation from the AI assistant to a human: stops the bot and
|
|
946
|
+
* assigns `agentId` (a team-member id) if nobody holds it yet. Fails with
|
|
947
|
+
* 400 if the AI is no longer handling it.
|
|
948
|
+
*/
|
|
949
|
+
takeOver(id: number, params: TakeOverParams): Promise<{
|
|
950
|
+
success: boolean;
|
|
951
|
+
conversationId: number;
|
|
952
|
+
}>;
|
|
953
|
+
getMessages(id: number, params?: ListMessagesParams): Promise<{
|
|
954
|
+
data: Message[];
|
|
955
|
+
meta: {
|
|
956
|
+
hasMore: boolean;
|
|
957
|
+
nextCursor?: string;
|
|
958
|
+
};
|
|
959
|
+
}>;
|
|
960
|
+
sendMessage(id: number, params: SendMessageParams): Promise<Message>;
|
|
961
|
+
delete(id: number): Promise<void>;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
declare class CustomersResource {
|
|
965
|
+
private readonly http;
|
|
966
|
+
constructor(http: HttpClient);
|
|
967
|
+
list(params?: {
|
|
968
|
+
search?: string;
|
|
969
|
+
page?: number;
|
|
970
|
+
limit?: number;
|
|
971
|
+
}): Promise<{
|
|
972
|
+
data: Customer[];
|
|
973
|
+
meta: PaginationMeta;
|
|
974
|
+
}>;
|
|
975
|
+
get(id: number): Promise<Customer>;
|
|
976
|
+
upsert(params: UpsertCustomerParams): Promise<Customer>;
|
|
977
|
+
update(id: number, params: Partial<UpsertCustomerParams>): Promise<Customer>;
|
|
978
|
+
getConversations(id: number): Promise<{
|
|
979
|
+
data: Conversation[];
|
|
980
|
+
}>;
|
|
981
|
+
delete(id: number): Promise<void>;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
declare class VisitorsResource {
|
|
985
|
+
private readonly http;
|
|
986
|
+
constructor(http: HttpClient);
|
|
987
|
+
/** Visitors from the last few days (online and offline) with visit counts and block/allow status. */
|
|
988
|
+
list(params?: ListVisitorsParams): Promise<{
|
|
989
|
+
data: Visitor[];
|
|
990
|
+
meta: PaginationMeta & {
|
|
991
|
+
truncated: boolean;
|
|
992
|
+
};
|
|
993
|
+
}>;
|
|
994
|
+
/** Visitors on the site right now. */
|
|
995
|
+
getActive(): Promise<{
|
|
996
|
+
data: Visitor[];
|
|
997
|
+
}>;
|
|
998
|
+
/** Online now, countries and returning visitors (24h), active IP blocks, top countries. */
|
|
999
|
+
getOverview(): Promise<VisitorsOverview>;
|
|
1000
|
+
/**
|
|
1001
|
+
* CSV of the visitors matching the filters (max 5,000). Requires a plan with
|
|
1002
|
+
* data exports (Pro and above) — otherwise throws an HttpError with status 403.
|
|
1003
|
+
*/
|
|
1004
|
+
export(params?: Omit<ListVisitorsParams, 'page' | 'limit'>): Promise<VisitorsExport>;
|
|
1005
|
+
getPages(sessionId: string): Promise<{
|
|
1006
|
+
data: {
|
|
1007
|
+
url: string;
|
|
1008
|
+
title: string;
|
|
1009
|
+
visitedAt: string;
|
|
1010
|
+
}[];
|
|
1011
|
+
}>;
|
|
1012
|
+
block(sessionId: string, params?: BlockVisitorParams): Promise<{
|
|
1013
|
+
success: boolean;
|
|
1014
|
+
}>;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
declare class AgentsResource {
|
|
1018
|
+
private readonly http;
|
|
1019
|
+
constructor(http: HttpClient);
|
|
1020
|
+
list(): Promise<{
|
|
1021
|
+
data: Agent[];
|
|
1022
|
+
}>;
|
|
1023
|
+
getOnline(): Promise<{
|
|
1024
|
+
data: {
|
|
1025
|
+
agentId: number;
|
|
1026
|
+
name: string;
|
|
1027
|
+
status: string;
|
|
1028
|
+
}[];
|
|
1029
|
+
}>;
|
|
1030
|
+
invite(params: InviteAgentParams): Promise<{
|
|
1031
|
+
success: boolean;
|
|
1032
|
+
message: string;
|
|
1033
|
+
}>;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
declare class KnowledgeBaseResource {
|
|
1037
|
+
private readonly http;
|
|
1038
|
+
constructor(http: HttpClient);
|
|
1039
|
+
list(params?: {
|
|
1040
|
+
search?: string;
|
|
1041
|
+
category?: string;
|
|
1042
|
+
page?: number;
|
|
1043
|
+
limit?: number;
|
|
1044
|
+
}): Promise<{
|
|
1045
|
+
data: KbArticle[];
|
|
1046
|
+
meta: PaginationMeta;
|
|
1047
|
+
}>;
|
|
1048
|
+
/** Totals and the categories in use. */
|
|
1049
|
+
getStats(): Promise<KbStats>;
|
|
1050
|
+
/** What to write or fix next: most viewed, unanswered customer questions, lowest rated, and stale articles. */
|
|
1051
|
+
getInsights(): Promise<KbInsights>;
|
|
1052
|
+
get(id: number): Promise<KbArticle>;
|
|
1053
|
+
search(query: string): Promise<{
|
|
1054
|
+
data: KbArticle[];
|
|
1055
|
+
}>;
|
|
1056
|
+
createArticle(params: CreateArticleParams): Promise<KbArticle>;
|
|
1057
|
+
updateArticle(id: number, params: Partial<CreateArticleParams>): Promise<KbArticle>;
|
|
1058
|
+
deleteArticle(id: number): Promise<void>;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
declare class WebhooksResource {
|
|
1062
|
+
private readonly http;
|
|
1063
|
+
constructor(http: HttpClient);
|
|
1064
|
+
list(): Promise<{
|
|
1065
|
+
data: Webhook[];
|
|
1066
|
+
}>;
|
|
1067
|
+
get(id: number): Promise<Webhook>;
|
|
1068
|
+
create(params: CreateWebhookParams): Promise<Webhook>;
|
|
1069
|
+
update(id: number, params: Partial<CreateWebhookParams & {
|
|
1070
|
+
isActive: boolean;
|
|
1071
|
+
}>): Promise<Webhook>;
|
|
1072
|
+
delete(id: number): Promise<void>;
|
|
1073
|
+
/**
|
|
1074
|
+
* Verify an incoming webhook signature.
|
|
1075
|
+
* The signature header is `X-Kerabie-Signature`.
|
|
1076
|
+
*/
|
|
1077
|
+
static verify(rawBody: string, signature: string, secret: string): boolean;
|
|
1078
|
+
/**
|
|
1079
|
+
* Parse a verified webhook payload with full TypeScript types.
|
|
1080
|
+
*/
|
|
1081
|
+
static parse<T = any>(rawBody: string): WebhookPayload<T>;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
declare class AnalyticsResource {
|
|
1085
|
+
private readonly http;
|
|
1086
|
+
constructor(http: HttpClient);
|
|
1087
|
+
/** Conversation, response-time, satisfaction and AI numbers for the last `days` days (default 30), with deltas vs the previous period. */
|
|
1088
|
+
getSummary(params?: AnalyticsParams): Promise<AnalyticsSummary>;
|
|
1089
|
+
getAgentStats(params?: AnalyticsParams): Promise<{
|
|
1090
|
+
agents: AgentStat[];
|
|
1091
|
+
}>;
|
|
1092
|
+
/**
|
|
1093
|
+
* The deeper numbers: first-response times, per-agent and per-channel results, the questions customers ask,
|
|
1094
|
+
* who they are, when they write in, and which pages start conversations.
|
|
1095
|
+
*/
|
|
1096
|
+
getInsights(params?: AnalyticsParams): Promise<AnalyticsInsights>;
|
|
1097
|
+
/** Open tickets by priority, and the percentage still within their SLA. */
|
|
1098
|
+
getTicketSla(): Promise<TicketSla>;
|
|
1099
|
+
/** Which of the first-run steps (connect a channel, train the AI, create an automation) are done. */
|
|
1100
|
+
getSetupStatus(): Promise<SetupStatus>;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
declare class StoreResource {
|
|
1104
|
+
private readonly http;
|
|
1105
|
+
constructor(http: HttpClient);
|
|
1106
|
+
list(params?: {
|
|
1107
|
+
page?: number;
|
|
1108
|
+
limit?: number;
|
|
1109
|
+
}): Promise<{
|
|
1110
|
+
data: StoreProduct[];
|
|
1111
|
+
meta: PaginationMeta;
|
|
1112
|
+
}>;
|
|
1113
|
+
get(id: number): Promise<StoreProduct>;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
declare class TicketsResource {
|
|
1117
|
+
private readonly http;
|
|
1118
|
+
constructor(http: HttpClient);
|
|
1119
|
+
list(params?: {
|
|
1120
|
+
status?: string;
|
|
1121
|
+
priority?: string;
|
|
1122
|
+
page?: number;
|
|
1123
|
+
limit?: number;
|
|
1124
|
+
}): Promise<{
|
|
1125
|
+
data: Ticket[];
|
|
1126
|
+
meta: PaginationMeta;
|
|
1127
|
+
}>;
|
|
1128
|
+
/** Open, unassigned and SLA-breaching counts plus the 7-day average resolution time and its change. */
|
|
1129
|
+
getStats(): Promise<TicketStats>;
|
|
1130
|
+
/**
|
|
1131
|
+
* CSV of tickets matching the filters (max 5,000). Requires a plan with
|
|
1132
|
+
* data exports (Pro and above) — otherwise throws an HttpError with status 403.
|
|
1133
|
+
*/
|
|
1134
|
+
export(params?: ExportTicketsParams): Promise<TicketExport>;
|
|
1135
|
+
get(id: number): Promise<Ticket & {
|
|
1136
|
+
messages: TicketMessage[];
|
|
1137
|
+
}>;
|
|
1138
|
+
create(params: CreateTicketParams): Promise<{
|
|
1139
|
+
ticketId: number;
|
|
1140
|
+
message: TicketMessage;
|
|
1141
|
+
}>;
|
|
1142
|
+
update(id: number, params: UpdateTicketParams): Promise<Ticket>;
|
|
1143
|
+
resolve(id: number): Promise<Ticket>;
|
|
1144
|
+
close(id: number): Promise<Ticket>;
|
|
1145
|
+
reply(id: number, message: string): Promise<TicketMessage>;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
declare class ContactsResource {
|
|
1149
|
+
private readonly http;
|
|
1150
|
+
constructor(http: HttpClient);
|
|
1151
|
+
/** People with a name, email or phone number, last-contacted first. */
|
|
1152
|
+
list(params?: ListContactsParams): Promise<{
|
|
1153
|
+
contacts: Contact[];
|
|
1154
|
+
meta: PaginationMeta;
|
|
1155
|
+
}>;
|
|
1156
|
+
/** Totals for the overview: everyone, new this week, leads, VIPs. */
|
|
1157
|
+
getStats(): Promise<ContactStats>;
|
|
1158
|
+
get(id: number): Promise<Contact>;
|
|
1159
|
+
/** Adds a contact. Needs a name, email or phone. Throws an HttpError with status 409 if the email is already saved. */
|
|
1160
|
+
create(params: CreateContactParams): Promise<{
|
|
1161
|
+
contact: Contact;
|
|
1162
|
+
}>;
|
|
1163
|
+
update(id: number, params: UpdateContactParams): Promise<{
|
|
1164
|
+
success: boolean;
|
|
1165
|
+
}>;
|
|
1166
|
+
/**
|
|
1167
|
+
* Imports up to 1,000 contacts per call. Rows whose email is already saved are skipped;
|
|
1168
|
+
* invalid rows are reported with their number instead of failing the whole import.
|
|
1169
|
+
*/
|
|
1170
|
+
import(rows: ImportContactRow[]): Promise<ImportContactsResult>;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
declare class CampaignsResource {
|
|
1174
|
+
private readonly http;
|
|
1175
|
+
constructor(http: HttpClient);
|
|
1176
|
+
/** Proactive messages shown on your chat widget, newest first. */
|
|
1177
|
+
list(params?: ListCampaignsParams): Promise<{
|
|
1178
|
+
campaigns: Campaign[];
|
|
1179
|
+
meta: PaginationMeta;
|
|
1180
|
+
}>;
|
|
1181
|
+
/** Totals and funnel numbers, plus how many campaigns your plan lets you run at once. */
|
|
1182
|
+
getStats(): Promise<CampaignStats>;
|
|
1183
|
+
get(id: number): Promise<Campaign>;
|
|
1184
|
+
/**
|
|
1185
|
+
* Saves a draft, or launches it with `isActive: true`.
|
|
1186
|
+
* Throws an HttpError with status 403 when launching would exceed your plan's live-campaign limit.
|
|
1187
|
+
*/
|
|
1188
|
+
create(params: CreateCampaignParams): Promise<{
|
|
1189
|
+
campaign: Campaign;
|
|
1190
|
+
}>;
|
|
1191
|
+
/** Edits fields and/or turns it on or off with `isActive`. Send only what you want to change. */
|
|
1192
|
+
update(id: number, params: UpdateCampaignParams): Promise<{
|
|
1193
|
+
success: boolean;
|
|
1194
|
+
}>;
|
|
1195
|
+
/** A copy saved as a draft, with fresh results. */
|
|
1196
|
+
duplicate(id: number): Promise<{
|
|
1197
|
+
campaign: Campaign;
|
|
1198
|
+
}>;
|
|
1199
|
+
delete(id: number): Promise<{
|
|
1200
|
+
success: boolean;
|
|
1201
|
+
}>;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
declare class AiToolsResource {
|
|
1205
|
+
private readonly http;
|
|
1206
|
+
constructor(http: HttpClient);
|
|
1207
|
+
/** Your AI agent tools (custom API actions the chatbot can call), with 30-day usage and your plan's limit. */
|
|
1208
|
+
list(): Promise<{
|
|
1209
|
+
tools: AiTool[];
|
|
1210
|
+
stats: AiToolStats;
|
|
1211
|
+
}>;
|
|
1212
|
+
/** One tool. Secrets are never returned. */
|
|
1213
|
+
get(id: number): Promise<AiToolDetail>;
|
|
1214
|
+
/**
|
|
1215
|
+
* Adds a tool. Throws an HttpError with status 403 when your plan has no room for another,
|
|
1216
|
+
* 409 when the function name is taken, and 400 for a private or local endpoint.
|
|
1217
|
+
*/
|
|
1218
|
+
create(params: CreateAiToolParams): Promise<{
|
|
1219
|
+
tool: {
|
|
1220
|
+
id: number;
|
|
1221
|
+
};
|
|
1222
|
+
}>;
|
|
1223
|
+
/** Edits fields and/or switches the tool on or off with `enabled`. Send only what you want to change. */
|
|
1224
|
+
update(id: number, params: UpdateAiToolParams): Promise<{
|
|
1225
|
+
tool: {
|
|
1226
|
+
id: number;
|
|
1227
|
+
};
|
|
1228
|
+
}>;
|
|
1229
|
+
/** A copy that starts switched off. Counts against your plan's tool limit. */
|
|
1230
|
+
duplicate(id: number): Promise<{
|
|
1231
|
+
tool: {
|
|
1232
|
+
id: number;
|
|
1233
|
+
};
|
|
1234
|
+
}>;
|
|
1235
|
+
delete(id: number): Promise<{
|
|
1236
|
+
success: boolean;
|
|
1237
|
+
}>;
|
|
1238
|
+
/** Calls the tool's real endpoint once with `args`, the way the AI would. Not counted as usage. Limited to 40 a hour. */
|
|
1239
|
+
test(id: number, args?: Record<string, unknown>): Promise<AiToolTestResult>;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
/** Remote MCP servers whose tools your AI chatbot can call, next to your own AI tools. */
|
|
1243
|
+
declare class McpServersResource {
|
|
1244
|
+
private readonly http;
|
|
1245
|
+
constructor(http: HttpClient);
|
|
1246
|
+
/** Connected servers, with the tools each offers and which are switched on. */
|
|
1247
|
+
list(): Promise<{
|
|
1248
|
+
servers: McpServer[];
|
|
1249
|
+
limit: number;
|
|
1250
|
+
}>;
|
|
1251
|
+
/**
|
|
1252
|
+
* Connects a server and reads its tools. No tool is switched on yet: use `update` with `enabledTools`.
|
|
1253
|
+
* Throws an HttpError with status 400 when the server can't be reached, 403 when your plan has no AI tools,
|
|
1254
|
+
* and 409 when it is already connected.
|
|
1255
|
+
*/
|
|
1256
|
+
create(params: CreateMcpServerParams): Promise<{
|
|
1257
|
+
server: McpServer;
|
|
1258
|
+
}>;
|
|
1259
|
+
/** Reads the server's tools again. Switched-on tools the server no longer offers are dropped. */
|
|
1260
|
+
sync(id: number): Promise<{
|
|
1261
|
+
server: McpServer;
|
|
1262
|
+
}>;
|
|
1263
|
+
/** Renames, switches the server on or off, changes which tools the chatbot may use, or updates credentials. */
|
|
1264
|
+
update(id: number, params: UpdateMcpServerParams): Promise<{
|
|
1265
|
+
server: McpServer;
|
|
1266
|
+
}>;
|
|
1267
|
+
delete(id: number): Promise<{
|
|
1268
|
+
success: boolean;
|
|
1269
|
+
}>;
|
|
1270
|
+
/** Runs one of the server's tools once with `args`, the way the chatbot would. Limited to 40 a hour. */
|
|
1271
|
+
test(id: number, tool: string, args?: Record<string, unknown>): Promise<AiToolTestResult>;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
declare class KerAbieClient {
|
|
1275
|
+
readonly conversations: ConversationsResource;
|
|
1276
|
+
readonly customers: CustomersResource;
|
|
1277
|
+
readonly visitors: VisitorsResource;
|
|
1278
|
+
readonly agents: AgentsResource;
|
|
1279
|
+
readonly kb: KnowledgeBaseResource;
|
|
1280
|
+
readonly webhooks: WebhooksResource;
|
|
1281
|
+
readonly analytics: AnalyticsResource;
|
|
1282
|
+
readonly store: StoreResource;
|
|
1283
|
+
readonly tickets: TicketsResource;
|
|
1284
|
+
readonly contacts: ContactsResource;
|
|
1285
|
+
readonly campaigns: CampaignsResource;
|
|
1286
|
+
readonly aiTools: AiToolsResource;
|
|
1287
|
+
readonly mcpServers: McpServersResource;
|
|
1288
|
+
private readonly http;
|
|
1289
|
+
constructor(config: KerAbieClientConfig);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
export { type Agent, type AgentInsight, type AgentStat, type AiTool, type AiToolAuthType, type AiToolDetail, type AiToolMethod, type AiToolParameter, type AiToolStats, type AiToolTestResult, type AiToolUsage, type AnalyticsInsights, type AnalyticsParams, type AnalyticsSummary, type Attachment, type BlockVisitorParams, type Campaign, type CampaignAction, type CampaignAudience, type CampaignFrequency, type CampaignStats, type CampaignStatus, type CampaignTrigger, type Contact, type ContactStats, type ContactType, type Conversation, type ConversationChannel, type ConversationCounts, type ConversationStatus, type CreateAiToolParams, type CreateArticleParams, type CreateCampaignParams, type CreateContactParams, type CreateConversationParams, type CreateMcpServerParams, type CreateTicketParams, type CreateWebhookParams, type Customer, type ExportTicketsParams, HttpError, type ImportContactRow, type ImportContactsResult, type InviteAgentParams, type KbArticle, type KbInsights, type KbStats, KerAbieClient, type KerAbieClientConfig, type ListCampaignsParams, type ListContactsParams, type ListConversationsParams, type ListMessagesParams, type ListVisitorsParams, type McpServer, type McpServerTool, type Message, type MessageType, type PaginationMeta, type PreviousConversation, type QuestionInsight, type SendMessageParams, type SenderType, type SetupStatus, type StoreProduct, StoreResource, type TakeOverParams, type Ticket, type TicketExport, type TicketMessage, type TicketPriority, type TicketSla, type TicketStats, type UpdateAiToolParams, type UpdateCampaignParams, type UpdateContactParams, type UpdateConversationParams, type UpdateMcpServerParams, type UpdateTicketParams, type UpsertCustomerParams, type Visitor, type VisitorStatus, type VisitorsExport, type VisitorsOverview, type Webhook, type WebhookEvent, type WebhookPayload, WebhooksResource };
|