@graph8/sdk 0.3.0 → 0.5.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/dist/index.d.mts +2089 -13
- package/dist/index.d.ts +2089 -13
- package/dist/index.js +1166 -95
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1166 -95
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +2067 -18
- package/dist/react.d.ts +2067 -18
- package/dist/react.js +1166 -95
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1166 -95
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -328,18 +328,133 @@ var DEFAULT_API7 = "https://be.graph8.com";
|
|
|
328
328
|
var createSequencesClient = (apiKey, apiUrl) => {
|
|
329
329
|
const baseUrl = apiUrl || DEFAULT_API7;
|
|
330
330
|
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
331
|
+
const toQuery = (params) => {
|
|
332
|
+
const qs = new URLSearchParams();
|
|
333
|
+
for (const [k, v] of Object.entries(params)) {
|
|
334
|
+
if (v != null) qs.set(k, String(v));
|
|
335
|
+
}
|
|
336
|
+
const s = qs.toString();
|
|
337
|
+
return s ? `?${s}` : "";
|
|
338
|
+
};
|
|
339
|
+
async function list(pageOrParams, limit) {
|
|
340
|
+
let params;
|
|
341
|
+
if (typeof pageOrParams === "number") {
|
|
342
|
+
params = { page: pageOrParams, limit: limit ?? 50 };
|
|
343
|
+
} else {
|
|
344
|
+
params = pageOrParams ?? {};
|
|
345
|
+
}
|
|
346
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences${toQuery(params)}`, { headers: headers() });
|
|
347
|
+
const data = await resp.json();
|
|
348
|
+
return data.data || data;
|
|
349
|
+
}
|
|
331
350
|
return {
|
|
332
|
-
|
|
333
|
-
|
|
351
|
+
/** List sequences with pagination + optional status filter. */
|
|
352
|
+
list,
|
|
353
|
+
/** Get full sequence details by ID. */
|
|
354
|
+
async get(sequenceId) {
|
|
355
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, { headers: headers() });
|
|
334
356
|
const data = await resp.json();
|
|
335
357
|
return data.data || data;
|
|
336
358
|
},
|
|
359
|
+
/** List contacts enrolled in a sequence. Filter by state (e.g. "active", "replied"). */
|
|
360
|
+
async contacts(sequenceId, params = {}) {
|
|
361
|
+
const resp = await fetch(
|
|
362
|
+
`${baseUrl}/api/v1/sequences/${sequenceId}/contacts${toQuery(params)}`,
|
|
363
|
+
{ headers: headers() }
|
|
364
|
+
);
|
|
365
|
+
return resp.json();
|
|
366
|
+
},
|
|
367
|
+
/** Add contacts to a sequence (V2 queuing). Live or drafted sequences only. */
|
|
337
368
|
async add(config) {
|
|
338
|
-
await fetch(`${baseUrl}/api/v1/sequences/${config.sequenceId}/contacts`, {
|
|
369
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${config.sequenceId}/contacts`, {
|
|
339
370
|
method: "POST",
|
|
340
371
|
headers: headers(),
|
|
341
372
|
body: JSON.stringify({ contact_ids: config.contactIds, list_id: config.listId })
|
|
342
373
|
});
|
|
374
|
+
const data = await resp.json();
|
|
375
|
+
return data.data || data;
|
|
376
|
+
},
|
|
377
|
+
/** Create a new sequence with optional steps + channels. */
|
|
378
|
+
async create(payload) {
|
|
379
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences`, {
|
|
380
|
+
method: "POST",
|
|
381
|
+
headers: headers(),
|
|
382
|
+
body: JSON.stringify(payload)
|
|
383
|
+
});
|
|
384
|
+
const data = await resp.json();
|
|
385
|
+
return data.data || data;
|
|
386
|
+
},
|
|
387
|
+
/** Update sequence metadata. Rejected (409) if sequence is in a transitional status. */
|
|
388
|
+
async update(sequenceId, fields) {
|
|
389
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {
|
|
390
|
+
method: "PATCH",
|
|
391
|
+
headers: headers(),
|
|
392
|
+
body: JSON.stringify(fields)
|
|
393
|
+
});
|
|
394
|
+
const data = await resp.json();
|
|
395
|
+
return data.data || data;
|
|
396
|
+
},
|
|
397
|
+
/** Update a single step within a sequence. */
|
|
398
|
+
async updateStep(sequenceId, stepId, fields) {
|
|
399
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/steps/${stepId}`, {
|
|
400
|
+
method: "PATCH",
|
|
401
|
+
headers: headers(),
|
|
402
|
+
body: JSON.stringify(fields)
|
|
403
|
+
});
|
|
404
|
+
const data = await resp.json();
|
|
405
|
+
return data.data || data;
|
|
406
|
+
},
|
|
407
|
+
/** Soft-delete (archive) a sequence. */
|
|
408
|
+
async delete(sequenceId) {
|
|
409
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {
|
|
410
|
+
method: "DELETE",
|
|
411
|
+
headers: headers()
|
|
412
|
+
});
|
|
413
|
+
const data = await resp.json();
|
|
414
|
+
return data.data || data;
|
|
415
|
+
},
|
|
416
|
+
/** Run/start a DRAFTED sequence (V2 orchestration). */
|
|
417
|
+
async run(sequenceId) {
|
|
418
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/run`, {
|
|
419
|
+
method: "POST",
|
|
420
|
+
headers: headers()
|
|
421
|
+
});
|
|
422
|
+
const data = await resp.json();
|
|
423
|
+
return data.data || data;
|
|
424
|
+
},
|
|
425
|
+
/** Pause a live sequence. */
|
|
426
|
+
async pause(sequenceId) {
|
|
427
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/pause`, {
|
|
428
|
+
method: "POST",
|
|
429
|
+
headers: headers()
|
|
430
|
+
});
|
|
431
|
+
const data = await resp.json();
|
|
432
|
+
return data.data || data;
|
|
433
|
+
},
|
|
434
|
+
/** Resume a paused sequence. */
|
|
435
|
+
async resume(sequenceId) {
|
|
436
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/resume`, {
|
|
437
|
+
method: "POST",
|
|
438
|
+
headers: headers()
|
|
439
|
+
});
|
|
440
|
+
const data = await resp.json();
|
|
441
|
+
return data.data || data;
|
|
442
|
+
},
|
|
443
|
+
/** Read-only sequence preview with all steps + channels (no enrollment). */
|
|
444
|
+
async preview(sequenceId) {
|
|
445
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/preview`, {
|
|
446
|
+
headers: headers()
|
|
447
|
+
});
|
|
448
|
+
const data = await resp.json();
|
|
449
|
+
return data.data || data;
|
|
450
|
+
},
|
|
451
|
+
/** Comprehensive analytics for a sequence. */
|
|
452
|
+
async analytics(sequenceId) {
|
|
453
|
+
const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/analytics`, {
|
|
454
|
+
headers: headers()
|
|
455
|
+
});
|
|
456
|
+
const data = await resp.json();
|
|
457
|
+
return data.data || data;
|
|
343
458
|
}
|
|
344
459
|
};
|
|
345
460
|
};
|
|
@@ -464,8 +579,148 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
464
579
|
const baseUrl = apiUrl || DEFAULT_API12;
|
|
465
580
|
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
466
581
|
const listeners = /* @__PURE__ */ new Map();
|
|
582
|
+
const toQuery = (params) => {
|
|
583
|
+
const qs = new URLSearchParams();
|
|
584
|
+
for (const [k, v] of Object.entries(params)) {
|
|
585
|
+
if (v != null) qs.set(k, String(v));
|
|
586
|
+
}
|
|
587
|
+
const s = qs.toString();
|
|
588
|
+
return s ? `?${s}` : "";
|
|
589
|
+
};
|
|
590
|
+
const dialer = {
|
|
591
|
+
/** List parallel-dialer sessions with filters + pagination. */
|
|
592
|
+
async listSessions(params = {}) {
|
|
593
|
+
const resp = await fetch(
|
|
594
|
+
`${baseUrl}/api/v1/voice/dialer/sessions${toQuery(params)}`,
|
|
595
|
+
{ headers: headers() }
|
|
596
|
+
);
|
|
597
|
+
const data = await resp.json();
|
|
598
|
+
return data.data || data;
|
|
599
|
+
},
|
|
600
|
+
/** Create a parallel-dialer session in PAUSED state. SDR opens UI to start dialing. */
|
|
601
|
+
async createSession(payload) {
|
|
602
|
+
const resp = await fetch(`${baseUrl}/api/v1/voice/dialer/sessions`, {
|
|
603
|
+
method: "POST",
|
|
604
|
+
headers: headers(),
|
|
605
|
+
body: JSON.stringify(payload)
|
|
606
|
+
});
|
|
607
|
+
const data = await resp.json();
|
|
608
|
+
return data.data || data;
|
|
609
|
+
},
|
|
610
|
+
/** Pause / resume / stop a dialer session via status flip. */
|
|
611
|
+
async updateSessionStatus(sessionId, status) {
|
|
612
|
+
const resp = await fetch(
|
|
613
|
+
`${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/status`,
|
|
614
|
+
{
|
|
615
|
+
method: "PATCH",
|
|
616
|
+
headers: headers(),
|
|
617
|
+
body: JSON.stringify({ status })
|
|
618
|
+
}
|
|
619
|
+
);
|
|
620
|
+
const data = await resp.json();
|
|
621
|
+
return data.data || data;
|
|
622
|
+
},
|
|
623
|
+
/**
|
|
624
|
+
* Resume a PAUSED dialer session. Auto-fetches the next batch from the source list,
|
|
625
|
+
* filters already-called + phoneless rows, and forwards to voice's start-session.
|
|
626
|
+
* @param maxContacts 1-4 (voice caps parallel dialing at 4). Default 4.
|
|
627
|
+
*/
|
|
628
|
+
async resumeSession(sessionId, maxContacts = 4) {
|
|
629
|
+
const resp = await fetch(
|
|
630
|
+
`${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/resume`,
|
|
631
|
+
{
|
|
632
|
+
method: "POST",
|
|
633
|
+
headers: headers(),
|
|
634
|
+
body: JSON.stringify({ max_contacts: maxContacts })
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
const data = await resp.json();
|
|
638
|
+
return data.data || data;
|
|
639
|
+
},
|
|
640
|
+
/** Aggregated dialer analytics (daily breakdown or total). */
|
|
641
|
+
async stats(params = {}) {
|
|
642
|
+
const resp = await fetch(
|
|
643
|
+
`${baseUrl}/api/v1/voice/dialer/stats${toQuery(params)}`,
|
|
644
|
+
{ headers: headers() }
|
|
645
|
+
);
|
|
646
|
+
const data = await resp.json();
|
|
647
|
+
return data.data || data;
|
|
648
|
+
},
|
|
649
|
+
/** List dialer-eligible phone numbers with 7-day stats + daily limits. */
|
|
650
|
+
async numbers(userEmail) {
|
|
651
|
+
const params = userEmail ? { user_email: userEmail } : {};
|
|
652
|
+
const resp = await fetch(
|
|
653
|
+
`${baseUrl}/api/v1/voice/dialer/numbers${toQuery(params)}`,
|
|
654
|
+
{ headers: headers() }
|
|
655
|
+
);
|
|
656
|
+
const data = await resp.json();
|
|
657
|
+
return data.data || data;
|
|
658
|
+
},
|
|
659
|
+
/** List missed inbound callbacks with caller / contact info. */
|
|
660
|
+
async missedCallbacks(limit = 50) {
|
|
661
|
+
const resp = await fetch(
|
|
662
|
+
`${baseUrl}/api/v1/voice/dialer/missed-callbacks${toQuery({ limit })}`,
|
|
663
|
+
{ headers: headers() }
|
|
664
|
+
);
|
|
665
|
+
const data = await resp.json();
|
|
666
|
+
return data.data || data;
|
|
667
|
+
},
|
|
668
|
+
/** AI grading for a single dialer call (returns "pending" while in progress). */
|
|
669
|
+
async callGrading(roomName) {
|
|
670
|
+
const resp = await fetch(
|
|
671
|
+
`${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/grading`,
|
|
672
|
+
{ headers: headers() }
|
|
673
|
+
);
|
|
674
|
+
const data = await resp.json();
|
|
675
|
+
return data.data || data;
|
|
676
|
+
},
|
|
677
|
+
/** List voice agents available for dialer sessions (capped at 100; no pagination). */
|
|
678
|
+
async agents(params = {}) {
|
|
679
|
+
const resp = await fetch(
|
|
680
|
+
`${baseUrl}/api/v1/voice/dialer/agents${toQuery(params)}`,
|
|
681
|
+
{ headers: headers() }
|
|
682
|
+
);
|
|
683
|
+
const data = await resp.json();
|
|
684
|
+
return data.data || data;
|
|
685
|
+
},
|
|
686
|
+
/** Fetch the full transcript for a single dialer call. */
|
|
687
|
+
async callTranscript(roomName) {
|
|
688
|
+
const resp = await fetch(
|
|
689
|
+
`${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/transcript`,
|
|
690
|
+
{ headers: headers() }
|
|
691
|
+
);
|
|
692
|
+
return resp.json();
|
|
693
|
+
},
|
|
694
|
+
/** List dialer calls — pass `contact_id` or `user_email` to scope. */
|
|
695
|
+
async listCalls(params = {}) {
|
|
696
|
+
const resp = await fetch(
|
|
697
|
+
`${baseUrl}/api/v1/voice/dialer/calls${toQuery(params)}`,
|
|
698
|
+
{ headers: headers() }
|
|
699
|
+
);
|
|
700
|
+
return resp.json();
|
|
701
|
+
},
|
|
702
|
+
/** Convenience: list calls for a single contact. */
|
|
703
|
+
async listCallsForContact(contactId, extra = {}) {
|
|
704
|
+
const resp = await fetch(
|
|
705
|
+
`${baseUrl}/api/v1/voice/dialer/calls${toQuery({ contact_id: contactId, ...extra })}`,
|
|
706
|
+
{ headers: headers() }
|
|
707
|
+
);
|
|
708
|
+
return resp.json();
|
|
709
|
+
},
|
|
710
|
+
/** Convenience: list calls placed by a specific SDR. */
|
|
711
|
+
async listCallsForSdr(userEmail, extra = {}) {
|
|
712
|
+
const resp = await fetch(
|
|
713
|
+
`${baseUrl}/api/v1/voice/dialer/calls${toQuery({ user_email: userEmail, ...extra })}`,
|
|
714
|
+
{ headers: headers() }
|
|
715
|
+
);
|
|
716
|
+
return resp.json();
|
|
717
|
+
}
|
|
718
|
+
};
|
|
467
719
|
return {
|
|
468
|
-
/**
|
|
720
|
+
/**
|
|
721
|
+
* Start an AI voice session.
|
|
722
|
+
* @deprecated Preview surface — for parallel-dialer flows use `voice.dialer.createSession()`.
|
|
723
|
+
*/
|
|
469
724
|
async start(config) {
|
|
470
725
|
const resp = await fetch(`${baseUrl}/api/v1/voice/sessions`, {
|
|
471
726
|
method: "POST",
|
|
@@ -475,7 +730,10 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
475
730
|
const data = await resp.json();
|
|
476
731
|
return data.data || data;
|
|
477
732
|
},
|
|
478
|
-
/**
|
|
733
|
+
/**
|
|
734
|
+
* Get call analysis for a completed session.
|
|
735
|
+
* @deprecated Preview surface — for dialer-call grading use `voice.dialer.callGrading(roomName)`.
|
|
736
|
+
*/
|
|
479
737
|
async analysis(sessionId) {
|
|
480
738
|
const resp = await fetch(`${baseUrl}/api/v1/voice/sessions/${sessionId}/analysis`, { headers: headers() });
|
|
481
739
|
const data = await resp.json();
|
|
@@ -485,7 +743,9 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
485
743
|
on(event, callback) {
|
|
486
744
|
if (!listeners.has(event)) listeners.set(event, []);
|
|
487
745
|
listeners.get(event).push(callback);
|
|
488
|
-
}
|
|
746
|
+
},
|
|
747
|
+
/** Parallel-dialer session control + analytics. */
|
|
748
|
+
dialer
|
|
489
749
|
};
|
|
490
750
|
};
|
|
491
751
|
|
|
@@ -1014,98 +1274,869 @@ var createDealsClient = (apiKey, apiUrl) => {
|
|
|
1014
1274
|
};
|
|
1015
1275
|
};
|
|
1016
1276
|
|
|
1017
|
-
// src/
|
|
1018
|
-
var DEFAULT_HOST = "https://t.graph8.com";
|
|
1277
|
+
// src/inbox.ts
|
|
1019
1278
|
var DEFAULT_API22 = "https://be.graph8.com";
|
|
1020
|
-
var
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
this._forms = null;
|
|
1028
|
-
/** @internal */
|
|
1029
|
-
this._visitors = null;
|
|
1030
|
-
/** @internal */
|
|
1031
|
-
this._copilot = null;
|
|
1032
|
-
/** @internal */
|
|
1033
|
-
this._chat = null;
|
|
1034
|
-
/** @internal */
|
|
1035
|
-
this._calendar = null;
|
|
1036
|
-
/** @internal */
|
|
1037
|
-
this._enrich = null;
|
|
1038
|
-
/** @internal */
|
|
1039
|
-
this._sequences = null;
|
|
1040
|
-
/** @internal */
|
|
1041
|
-
this._campaigns = null;
|
|
1042
|
-
/** @internal */
|
|
1043
|
-
this._integrations = null;
|
|
1044
|
-
/** @internal */
|
|
1045
|
-
this._signals = null;
|
|
1046
|
-
/** @internal */
|
|
1047
|
-
this._analytics = null;
|
|
1048
|
-
/** @internal */
|
|
1049
|
-
this._voice = null;
|
|
1050
|
-
/** @internal */
|
|
1051
|
-
this._pages = null;
|
|
1052
|
-
/** @internal */
|
|
1053
|
-
this._webhooks = null;
|
|
1054
|
-
/** @internal */
|
|
1055
|
-
this._contacts = null;
|
|
1056
|
-
/** @internal */
|
|
1057
|
-
this._companies = null;
|
|
1058
|
-
/** @internal */
|
|
1059
|
-
this._lists = null;
|
|
1060
|
-
/** @internal */
|
|
1061
|
-
this._notes = null;
|
|
1062
|
-
/** @internal */
|
|
1063
|
-
this._tasks = null;
|
|
1064
|
-
/** @internal */
|
|
1065
|
-
this._fields = null;
|
|
1066
|
-
/** @internal */
|
|
1067
|
-
this._deals = null;
|
|
1068
|
-
}
|
|
1069
|
-
/**
|
|
1070
|
-
* Initialize the graph8 SDK. Must be called before any other method.
|
|
1071
|
-
* Safe to call on the server (SSR) - becomes a no-op for tracking.
|
|
1072
|
-
*/
|
|
1073
|
-
init(config) {
|
|
1074
|
-
this.config = config;
|
|
1075
|
-
if (!isServer) {
|
|
1076
|
-
this.client = jitsuAnalytics({
|
|
1077
|
-
host: config.host || DEFAULT_HOST,
|
|
1078
|
-
writeKey: config.writeKey || "",
|
|
1079
|
-
debug: config.debug
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
|
-
const apiUrl = config.apiUrl || DEFAULT_API22;
|
|
1083
|
-
const writeKey = config.writeKey || "";
|
|
1084
|
-
const apiKey = config.apiKey || "";
|
|
1085
|
-
if (writeKey) {
|
|
1086
|
-
this._forms = createFormsClient(writeKey, apiUrl);
|
|
1087
|
-
this._visitors = createVisitorsClient(writeKey, apiUrl);
|
|
1088
|
-
this._copilot = createCopilotClient(writeKey, apiUrl);
|
|
1089
|
-
this._chat = createChatClient(writeKey, apiUrl);
|
|
1090
|
-
this._calendar = createCalendarClient(apiUrl);
|
|
1091
|
-
this._signals = createSignalsClient(writeKey, false, apiUrl);
|
|
1279
|
+
var createInboxClient = (apiKey, apiUrl) => {
|
|
1280
|
+
const baseUrl = apiUrl || DEFAULT_API22;
|
|
1281
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1282
|
+
const toQuery = (params) => {
|
|
1283
|
+
const qs = new URLSearchParams();
|
|
1284
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1285
|
+
if (v != null) qs.set(k, String(v));
|
|
1092
1286
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1287
|
+
const s = qs.toString();
|
|
1288
|
+
return s ? `?${s}` : "";
|
|
1289
|
+
};
|
|
1290
|
+
return {
|
|
1291
|
+
/** List inbox threads across email, SMS, and LinkedIn. */
|
|
1292
|
+
async list(params = {}) {
|
|
1293
|
+
const resp = await fetch(`${baseUrl}/api/v1/inbox${toQuery(params)}`, { headers: headers() });
|
|
1294
|
+
return resp.json();
|
|
1295
|
+
},
|
|
1296
|
+
/** Get a single inbox thread. Defaults to email channel. */
|
|
1297
|
+
async get(replyId, channel = "email") {
|
|
1298
|
+
const resp = await fetch(
|
|
1299
|
+
`${baseUrl}/api/v1/inbox/${replyId}${toQuery({ channel })}`,
|
|
1300
|
+
{ headers: headers() }
|
|
1301
|
+
);
|
|
1302
|
+
const data = await resp.json();
|
|
1303
|
+
return data.data || data;
|
|
1304
|
+
},
|
|
1305
|
+
/** Assign a user to an inbox thread. */
|
|
1306
|
+
async assign(replyId, assigneeEmail, channel = "email") {
|
|
1307
|
+
const resp = await fetch(
|
|
1308
|
+
`${baseUrl}/api/v1/inbox/${replyId}/assign${toQuery({ channel })}`,
|
|
1309
|
+
{
|
|
1310
|
+
method: "POST",
|
|
1311
|
+
headers: headers(),
|
|
1312
|
+
body: JSON.stringify({ assignee_email: assigneeEmail })
|
|
1313
|
+
}
|
|
1314
|
+
);
|
|
1315
|
+
const data = await resp.json();
|
|
1316
|
+
return data.data || data;
|
|
1317
|
+
},
|
|
1318
|
+
/** Attach tag IDs to an inbox thread. */
|
|
1319
|
+
async tag(replyId, tagIds, channel = "email") {
|
|
1320
|
+
const resp = await fetch(
|
|
1321
|
+
`${baseUrl}/api/v1/inbox/${replyId}/tag${toQuery({ channel })}`,
|
|
1322
|
+
{
|
|
1323
|
+
method: "POST",
|
|
1324
|
+
headers: headers(),
|
|
1325
|
+
body: JSON.stringify({ tag_ids: tagIds })
|
|
1326
|
+
}
|
|
1327
|
+
);
|
|
1328
|
+
const data = await resp.json();
|
|
1329
|
+
return data.data || data;
|
|
1330
|
+
},
|
|
1331
|
+
/**
|
|
1332
|
+
* Generate an AI draft reply for a thread.
|
|
1333
|
+
* Charges credits — server returns 402 if balance is insufficient.
|
|
1334
|
+
*/
|
|
1335
|
+
async draft(replyId, channel = "email") {
|
|
1336
|
+
const resp = await fetch(
|
|
1337
|
+
`${baseUrl}/api/v1/inbox/${replyId}/draft${toQuery({ channel })}`,
|
|
1338
|
+
{ headers: headers() }
|
|
1339
|
+
);
|
|
1340
|
+
const data = await resp.json();
|
|
1341
|
+
return data.data || data;
|
|
1342
|
+
},
|
|
1343
|
+
/** Send a reply through email, SMS, or LinkedIn. */
|
|
1344
|
+
async send(replyId, payload) {
|
|
1345
|
+
const resp = await fetch(`${baseUrl}/api/v1/inbox/${replyId}/send`, {
|
|
1346
|
+
method: "POST",
|
|
1347
|
+
headers: headers(),
|
|
1348
|
+
body: JSON.stringify(payload)
|
|
1349
|
+
});
|
|
1350
|
+
const data = await resp.json();
|
|
1351
|
+
return data.data || data;
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
// src/quotes.ts
|
|
1357
|
+
var DEFAULT_API23 = "https://be.graph8.com";
|
|
1358
|
+
var createQuotesClient = (apiKey, apiUrl) => {
|
|
1359
|
+
const baseUrl = apiUrl || DEFAULT_API23;
|
|
1360
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1361
|
+
const toQuery = (params) => {
|
|
1362
|
+
const qs = new URLSearchParams();
|
|
1363
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1364
|
+
if (v != null) qs.set(k, String(v));
|
|
1365
|
+
}
|
|
1366
|
+
const s = qs.toString();
|
|
1367
|
+
return s ? `?${s}` : "";
|
|
1368
|
+
};
|
|
1369
|
+
return {
|
|
1370
|
+
/** List quotes org-wide with optional filters and pagination. */
|
|
1371
|
+
async list(params = {}) {
|
|
1372
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes${toQuery(params)}`, { headers: headers() });
|
|
1373
|
+
return resp.json();
|
|
1374
|
+
},
|
|
1375
|
+
/** Get full details for a single quote. */
|
|
1376
|
+
async get(quoteId) {
|
|
1377
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, { headers: headers() });
|
|
1378
|
+
const data = await resp.json();
|
|
1379
|
+
return data.data || data;
|
|
1380
|
+
},
|
|
1381
|
+
/** Create a new quote from line items. */
|
|
1382
|
+
async create(quote) {
|
|
1383
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes`, {
|
|
1384
|
+
method: "POST",
|
|
1385
|
+
headers: headers(),
|
|
1386
|
+
body: JSON.stringify(quote)
|
|
1387
|
+
});
|
|
1388
|
+
const data = await resp.json();
|
|
1389
|
+
return data.data || data;
|
|
1390
|
+
},
|
|
1391
|
+
/** Update a draft quote (line items, expiry, notes). */
|
|
1392
|
+
async update(quoteId, fields) {
|
|
1393
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {
|
|
1394
|
+
method: "PUT",
|
|
1395
|
+
headers: headers(),
|
|
1396
|
+
body: JSON.stringify(fields)
|
|
1397
|
+
});
|
|
1398
|
+
const data = await resp.json();
|
|
1399
|
+
return data.data || data;
|
|
1400
|
+
},
|
|
1401
|
+
/** Delete a draft quote (irreversible). */
|
|
1402
|
+
async delete(quoteId) {
|
|
1403
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {
|
|
1404
|
+
method: "DELETE",
|
|
1405
|
+
headers: headers()
|
|
1406
|
+
});
|
|
1407
|
+
return resp.json();
|
|
1408
|
+
},
|
|
1409
|
+
/** Duplicate an existing quote (all line items copied into a new draft). */
|
|
1410
|
+
async duplicate(quoteId) {
|
|
1411
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/duplicate`, {
|
|
1412
|
+
method: "POST",
|
|
1413
|
+
headers: headers(),
|
|
1414
|
+
body: JSON.stringify({})
|
|
1415
|
+
});
|
|
1416
|
+
const data = await resp.json();
|
|
1417
|
+
return data.data || data;
|
|
1418
|
+
},
|
|
1419
|
+
/** Convert a signed / sent quote back to editable draft state. */
|
|
1420
|
+
async editAsDraft(quoteId) {
|
|
1421
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/edit-as-draft`, {
|
|
1422
|
+
method: "POST",
|
|
1423
|
+
headers: headers(),
|
|
1424
|
+
body: JSON.stringify({})
|
|
1425
|
+
});
|
|
1426
|
+
return resp.json();
|
|
1427
|
+
},
|
|
1428
|
+
/** Send a quote to its recipient via email (with signature + optional payment link). */
|
|
1429
|
+
async send(quoteId, params) {
|
|
1430
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/send`, {
|
|
1431
|
+
method: "POST",
|
|
1432
|
+
headers: headers(),
|
|
1433
|
+
body: JSON.stringify(params)
|
|
1434
|
+
});
|
|
1435
|
+
const data = await resp.json();
|
|
1436
|
+
return data.data || data;
|
|
1437
|
+
},
|
|
1438
|
+
/** List products available for line items. */
|
|
1439
|
+
async products() {
|
|
1440
|
+
const resp = await fetch(`${baseUrl}/api/v1/quotable-products`, { headers: headers() });
|
|
1441
|
+
return resp.json();
|
|
1442
|
+
},
|
|
1443
|
+
/** Get org-level quote settings (currency, tax rate, payment providers, logo). */
|
|
1444
|
+
async settings() {
|
|
1445
|
+
const resp = await fetch(`${baseUrl}/api/v1/quote-settings`, { headers: headers() });
|
|
1446
|
+
const data = await resp.json();
|
|
1447
|
+
return data.data || data;
|
|
1448
|
+
},
|
|
1449
|
+
/** Get all quotes associated with a contact. */
|
|
1450
|
+
async forContact(contactId) {
|
|
1451
|
+
const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/quotes`, { headers: headers() });
|
|
1452
|
+
return resp.json();
|
|
1453
|
+
},
|
|
1454
|
+
/** Get all quotes associated with a company. */
|
|
1455
|
+
async forCompany(companyId) {
|
|
1456
|
+
const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}/quotes`, { headers: headers() });
|
|
1457
|
+
return resp.json();
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
};
|
|
1461
|
+
|
|
1462
|
+
// src/pipelines.ts
|
|
1463
|
+
var DEFAULT_API24 = "https://be.graph8.com";
|
|
1464
|
+
var createPipelinesClient = (apiKey, apiUrl) => {
|
|
1465
|
+
const baseUrl = apiUrl || DEFAULT_API24;
|
|
1466
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1467
|
+
return {
|
|
1468
|
+
/** List all stage-checklist pipelines with stages, evidence, scripts. */
|
|
1469
|
+
async list() {
|
|
1470
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines`, { headers: headers() });
|
|
1471
|
+
return resp.json();
|
|
1472
|
+
},
|
|
1473
|
+
/** Get a single pipeline by ID. */
|
|
1474
|
+
async get(pipelineId) {
|
|
1475
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, { headers: headers() });
|
|
1476
|
+
const data = await resp.json();
|
|
1477
|
+
return data.data || data;
|
|
1478
|
+
},
|
|
1479
|
+
/** Get the canonical evidence-key library (used when defining stages). */
|
|
1480
|
+
async evidenceLibrary() {
|
|
1481
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/evidence-library`, { headers: headers() });
|
|
1482
|
+
return resp.json();
|
|
1483
|
+
},
|
|
1484
|
+
/** Create a new pipeline. Defaults to a templated set of stages; pass blank=true for empty. */
|
|
1485
|
+
async create(params) {
|
|
1486
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines`, {
|
|
1487
|
+
method: "POST",
|
|
1488
|
+
headers: headers(),
|
|
1489
|
+
body: JSON.stringify(params)
|
|
1490
|
+
});
|
|
1491
|
+
const data = await resp.json();
|
|
1492
|
+
return data.data || data;
|
|
1493
|
+
},
|
|
1494
|
+
/** Update pipeline metadata (name, target). */
|
|
1495
|
+
async update(pipelineId, fields) {
|
|
1496
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {
|
|
1497
|
+
method: "PUT",
|
|
1498
|
+
headers: headers(),
|
|
1499
|
+
body: JSON.stringify(fields)
|
|
1500
|
+
});
|
|
1501
|
+
const data = await resp.json();
|
|
1502
|
+
return data.data || data;
|
|
1503
|
+
},
|
|
1504
|
+
/** Delete a pipeline. Only allowed when no deals reference it. */
|
|
1505
|
+
async delete(pipelineId) {
|
|
1506
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {
|
|
1507
|
+
method: "DELETE",
|
|
1508
|
+
headers: headers()
|
|
1509
|
+
});
|
|
1510
|
+
return resp.json();
|
|
1511
|
+
},
|
|
1512
|
+
/** Add a new stage to a pipeline. */
|
|
1513
|
+
async createStage(pipelineId, stage) {
|
|
1514
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages`, {
|
|
1515
|
+
method: "POST",
|
|
1516
|
+
headers: headers(),
|
|
1517
|
+
body: JSON.stringify(stage)
|
|
1518
|
+
});
|
|
1519
|
+
const data = await resp.json();
|
|
1520
|
+
return data.data || data;
|
|
1521
|
+
},
|
|
1522
|
+
/** Update a stage (evidence, scripts, position). */
|
|
1523
|
+
async updateStage(pipelineId, stageId, fields) {
|
|
1524
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {
|
|
1525
|
+
method: "PUT",
|
|
1526
|
+
headers: headers(),
|
|
1527
|
+
body: JSON.stringify(fields)
|
|
1528
|
+
});
|
|
1529
|
+
const data = await resp.json();
|
|
1530
|
+
return data.data || data;
|
|
1531
|
+
},
|
|
1532
|
+
/** Reorder stages within a pipeline (pass full ordered list of stage IDs). */
|
|
1533
|
+
async reorderStages(pipelineId, stageIds) {
|
|
1534
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/reorder`, {
|
|
1535
|
+
method: "PUT",
|
|
1536
|
+
headers: headers(),
|
|
1537
|
+
body: JSON.stringify({ stage_ids: stageIds })
|
|
1538
|
+
});
|
|
1539
|
+
return resp.json();
|
|
1540
|
+
},
|
|
1541
|
+
/** Delete a stage from a pipeline. */
|
|
1542
|
+
async deleteStage(pipelineId, stageId) {
|
|
1543
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {
|
|
1544
|
+
method: "DELETE",
|
|
1545
|
+
headers: headers()
|
|
1546
|
+
});
|
|
1547
|
+
return resp.json();
|
|
1548
|
+
},
|
|
1549
|
+
/** Get an AI-suggested pipeline based on org context (brand, ICP, messaging). */
|
|
1550
|
+
async suggest() {
|
|
1551
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/suggest`, {
|
|
1552
|
+
method: "POST",
|
|
1553
|
+
headers: headers(),
|
|
1554
|
+
body: JSON.stringify({})
|
|
1555
|
+
});
|
|
1556
|
+
return resp.json();
|
|
1557
|
+
},
|
|
1558
|
+
/** Create a real pipeline from an AI suggestion (optionally with overrides). */
|
|
1559
|
+
async fromSuggestion(suggestionId, overrides) {
|
|
1560
|
+
const resp = await fetch(`${baseUrl}/api/v1/pipelines/from-suggestion`, {
|
|
1561
|
+
method: "POST",
|
|
1562
|
+
headers: headers(),
|
|
1563
|
+
body: JSON.stringify({ suggestion_id: suggestionId, ...overrides || {} })
|
|
1564
|
+
});
|
|
1565
|
+
const data = await resp.json();
|
|
1566
|
+
return data.data || data;
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
// src/workflows.ts
|
|
1572
|
+
var DEFAULT_API25 = "https://be.graph8.com";
|
|
1573
|
+
var createWorkflowsClient = (apiKey, apiUrl) => {
|
|
1574
|
+
const baseUrl = apiUrl || DEFAULT_API25;
|
|
1575
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1576
|
+
const toQuery = (params) => {
|
|
1577
|
+
const qs = new URLSearchParams();
|
|
1578
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1579
|
+
if (v != null) qs.set(k, String(v));
|
|
1580
|
+
}
|
|
1581
|
+
const s = qs.toString();
|
|
1582
|
+
return s ? `?${s}` : "";
|
|
1583
|
+
};
|
|
1584
|
+
return {
|
|
1585
|
+
/** List workflows org-wide. */
|
|
1586
|
+
async list(params = {}) {
|
|
1587
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows${toQuery(params)}`, { headers: headers() });
|
|
1588
|
+
return resp.json();
|
|
1589
|
+
},
|
|
1590
|
+
/** Get full workflow definition (nodes, connections, trigger, execution state). */
|
|
1591
|
+
async get(workflowId) {
|
|
1592
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, { headers: headers() });
|
|
1593
|
+
const data = await resp.json();
|
|
1594
|
+
return data.data || data;
|
|
1595
|
+
},
|
|
1596
|
+
/** Create a new workflow. */
|
|
1597
|
+
async create(params) {
|
|
1598
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows`, {
|
|
1599
|
+
method: "POST",
|
|
1600
|
+
headers: headers(),
|
|
1601
|
+
body: JSON.stringify(params)
|
|
1602
|
+
});
|
|
1603
|
+
const data = await resp.json();
|
|
1604
|
+
return data.data || data;
|
|
1605
|
+
},
|
|
1606
|
+
/**
|
|
1607
|
+
* Update a workflow. Pass the full `config` (nodes + connections) to edit
|
|
1608
|
+
* the graph — node-level CRUD is performed client-side by mutating the
|
|
1609
|
+
* config and submitting the updated record.
|
|
1610
|
+
*/
|
|
1611
|
+
async update(workflowId, fields) {
|
|
1612
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {
|
|
1613
|
+
method: "PUT",
|
|
1614
|
+
headers: headers(),
|
|
1615
|
+
body: JSON.stringify(fields)
|
|
1616
|
+
});
|
|
1617
|
+
const data = await resp.json();
|
|
1618
|
+
return data.data || data;
|
|
1619
|
+
},
|
|
1620
|
+
/** Delete a workflow. */
|
|
1621
|
+
async delete(workflowId) {
|
|
1622
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {
|
|
1623
|
+
method: "DELETE",
|
|
1624
|
+
headers: headers()
|
|
1625
|
+
});
|
|
1626
|
+
return resp.json();
|
|
1627
|
+
},
|
|
1628
|
+
/** Validate a workflow definition (orphans, dangling connections, required fields). */
|
|
1629
|
+
async validate(workflow) {
|
|
1630
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/validate`, {
|
|
1631
|
+
method: "POST",
|
|
1632
|
+
headers: headers(),
|
|
1633
|
+
body: JSON.stringify(workflow)
|
|
1634
|
+
});
|
|
1635
|
+
return resp.json();
|
|
1636
|
+
},
|
|
1637
|
+
/** Execute a workflow immediately with a trigger payload. */
|
|
1638
|
+
async execute(workflowId, triggerPayload = {}) {
|
|
1639
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/execute`, {
|
|
1640
|
+
method: "POST",
|
|
1641
|
+
headers: headers(),
|
|
1642
|
+
body: JSON.stringify({ trigger_payload: triggerPayload })
|
|
1643
|
+
});
|
|
1644
|
+
const data = await resp.json();
|
|
1645
|
+
return data.data || data;
|
|
1646
|
+
},
|
|
1647
|
+
/** Get the status + output of a workflow execution. */
|
|
1648
|
+
async getExecution(executionId) {
|
|
1649
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}`, { headers: headers() });
|
|
1650
|
+
const data = await resp.json();
|
|
1651
|
+
return data.data || data;
|
|
1652
|
+
},
|
|
1653
|
+
/** Pause an in-flight execution. */
|
|
1654
|
+
async pauseExecution(executionId) {
|
|
1655
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/pause`, {
|
|
1656
|
+
method: "POST",
|
|
1657
|
+
headers: headers(),
|
|
1658
|
+
body: JSON.stringify({})
|
|
1659
|
+
});
|
|
1660
|
+
return resp.json();
|
|
1661
|
+
},
|
|
1662
|
+
/** Resume a paused execution. */
|
|
1663
|
+
async resumeExecution(executionId) {
|
|
1664
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/resume`, {
|
|
1665
|
+
method: "POST",
|
|
1666
|
+
headers: headers(),
|
|
1667
|
+
body: JSON.stringify({})
|
|
1668
|
+
});
|
|
1669
|
+
return resp.json();
|
|
1670
|
+
},
|
|
1671
|
+
/** Stop an execution (terminal state — cannot resume). */
|
|
1672
|
+
async stopExecution(executionId) {
|
|
1673
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/stop`, {
|
|
1674
|
+
method: "POST",
|
|
1675
|
+
headers: headers(),
|
|
1676
|
+
body: JSON.stringify({})
|
|
1677
|
+
});
|
|
1678
|
+
return resp.json();
|
|
1679
|
+
},
|
|
1680
|
+
/** Get the status of a workflow's external trigger (e.g. "waiting for webhook"). */
|
|
1681
|
+
async getTriggerStatus(workflowId) {
|
|
1682
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-status`, { headers: headers() });
|
|
1683
|
+
return resp.json();
|
|
1684
|
+
},
|
|
1685
|
+
/** Reset the trigger cursor (e.g. for event-stream triggers — resume from beginning). */
|
|
1686
|
+
async resetTrigger(workflowId) {
|
|
1687
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-reset`, {
|
|
1688
|
+
method: "POST",
|
|
1689
|
+
headers: headers(),
|
|
1690
|
+
body: JSON.stringify({})
|
|
1691
|
+
});
|
|
1692
|
+
return resp.json();
|
|
1693
|
+
},
|
|
1694
|
+
/**
|
|
1695
|
+
* List available node types with schemas. Pass a `type` param to fetch one type's full schema.
|
|
1696
|
+
*/
|
|
1697
|
+
async nodeTypes(params = {}) {
|
|
1698
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/node-types/schema${toQuery(params)}`, { headers: headers() });
|
|
1699
|
+
return resp.json();
|
|
1700
|
+
},
|
|
1701
|
+
/** Slack workspace users (for Slack action recipients). */
|
|
1702
|
+
async listSlackUsers() {
|
|
1703
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/users`, { headers: headers() });
|
|
1704
|
+
return resp.json();
|
|
1705
|
+
},
|
|
1706
|
+
/** Slack channels. */
|
|
1707
|
+
async listSlackChannels() {
|
|
1708
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/channels`, { headers: headers() });
|
|
1709
|
+
return resp.json();
|
|
1710
|
+
},
|
|
1711
|
+
/** Roam (Copilot chat) users. */
|
|
1712
|
+
async listRoamUsers() {
|
|
1713
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/users`, { headers: headers() });
|
|
1714
|
+
return resp.json();
|
|
1715
|
+
},
|
|
1716
|
+
/** Roam (Copilot chat) groups. */
|
|
1717
|
+
async listRoamGroups() {
|
|
1718
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/groups`, { headers: headers() });
|
|
1719
|
+
return resp.json();
|
|
1720
|
+
},
|
|
1721
|
+
/** Available MCP servers (for Agent-node integrations). */
|
|
1722
|
+
async listMcpServers() {
|
|
1723
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/mcp-servers`, { headers: headers() });
|
|
1724
|
+
return resp.json();
|
|
1725
|
+
},
|
|
1726
|
+
/** Available call dispositions (voice workflow nodes). */
|
|
1727
|
+
async listDispositions() {
|
|
1728
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/dispositions`, { headers: headers() });
|
|
1729
|
+
return resp.json();
|
|
1730
|
+
},
|
|
1731
|
+
/** Form field schema for form-trigger nodes. */
|
|
1732
|
+
async listFormFields(formId) {
|
|
1733
|
+
const resp = await fetch(`${baseUrl}/api/v1/workflows/forms/${formId}/fields`, { headers: headers() });
|
|
1734
|
+
return resp.json();
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
};
|
|
1738
|
+
|
|
1739
|
+
// src/skills.ts
|
|
1740
|
+
var DEFAULT_API26 = "https://be.graph8.com";
|
|
1741
|
+
var createSkillsClient = (apiKey, apiUrl) => {
|
|
1742
|
+
const baseUrl = apiUrl || DEFAULT_API26;
|
|
1743
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1744
|
+
const toQuery = (params) => {
|
|
1745
|
+
const qs = new URLSearchParams();
|
|
1746
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1747
|
+
if (v != null) qs.set(k, String(v));
|
|
1748
|
+
}
|
|
1749
|
+
const s = qs.toString();
|
|
1750
|
+
return s ? `?${s}` : "";
|
|
1751
|
+
};
|
|
1752
|
+
return {
|
|
1753
|
+
/** List skills. */
|
|
1754
|
+
async list(params = {}) {
|
|
1755
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills${toQuery(params)}`, { headers: headers() });
|
|
1756
|
+
return resp.json();
|
|
1757
|
+
},
|
|
1758
|
+
/** Get a skill by ID. */
|
|
1759
|
+
async get(skillId) {
|
|
1760
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, { headers: headers() });
|
|
1761
|
+
const data = await resp.json();
|
|
1762
|
+
return data.data || data;
|
|
1763
|
+
},
|
|
1764
|
+
/** Get the variables required by a skill (extracted from prompt or body template). */
|
|
1765
|
+
async getVariables(skillId) {
|
|
1766
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/variables`, { headers: headers() });
|
|
1767
|
+
return resp.json();
|
|
1768
|
+
},
|
|
1769
|
+
/** List available LLM models. */
|
|
1770
|
+
async listModels() {
|
|
1771
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/models`, { headers: headers() });
|
|
1772
|
+
return resp.json();
|
|
1773
|
+
},
|
|
1774
|
+
/** List skill templates. */
|
|
1775
|
+
async listTemplates(params = {}) {
|
|
1776
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/templates${toQuery(params)}`, { headers: headers() });
|
|
1777
|
+
return resp.json();
|
|
1778
|
+
},
|
|
1779
|
+
/** Create an LLM skill (prompt + model + schemas). */
|
|
1780
|
+
async createLLM(params) {
|
|
1781
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills`, {
|
|
1782
|
+
method: "POST",
|
|
1783
|
+
headers: headers(),
|
|
1784
|
+
body: JSON.stringify({ ...params, type: "llm" })
|
|
1785
|
+
});
|
|
1786
|
+
const data = await resp.json();
|
|
1787
|
+
return data.data || data;
|
|
1788
|
+
},
|
|
1789
|
+
/** Create an API skill (HTTP request wrapper). */
|
|
1790
|
+
async createAPI(params) {
|
|
1791
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills`, {
|
|
1792
|
+
method: "POST",
|
|
1793
|
+
headers: headers(),
|
|
1794
|
+
body: JSON.stringify({ ...params, type: "api" })
|
|
1795
|
+
});
|
|
1796
|
+
const data = await resp.json();
|
|
1797
|
+
return data.data || data;
|
|
1798
|
+
},
|
|
1799
|
+
/** Create a skill from a built-in template. */
|
|
1800
|
+
async createFromTemplate(params) {
|
|
1801
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/from-template`, {
|
|
1802
|
+
method: "POST",
|
|
1803
|
+
headers: headers(),
|
|
1804
|
+
body: JSON.stringify(params)
|
|
1805
|
+
});
|
|
1806
|
+
const data = await resp.json();
|
|
1807
|
+
return data.data || data;
|
|
1808
|
+
},
|
|
1809
|
+
/** Lift a workflow node into a reusable skill. */
|
|
1810
|
+
async createFromNode(params) {
|
|
1811
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/from-node`, {
|
|
1812
|
+
method: "POST",
|
|
1813
|
+
headers: headers(),
|
|
1814
|
+
body: JSON.stringify(params)
|
|
1815
|
+
});
|
|
1816
|
+
const data = await resp.json();
|
|
1817
|
+
return data.data || data;
|
|
1818
|
+
},
|
|
1819
|
+
/** Update an LLM skill. */
|
|
1820
|
+
async updateLLM(skillId, fields) {
|
|
1821
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {
|
|
1822
|
+
method: "PUT",
|
|
1823
|
+
headers: headers(),
|
|
1824
|
+
body: JSON.stringify({ ...fields, type: "llm" })
|
|
1825
|
+
});
|
|
1826
|
+
const data = await resp.json();
|
|
1827
|
+
return data.data || data;
|
|
1828
|
+
},
|
|
1829
|
+
/** Update an API skill. */
|
|
1830
|
+
async updateAPI(skillId, fields) {
|
|
1831
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {
|
|
1832
|
+
method: "PUT",
|
|
1833
|
+
headers: headers(),
|
|
1834
|
+
body: JSON.stringify({ ...fields, type: "api" })
|
|
1835
|
+
});
|
|
1836
|
+
const data = await resp.json();
|
|
1837
|
+
return data.data || data;
|
|
1838
|
+
},
|
|
1839
|
+
/** Delete a skill (irreversible if in-use workflows exist). */
|
|
1840
|
+
async delete(skillId) {
|
|
1841
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {
|
|
1842
|
+
method: "DELETE",
|
|
1843
|
+
headers: headers()
|
|
1844
|
+
});
|
|
1845
|
+
return resp.json();
|
|
1846
|
+
},
|
|
1847
|
+
/** Validate a skill definition (without saving). */
|
|
1848
|
+
async validate(skill) {
|
|
1849
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/validate`, {
|
|
1850
|
+
method: "POST",
|
|
1851
|
+
headers: headers(),
|
|
1852
|
+
body: JSON.stringify(skill)
|
|
1853
|
+
});
|
|
1854
|
+
return resp.json();
|
|
1855
|
+
},
|
|
1856
|
+
/** Execute a skill immediately with an input payload (test / preview). */
|
|
1857
|
+
async execute(skillId, inputPayload) {
|
|
1858
|
+
const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/execute`, {
|
|
1859
|
+
method: "POST",
|
|
1860
|
+
headers: headers(),
|
|
1861
|
+
body: JSON.stringify(inputPayload)
|
|
1862
|
+
});
|
|
1863
|
+
return resp.json();
|
|
1864
|
+
}
|
|
1865
|
+
};
|
|
1866
|
+
};
|
|
1867
|
+
|
|
1868
|
+
// src/intent.ts
|
|
1869
|
+
var DEFAULT_API27 = "https://be.graph8.com";
|
|
1870
|
+
var createIntentClient = (apiKey, apiUrl) => {
|
|
1871
|
+
const baseUrl = apiUrl || DEFAULT_API27;
|
|
1872
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1873
|
+
const get = async (path) => {
|
|
1874
|
+
const resp = await fetch(`${baseUrl}/api/v1${path}`, { headers: headers() });
|
|
1875
|
+
return resp.json();
|
|
1876
|
+
};
|
|
1877
|
+
const post = async (path, body = {}) => {
|
|
1878
|
+
const resp = await fetch(`${baseUrl}/api/v1${path}`, {
|
|
1879
|
+
method: "POST",
|
|
1880
|
+
headers: headers(),
|
|
1881
|
+
body: JSON.stringify(body)
|
|
1882
|
+
});
|
|
1883
|
+
return resp.json();
|
|
1884
|
+
};
|
|
1885
|
+
const del = async (path) => {
|
|
1886
|
+
const resp = await fetch(`${baseUrl}/api/v1${path}`, { method: "DELETE", headers: headers() });
|
|
1887
|
+
return resp.json();
|
|
1888
|
+
};
|
|
1889
|
+
return {
|
|
1890
|
+
/** Org-level intent stats (totals over the last 30 days). */
|
|
1891
|
+
async stats() {
|
|
1892
|
+
return get("/intent/stats");
|
|
1893
|
+
},
|
|
1894
|
+
/** List tracked keywords with optional pagination. */
|
|
1895
|
+
async listKeywords(params = {}) {
|
|
1896
|
+
return post("/intent/keywords/list", params);
|
|
1897
|
+
},
|
|
1898
|
+
/** Create a keyword group from a domain (auto-tracks all pages). */
|
|
1899
|
+
async createFromDomain(domain) {
|
|
1900
|
+
return post("/intent/keywords/create-from-domain", { domain });
|
|
1901
|
+
},
|
|
1902
|
+
/** Stop tracking a keyword (irreversible — historical data is retained). */
|
|
1903
|
+
async deleteKeyword(keywordId) {
|
|
1904
|
+
return del(`/intent/keywords/${keywordId}`);
|
|
1905
|
+
},
|
|
1906
|
+
/** Companies showing interest in a tracked keyword. */
|
|
1907
|
+
async keywordCompanies(keywordId, params = {}) {
|
|
1908
|
+
return post(`/intent/keywords/${keywordId}/companies`, params);
|
|
1909
|
+
},
|
|
1910
|
+
/** Contacts showing interest in a tracked keyword. */
|
|
1911
|
+
async keywordContacts(keywordId, params = {}) {
|
|
1912
|
+
return post(`/intent/keywords/${keywordId}/contacts`, params);
|
|
1913
|
+
},
|
|
1914
|
+
/** URLs associated with a keyword (pages visitors landed on while interested). */
|
|
1915
|
+
async keywordUrls(keywordId, params = {}) {
|
|
1916
|
+
return post(`/intent/keywords/${keywordId}/urls`, params);
|
|
1917
|
+
},
|
|
1918
|
+
/** Pages tracked on a specific domain. */
|
|
1919
|
+
async pagesByDomain(domain, params = {}) {
|
|
1920
|
+
return post("/intent/pages-by-domain", { domain, ...params });
|
|
1921
|
+
},
|
|
1922
|
+
/** Search tracked pages by URL fragment or keyword. */
|
|
1923
|
+
async searchPages(query, params = {}) {
|
|
1924
|
+
return post("/intent/pages/search", { query, ...params });
|
|
1925
|
+
},
|
|
1926
|
+
/** Get visitor records for a specific page URL. */
|
|
1927
|
+
async pageVisitors(pageUrl, params = {}) {
|
|
1928
|
+
return post("/intent/pages/visitors", { url: pageUrl, ...params });
|
|
1929
|
+
},
|
|
1930
|
+
/** Get contacts who visited a specific page URL. */
|
|
1931
|
+
async pageContacts(pageUrl, params = {}) {
|
|
1932
|
+
return post("/intent/pages/contacts", { url: pageUrl, ...params });
|
|
1933
|
+
},
|
|
1934
|
+
/** Visitor count aggregates by page (pass an array of URLs). */
|
|
1935
|
+
async pageVisitorCounts(urls) {
|
|
1936
|
+
return post("/intent/pages/visitor-counts", { urls });
|
|
1937
|
+
},
|
|
1938
|
+
/**
|
|
1939
|
+
* Find companies whose users visited a specific URL (intent search).
|
|
1940
|
+
*
|
|
1941
|
+
* Note: this endpoint lives at the bare host (no `/api/v1` prefix), unlike the rest
|
|
1942
|
+
* of the intent surface — we call it directly here instead of through the shared `post()` helper.
|
|
1943
|
+
*/
|
|
1944
|
+
async urlCompanies(url, params = {}) {
|
|
1945
|
+
const resp = await fetch(`${baseUrl}/intent-search/url-companies`, {
|
|
1946
|
+
method: "POST",
|
|
1947
|
+
headers: headers(),
|
|
1948
|
+
body: JSON.stringify({ url, ...params })
|
|
1949
|
+
});
|
|
1950
|
+
return resp.json();
|
|
1951
|
+
}
|
|
1952
|
+
};
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
// src/studio.ts
|
|
1956
|
+
var DEFAULT_API28 = "https://be.graph8.com";
|
|
1957
|
+
var createStudioClient = (apiKey, apiUrl) => {
|
|
1958
|
+
const baseUrl = apiUrl || DEFAULT_API28;
|
|
1959
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1960
|
+
const toQuery = (params) => {
|
|
1961
|
+
const qs = new URLSearchParams();
|
|
1962
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1963
|
+
if (v != null) qs.set(k, String(v));
|
|
1964
|
+
}
|
|
1965
|
+
const s = qs.toString();
|
|
1966
|
+
return s ? `?${s}` : "";
|
|
1967
|
+
};
|
|
1968
|
+
const get = async (path, params = {}) => {
|
|
1969
|
+
const resp = await fetch(`${baseUrl}/api/v1${path}${toQuery(params)}`, { headers: headers() });
|
|
1970
|
+
return resp.json();
|
|
1971
|
+
};
|
|
1972
|
+
return {
|
|
1973
|
+
/** Org-level Studio documents (brand_brief, value_props, messaging_house, etc.). */
|
|
1974
|
+
async globalContext(params = {}) {
|
|
1975
|
+
return get("/global-context/documents", params);
|
|
1976
|
+
},
|
|
1977
|
+
/** ICP definitions. */
|
|
1978
|
+
async icps(params = {}) {
|
|
1979
|
+
return get("/icps", params);
|
|
1980
|
+
},
|
|
1981
|
+
/** Buyer persona definitions. */
|
|
1982
|
+
async personas(params = {}) {
|
|
1983
|
+
return get("/personas", params);
|
|
1984
|
+
},
|
|
1985
|
+
/** Intelligence data (website scrapes, enrichment, competitor research). */
|
|
1986
|
+
async intelligenceData(params = {}) {
|
|
1987
|
+
return get("/intelligence-data", params);
|
|
1988
|
+
},
|
|
1989
|
+
/** AI research reports (buyer psychology, competitive teardown, GTM channel, etc.). */
|
|
1990
|
+
async researchReports(params = {}) {
|
|
1991
|
+
return get("/research-reports", params);
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
};
|
|
1995
|
+
|
|
1996
|
+
// src/meetings.ts
|
|
1997
|
+
var DEFAULT_API29 = "https://be.graph8.com";
|
|
1998
|
+
var createMeetingsClient = (apiKey, apiUrl) => {
|
|
1999
|
+
const baseUrl = apiUrl || DEFAULT_API29;
|
|
2000
|
+
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
2001
|
+
const toQuery = (params) => {
|
|
2002
|
+
const qs = new URLSearchParams();
|
|
2003
|
+
for (const [k, v] of Object.entries(params)) {
|
|
2004
|
+
if (v != null) qs.set(k, String(v));
|
|
2005
|
+
}
|
|
2006
|
+
const s = qs.toString();
|
|
2007
|
+
return s ? `?${s}` : "";
|
|
2008
|
+
};
|
|
2009
|
+
return {
|
|
2010
|
+
/** List meetings with optional filters. Returns summary rows without transcript / analysis. */
|
|
2011
|
+
async list(params = {}) {
|
|
2012
|
+
const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings${toQuery(params)}`, { headers: headers() });
|
|
2013
|
+
return resp.json();
|
|
2014
|
+
},
|
|
2015
|
+
/** Get full meeting detail including transcript + AI analysis (transcript available 1-5 min after meeting ends). */
|
|
2016
|
+
async get(meetingId) {
|
|
2017
|
+
const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings/${meetingId}`, { headers: headers() });
|
|
2018
|
+
const data = await resp.json();
|
|
2019
|
+
return data.data || data;
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
};
|
|
2023
|
+
|
|
2024
|
+
// src/core.ts
|
|
2025
|
+
var DEFAULT_HOST = "https://t.graph8.com";
|
|
2026
|
+
var DEFAULT_API30 = "https://be.graph8.com";
|
|
2027
|
+
var G8 = class {
|
|
2028
|
+
constructor() {
|
|
2029
|
+
/** @internal */
|
|
2030
|
+
this.client = null;
|
|
2031
|
+
/** @internal */
|
|
2032
|
+
this.config = null;
|
|
2033
|
+
/** @internal */
|
|
2034
|
+
this._forms = null;
|
|
2035
|
+
/** @internal */
|
|
2036
|
+
this._visitors = null;
|
|
2037
|
+
/** @internal */
|
|
2038
|
+
this._copilot = null;
|
|
2039
|
+
/** @internal */
|
|
2040
|
+
this._chat = null;
|
|
2041
|
+
/** @internal */
|
|
2042
|
+
this._calendar = null;
|
|
2043
|
+
/** @internal */
|
|
2044
|
+
this._enrich = null;
|
|
2045
|
+
/** @internal */
|
|
2046
|
+
this._sequences = null;
|
|
2047
|
+
/** @internal */
|
|
2048
|
+
this._campaigns = null;
|
|
2049
|
+
/** @internal */
|
|
2050
|
+
this._integrations = null;
|
|
2051
|
+
/** @internal */
|
|
2052
|
+
this._signals = null;
|
|
2053
|
+
/** @internal */
|
|
2054
|
+
this._analytics = null;
|
|
2055
|
+
/** @internal */
|
|
2056
|
+
this._voice = null;
|
|
2057
|
+
/** @internal */
|
|
2058
|
+
this._pages = null;
|
|
2059
|
+
/** @internal */
|
|
2060
|
+
this._webhooks = null;
|
|
2061
|
+
/** @internal */
|
|
2062
|
+
this._contacts = null;
|
|
2063
|
+
/** @internal */
|
|
2064
|
+
this._companies = null;
|
|
2065
|
+
/** @internal */
|
|
2066
|
+
this._lists = null;
|
|
2067
|
+
/** @internal */
|
|
2068
|
+
this._notes = null;
|
|
2069
|
+
/** @internal */
|
|
2070
|
+
this._tasks = null;
|
|
2071
|
+
/** @internal */
|
|
2072
|
+
this._fields = null;
|
|
2073
|
+
/** @internal */
|
|
2074
|
+
this._deals = null;
|
|
2075
|
+
/** @internal */
|
|
2076
|
+
this._inbox = null;
|
|
2077
|
+
/** @internal */
|
|
2078
|
+
this._quotes = null;
|
|
2079
|
+
/** @internal */
|
|
2080
|
+
this._pipelines = null;
|
|
2081
|
+
/** @internal */
|
|
2082
|
+
this._workflows = null;
|
|
2083
|
+
/** @internal */
|
|
2084
|
+
this._skills = null;
|
|
2085
|
+
/** @internal */
|
|
2086
|
+
this._intent = null;
|
|
2087
|
+
/** @internal */
|
|
2088
|
+
this._studio = null;
|
|
2089
|
+
/** @internal */
|
|
2090
|
+
this._meetings = null;
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Initialize the graph8 SDK. Must be called before any other method.
|
|
2094
|
+
* Safe to call on the server (SSR) - becomes a no-op for tracking.
|
|
2095
|
+
*/
|
|
2096
|
+
init(config) {
|
|
2097
|
+
this.config = config;
|
|
2098
|
+
if (!isServer) {
|
|
2099
|
+
this.client = jitsuAnalytics({
|
|
2100
|
+
host: config.host || DEFAULT_HOST,
|
|
2101
|
+
writeKey: config.writeKey || "",
|
|
2102
|
+
debug: config.debug
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
const apiUrl = config.apiUrl || DEFAULT_API30;
|
|
2106
|
+
const writeKey = config.writeKey || "";
|
|
2107
|
+
const apiKey = config.apiKey || "";
|
|
2108
|
+
if (writeKey) {
|
|
2109
|
+
this._forms = createFormsClient(writeKey, apiUrl);
|
|
2110
|
+
this._visitors = createVisitorsClient(writeKey, apiUrl);
|
|
2111
|
+
this._copilot = createCopilotClient(writeKey, apiUrl);
|
|
2112
|
+
this._chat = createChatClient(writeKey, apiUrl);
|
|
2113
|
+
this._calendar = createCalendarClient(apiUrl);
|
|
2114
|
+
this._signals = createSignalsClient(writeKey, false, apiUrl);
|
|
2115
|
+
}
|
|
2116
|
+
if (apiKey) {
|
|
2117
|
+
this._enrich = createEnrichClient(apiKey, apiUrl);
|
|
2118
|
+
this._sequences = createSequencesClient(apiKey, apiUrl);
|
|
2119
|
+
this._campaigns = createCampaignsClient(apiKey, apiUrl);
|
|
2120
|
+
this._integrations = createIntegrationsClient(apiKey, apiUrl);
|
|
2121
|
+
this._analytics = createAnalyticsClient(apiKey, apiUrl);
|
|
2122
|
+
this._voice = createVoiceClient(apiKey, apiUrl);
|
|
2123
|
+
this._pages = createPagesClient(apiKey, apiUrl);
|
|
2124
|
+
this._webhooks = createWebhooksClient(apiKey, apiUrl);
|
|
2125
|
+
this._contacts = createContactsClient(apiKey, apiUrl);
|
|
2126
|
+
this._companies = createCompaniesClient(apiKey, apiUrl);
|
|
2127
|
+
this._lists = createListsClient(apiKey, apiUrl);
|
|
2128
|
+
this._notes = createNotesClient(apiKey, apiUrl);
|
|
2129
|
+
this._tasks = createTasksClient(apiKey, apiUrl);
|
|
2130
|
+
this._fields = createFieldsClient(apiKey, apiUrl);
|
|
1108
2131
|
this._deals = createDealsClient(apiKey, apiUrl);
|
|
2132
|
+
this._inbox = createInboxClient(apiKey, apiUrl);
|
|
2133
|
+
this._quotes = createQuotesClient(apiKey, apiUrl);
|
|
2134
|
+
this._pipelines = createPipelinesClient(apiKey, apiUrl);
|
|
2135
|
+
this._workflows = createWorkflowsClient(apiKey, apiUrl);
|
|
2136
|
+
this._skills = createSkillsClient(apiKey, apiUrl);
|
|
2137
|
+
this._intent = createIntentClient(apiKey, apiUrl);
|
|
2138
|
+
this._studio = createStudioClient(apiKey, apiUrl);
|
|
2139
|
+
this._meetings = createMeetingsClient(apiKey, apiUrl);
|
|
1109
2140
|
this._signals = createSignalsClient(apiKey, true, apiUrl);
|
|
1110
2141
|
}
|
|
1111
2142
|
}
|
|
@@ -1232,6 +2263,46 @@ var G8 = class {
|
|
|
1232
2263
|
this._assertKey("deals");
|
|
1233
2264
|
return this._deals;
|
|
1234
2265
|
}
|
|
2266
|
+
/** Multi-channel inbox — read + reply across email, SMS, LinkedIn (requires API key). */
|
|
2267
|
+
get inbox() {
|
|
2268
|
+
this._assertKey("inbox");
|
|
2269
|
+
return this._inbox;
|
|
2270
|
+
}
|
|
2271
|
+
/** Quote-to-cash: draft, send, sign, payment-link quotes (requires API key). */
|
|
2272
|
+
get quotes() {
|
|
2273
|
+
this._assertKey("quotes");
|
|
2274
|
+
return this._quotes;
|
|
2275
|
+
}
|
|
2276
|
+
/** Stage Checklist v2 pipelines: workflow stages with evidence + scripts (requires API key). */
|
|
2277
|
+
get pipelines() {
|
|
2278
|
+
this._assertKey("pipelines");
|
|
2279
|
+
return this._pipelines;
|
|
2280
|
+
}
|
|
2281
|
+
/** Workflow builder — multi-node automation graphs with execution lifecycle (requires API key). */
|
|
2282
|
+
get workflows() {
|
|
2283
|
+
this._assertKey("workflows");
|
|
2284
|
+
return this._workflows;
|
|
2285
|
+
}
|
|
2286
|
+
/** Skill authoring — LLM and API building blocks that workflows compose (requires API key). */
|
|
2287
|
+
get skills() {
|
|
2288
|
+
this._assertKey("skills");
|
|
2289
|
+
return this._skills;
|
|
2290
|
+
}
|
|
2291
|
+
/** Intent tracking — keyword groups, page visitors, account-level intent (requires API key). */
|
|
2292
|
+
get intent() {
|
|
2293
|
+
this._assertKey("intent");
|
|
2294
|
+
return this._intent;
|
|
2295
|
+
}
|
|
2296
|
+
/** Studio context — ICPs, personas, brand briefs, intelligence, AI research reports (requires API key). */
|
|
2297
|
+
get studio() {
|
|
2298
|
+
this._assertKey("studio");
|
|
2299
|
+
return this._studio;
|
|
2300
|
+
}
|
|
2301
|
+
/** Meetings — read scheduled, completed, cancelled meetings with transcripts + AI analysis (requires API key). */
|
|
2302
|
+
get meetings() {
|
|
2303
|
+
this._assertKey("meetings");
|
|
2304
|
+
return this._meetings;
|
|
2305
|
+
}
|
|
1235
2306
|
/** Whether the SDK has been initialized. */
|
|
1236
2307
|
get initialized() {
|
|
1237
2308
|
return this.config !== null;
|