@graph8/sdk 0.5.3 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -5
- package/dist/index.d.mts +575 -53
- package/dist/index.d.ts +575 -53
- package/dist/index.js +911 -897
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +901 -896
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +450 -37
- package/dist/react.d.ts +450 -37
- package/dist/react.js +881 -895
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +881 -895
- package/dist/react.mjs.map +1 -1
- package/package.json +24 -7
package/dist/index.js
CHANGED
|
@@ -20,7 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
G8Error: () => G8Error,
|
|
24
|
+
KNOWN_WEBHOOK_EVENTS: () => KNOWN_WEBHOOK_EVENTS,
|
|
25
|
+
WebhookSignatureError: () => WebhookSignatureError,
|
|
26
|
+
backoffDelayMs: () => backoffDelayMs,
|
|
27
|
+
constructEvent: () => constructEvent,
|
|
28
|
+
g8: () => g8,
|
|
29
|
+
isRetryableStatus: () => isRetryableStatus,
|
|
30
|
+
paginate: () => paginate,
|
|
31
|
+
parseRetryAfter: () => parseRetryAfter,
|
|
32
|
+
request: () => request
|
|
24
33
|
});
|
|
25
34
|
module.exports = __toCommonJS(index_exports);
|
|
26
35
|
|
|
@@ -272,11 +281,11 @@ var createCalendarClient = (apiUrl) => {
|
|
|
272
281
|
return data.slots || data.data || [];
|
|
273
282
|
},
|
|
274
283
|
/** Book a meeting programmatically. */
|
|
275
|
-
async book(
|
|
284
|
+
async book(request2) {
|
|
276
285
|
const resp = await fetch(`${baseUrl}/appointments/public/bookings`, {
|
|
277
286
|
method: "POST",
|
|
278
287
|
headers: { "Content-Type": "application/json" },
|
|
279
|
-
body: JSON.stringify(
|
|
288
|
+
body: JSON.stringify(request2)
|
|
280
289
|
});
|
|
281
290
|
if (!resp.ok) return null;
|
|
282
291
|
const data = await resp.json();
|
|
@@ -292,54 +301,174 @@ var createCalendarClient = (apiUrl) => {
|
|
|
292
301
|
};
|
|
293
302
|
};
|
|
294
303
|
|
|
304
|
+
// src/http.ts
|
|
305
|
+
var G8Error = class _G8Error extends Error {
|
|
306
|
+
constructor(args) {
|
|
307
|
+
super(args.message);
|
|
308
|
+
this.name = "G8Error";
|
|
309
|
+
this.status = args.status;
|
|
310
|
+
this.type = args.type;
|
|
311
|
+
this.code = args.code;
|
|
312
|
+
this.requestId = args.requestId;
|
|
313
|
+
this.detail = args.detail;
|
|
314
|
+
this.retryable = args.retryable ?? false;
|
|
315
|
+
Object.setPrototypeOf(this, _G8Error.prototype);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
function isRetryableStatus(status) {
|
|
319
|
+
return status === 429 || status >= 500 && status <= 599;
|
|
320
|
+
}
|
|
321
|
+
function parseRetryAfter(header, nowMs = Date.now()) {
|
|
322
|
+
if (!header) return null;
|
|
323
|
+
const secs = Number(header);
|
|
324
|
+
if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1e3);
|
|
325
|
+
const dateMs = Date.parse(header);
|
|
326
|
+
if (!Number.isNaN(dateMs)) {
|
|
327
|
+
const delta = dateMs - nowMs;
|
|
328
|
+
return delta > 0 ? delta : 0;
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
function backoffDelayMs(attempt, baseMs = 200, rand = Math.random) {
|
|
333
|
+
const expo = Math.min(baseMs * 2 ** attempt, 1e4);
|
|
334
|
+
return Math.floor(expo / 2 + rand() * (expo / 2));
|
|
335
|
+
}
|
|
336
|
+
function defaultSleep(ms) {
|
|
337
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
338
|
+
}
|
|
339
|
+
function buildQuery(query) {
|
|
340
|
+
if (!query) return "";
|
|
341
|
+
const qs = new URLSearchParams();
|
|
342
|
+
for (const [k, v] of Object.entries(query)) {
|
|
343
|
+
if (v != null) qs.set(k, String(v));
|
|
344
|
+
}
|
|
345
|
+
const s = qs.toString();
|
|
346
|
+
return s ? `?${s}` : "";
|
|
347
|
+
}
|
|
348
|
+
async function toG8Error(resp) {
|
|
349
|
+
let body = void 0;
|
|
350
|
+
try {
|
|
351
|
+
const text = await resp.text();
|
|
352
|
+
body = text ? JSON.parse(text) : void 0;
|
|
353
|
+
} catch {
|
|
354
|
+
body = void 0;
|
|
355
|
+
}
|
|
356
|
+
const env = body ?? {};
|
|
357
|
+
const message = typeof env.message === "string" && env.message || typeof env.error === "string" && env.error || `Request failed with status ${resp.status}`;
|
|
358
|
+
return new G8Error({
|
|
359
|
+
message,
|
|
360
|
+
status: resp.status,
|
|
361
|
+
type: typeof env.type === "string" && env.type || typeof env.error === "string" && env.error || "api_error",
|
|
362
|
+
code: typeof env.code === "string" ? env.code : String(resp.status),
|
|
363
|
+
requestId: typeof env.request_id === "string" && env.request_id || resp.headers.get("x-request-id") || void 0,
|
|
364
|
+
detail: env.detail,
|
|
365
|
+
retryable: isRetryableStatus(resp.status)
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async function request(baseUrl, path, apiKey, opts = {}) {
|
|
369
|
+
const {
|
|
370
|
+
method = "GET",
|
|
371
|
+
body,
|
|
372
|
+
headers = {},
|
|
373
|
+
query,
|
|
374
|
+
idempotencyKey,
|
|
375
|
+
maxRetries = 2,
|
|
376
|
+
retryBaseMs = 200,
|
|
377
|
+
signal,
|
|
378
|
+
fetchImpl = fetch,
|
|
379
|
+
sleepImpl = defaultSleep
|
|
380
|
+
} = opts;
|
|
381
|
+
const url = baseUrl.replace(/\/+$/, "") + path + buildQuery(query);
|
|
382
|
+
const finalHeaders = {
|
|
383
|
+
"Content-Type": "application/json",
|
|
384
|
+
Authorization: `Bearer ${apiKey}`,
|
|
385
|
+
...headers
|
|
386
|
+
};
|
|
387
|
+
if (idempotencyKey) finalHeaders["Idempotency-Key"] = idempotencyKey;
|
|
388
|
+
let attempt = 0;
|
|
389
|
+
for (; ; ) {
|
|
390
|
+
let resp;
|
|
391
|
+
try {
|
|
392
|
+
resp = await fetchImpl(url, {
|
|
393
|
+
method,
|
|
394
|
+
headers: finalHeaders,
|
|
395
|
+
body: body == null ? void 0 : JSON.stringify(body),
|
|
396
|
+
signal
|
|
397
|
+
});
|
|
398
|
+
} catch (err) {
|
|
399
|
+
if (attempt < maxRetries) {
|
|
400
|
+
await sleepImpl(backoffDelayMs(attempt, retryBaseMs));
|
|
401
|
+
attempt++;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
throw new G8Error({
|
|
405
|
+
message: `Network error: ${err?.message ?? "request failed"}`,
|
|
406
|
+
status: 0,
|
|
407
|
+
type: "network_error",
|
|
408
|
+
retryable: true
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
if (resp.ok) {
|
|
412
|
+
const text = await resp.text();
|
|
413
|
+
return text ? JSON.parse(text) : void 0;
|
|
414
|
+
}
|
|
415
|
+
if (isRetryableStatus(resp.status) && attempt < maxRetries) {
|
|
416
|
+
const retryAfter = parseRetryAfter(resp.headers.get("retry-after"));
|
|
417
|
+
const delay = retryAfter != null ? retryAfter : backoffDelayMs(attempt, retryBaseMs);
|
|
418
|
+
await sleepImpl(delay);
|
|
419
|
+
attempt++;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
throw await toG8Error(resp);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
async function* paginate(fetchPage) {
|
|
426
|
+
let cursor = void 0;
|
|
427
|
+
for (; ; ) {
|
|
428
|
+
const page = await fetchPage(cursor);
|
|
429
|
+
for (const item of page.data ?? []) yield item;
|
|
430
|
+
const next = page.pagination?.next_cursor;
|
|
431
|
+
if (!next) break;
|
|
432
|
+
cursor = next;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
295
436
|
// src/enrich.ts
|
|
296
437
|
var DEFAULT_API6 = "https://be.graph8.com";
|
|
297
438
|
var createEnrichClient = (apiKey, apiUrl) => {
|
|
298
439
|
const baseUrl = apiUrl || DEFAULT_API6;
|
|
299
|
-
const headers = () => ({
|
|
300
|
-
"Content-Type": "application/json",
|
|
301
|
-
Authorization: `Bearer ${apiKey}`
|
|
302
|
-
});
|
|
303
440
|
return {
|
|
304
441
|
/** Look up a person by email, LinkedIn, or name + company. Costs 1 credit. */
|
|
305
442
|
async person(params) {
|
|
306
|
-
const resp = await
|
|
443
|
+
const resp = await request(baseUrl, "/api/v1/enrichment/lookup/person", apiKey, {
|
|
307
444
|
method: "POST",
|
|
308
|
-
|
|
309
|
-
body: JSON.stringify(params)
|
|
445
|
+
body: params
|
|
310
446
|
});
|
|
311
|
-
|
|
312
|
-
return data.data || data;
|
|
447
|
+
return resp.data ?? resp;
|
|
313
448
|
},
|
|
314
449
|
/** Look up a company by domain or name. Costs 1 credit. */
|
|
315
450
|
async company(params) {
|
|
316
|
-
const resp = await
|
|
451
|
+
const resp = await request(baseUrl, "/api/v1/enrichment/lookup/company", apiKey, {
|
|
317
452
|
method: "POST",
|
|
318
|
-
|
|
319
|
-
body: JSON.stringify(params)
|
|
453
|
+
body: params
|
|
320
454
|
});
|
|
321
|
-
|
|
322
|
-
return data.data || data;
|
|
455
|
+
return resp.data ?? resp;
|
|
323
456
|
},
|
|
324
457
|
/** Verify an email address. Costs 1 credit. */
|
|
325
458
|
async verifyEmail(email) {
|
|
326
|
-
const resp = await
|
|
459
|
+
const resp = await request(baseUrl, "/api/v1/enrichment/verify-email", apiKey, {
|
|
327
460
|
method: "POST",
|
|
328
|
-
|
|
329
|
-
body: JSON.stringify({ email })
|
|
461
|
+
body: { email }
|
|
330
462
|
});
|
|
331
|
-
|
|
332
|
-
return data.data || data;
|
|
463
|
+
return resp.data ?? resp;
|
|
333
464
|
},
|
|
334
465
|
/** Search 300M+ contacts with filters. Credits charged per result. */
|
|
335
466
|
async search(filters, page = 1, limit = 25) {
|
|
336
|
-
const resp = await
|
|
467
|
+
const resp = await request(baseUrl, "/api/v1/search/contacts", apiKey, {
|
|
337
468
|
method: "POST",
|
|
338
|
-
|
|
339
|
-
body: JSON.stringify({ filters, page, limit })
|
|
469
|
+
body: { filters, page, limit }
|
|
340
470
|
});
|
|
341
|
-
|
|
342
|
-
return data.data || data;
|
|
471
|
+
return resp.data ?? resp;
|
|
343
472
|
}
|
|
344
473
|
};
|
|
345
474
|
};
|
|
@@ -348,15 +477,6 @@ var createEnrichClient = (apiKey, apiUrl) => {
|
|
|
348
477
|
var DEFAULT_API7 = "https://be.graph8.com";
|
|
349
478
|
var createSequencesClient = (apiKey, apiUrl) => {
|
|
350
479
|
const baseUrl = apiUrl || DEFAULT_API7;
|
|
351
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
352
|
-
const toQuery = (params) => {
|
|
353
|
-
const qs = new URLSearchParams();
|
|
354
|
-
for (const [k, v] of Object.entries(params)) {
|
|
355
|
-
if (v != null) qs.set(k, String(v));
|
|
356
|
-
}
|
|
357
|
-
const s = qs.toString();
|
|
358
|
-
return s ? `?${s}` : "";
|
|
359
|
-
};
|
|
360
480
|
async function list(pageOrParams, limit) {
|
|
361
481
|
let params;
|
|
362
482
|
if (typeof pageOrParams === "number") {
|
|
@@ -364,118 +484,111 @@ var createSequencesClient = (apiKey, apiUrl) => {
|
|
|
364
484
|
} else {
|
|
365
485
|
params = pageOrParams ?? {};
|
|
366
486
|
}
|
|
367
|
-
const resp = await
|
|
368
|
-
|
|
369
|
-
|
|
487
|
+
const resp = await request(baseUrl, "/api/v1/sequences", apiKey, {
|
|
488
|
+
query: params
|
|
489
|
+
});
|
|
490
|
+
return resp.data ?? resp;
|
|
370
491
|
}
|
|
371
492
|
return {
|
|
372
493
|
/** List sequences with pagination + optional status filter. */
|
|
373
494
|
list,
|
|
374
495
|
/** Get full sequence details by ID. */
|
|
375
496
|
async get(sequenceId) {
|
|
376
|
-
const resp = await
|
|
377
|
-
|
|
378
|
-
return data.data || data;
|
|
497
|
+
const resp = await request(baseUrl, `/api/v1/sequences/${sequenceId}`, apiKey);
|
|
498
|
+
return resp.data ?? resp;
|
|
379
499
|
},
|
|
380
500
|
/** List contacts enrolled in a sequence. Filter by state (e.g. "active", "replied"). */
|
|
381
501
|
async contacts(sequenceId, params = {}) {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
);
|
|
386
|
-
return resp.json();
|
|
502
|
+
return request(baseUrl, `/api/v1/sequences/${sequenceId}/contacts`, apiKey, {
|
|
503
|
+
query: params
|
|
504
|
+
});
|
|
387
505
|
},
|
|
388
506
|
/** Add contacts to a sequence (V2 queuing). Live or drafted sequences only. */
|
|
389
507
|
async add(config) {
|
|
390
|
-
const resp = await
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return
|
|
508
|
+
const resp = await request(
|
|
509
|
+
baseUrl,
|
|
510
|
+
`/api/v1/sequences/${config.sequenceId}/contacts`,
|
|
511
|
+
apiKey,
|
|
512
|
+
{ method: "POST", body: { contact_ids: config.contactIds, list_id: config.listId } }
|
|
513
|
+
);
|
|
514
|
+
return resp.data ?? resp;
|
|
397
515
|
},
|
|
398
516
|
/** Create a new sequence with optional steps + channels. */
|
|
399
517
|
async create(payload) {
|
|
400
|
-
const resp = await
|
|
518
|
+
const resp = await request(baseUrl, "/api/v1/sequences", apiKey, {
|
|
401
519
|
method: "POST",
|
|
402
|
-
|
|
403
|
-
body: JSON.stringify(payload)
|
|
520
|
+
body: payload
|
|
404
521
|
});
|
|
405
|
-
|
|
406
|
-
return data.data || data;
|
|
522
|
+
return resp.data ?? resp;
|
|
407
523
|
},
|
|
408
524
|
/** Update sequence metadata. Rejected (409) if sequence is in a transitional status. */
|
|
409
525
|
async update(sequenceId, fields) {
|
|
410
|
-
const resp = await
|
|
526
|
+
const resp = await request(baseUrl, `/api/v1/sequences/${sequenceId}`, apiKey, {
|
|
411
527
|
method: "PATCH",
|
|
412
|
-
|
|
413
|
-
body: JSON.stringify(fields)
|
|
528
|
+
body: fields
|
|
414
529
|
});
|
|
415
|
-
|
|
416
|
-
return data.data || data;
|
|
530
|
+
return resp.data ?? resp;
|
|
417
531
|
},
|
|
418
532
|
/** Update a single step within a sequence. */
|
|
419
533
|
async updateStep(sequenceId, stepId, fields) {
|
|
420
|
-
const resp = await
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
return
|
|
534
|
+
const resp = await request(
|
|
535
|
+
baseUrl,
|
|
536
|
+
`/api/v1/sequences/${sequenceId}/steps/${stepId}`,
|
|
537
|
+
apiKey,
|
|
538
|
+
{ method: "PATCH", body: fields }
|
|
539
|
+
);
|
|
540
|
+
return resp.data ?? resp;
|
|
427
541
|
},
|
|
428
542
|
/** Soft-delete (archive) a sequence. */
|
|
429
543
|
async delete(sequenceId) {
|
|
430
|
-
const resp = await
|
|
431
|
-
method: "DELETE"
|
|
432
|
-
headers: headers()
|
|
544
|
+
const resp = await request(baseUrl, `/api/v1/sequences/${sequenceId}`, apiKey, {
|
|
545
|
+
method: "DELETE"
|
|
433
546
|
});
|
|
434
|
-
|
|
435
|
-
return data.data || data;
|
|
547
|
+
return resp.data ?? resp;
|
|
436
548
|
},
|
|
437
549
|
/** Run/start a DRAFTED sequence (V2 orchestration). */
|
|
438
550
|
async run(sequenceId) {
|
|
439
|
-
const resp = await
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
551
|
+
const resp = await request(
|
|
552
|
+
baseUrl,
|
|
553
|
+
`/api/v1/sequences/${sequenceId}/run`,
|
|
554
|
+
apiKey,
|
|
555
|
+
{ method: "POST" }
|
|
556
|
+
);
|
|
557
|
+
return resp.data ?? resp;
|
|
445
558
|
},
|
|
446
559
|
/** Pause a live sequence. */
|
|
447
560
|
async pause(sequenceId) {
|
|
448
|
-
const resp = await
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
561
|
+
const resp = await request(
|
|
562
|
+
baseUrl,
|
|
563
|
+
`/api/v1/sequences/${sequenceId}/pause`,
|
|
564
|
+
apiKey,
|
|
565
|
+
{ method: "POST" }
|
|
566
|
+
);
|
|
567
|
+
return resp.data ?? resp;
|
|
454
568
|
},
|
|
455
569
|
/** Resume a paused sequence. */
|
|
456
570
|
async resume(sequenceId) {
|
|
457
|
-
const resp = await
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
571
|
+
const resp = await request(
|
|
572
|
+
baseUrl,
|
|
573
|
+
`/api/v1/sequences/${sequenceId}/resume`,
|
|
574
|
+
apiKey,
|
|
575
|
+
{ method: "POST" }
|
|
576
|
+
);
|
|
577
|
+
return resp.data ?? resp;
|
|
463
578
|
},
|
|
464
579
|
/** Read-only sequence preview with all steps + channels (no enrollment). */
|
|
465
580
|
async preview(sequenceId) {
|
|
466
|
-
const resp = await
|
|
467
|
-
|
|
468
|
-
});
|
|
469
|
-
const data = await resp.json();
|
|
470
|
-
return data.data || data;
|
|
581
|
+
const resp = await request(baseUrl, `/api/v1/sequences/${sequenceId}/preview`, apiKey);
|
|
582
|
+
return resp.data ?? resp;
|
|
471
583
|
},
|
|
472
584
|
/** Comprehensive analytics for a sequence. */
|
|
473
585
|
async analytics(sequenceId) {
|
|
474
|
-
const resp = await
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
586
|
+
const resp = await request(
|
|
587
|
+
baseUrl,
|
|
588
|
+
`/api/v1/sequences/${sequenceId}/analytics`,
|
|
589
|
+
apiKey
|
|
590
|
+
);
|
|
591
|
+
return resp.data ?? resp;
|
|
479
592
|
}
|
|
480
593
|
};
|
|
481
594
|
};
|
|
@@ -484,37 +597,30 @@ var createSequencesClient = (apiKey, apiUrl) => {
|
|
|
484
597
|
var DEFAULT_API8 = "https://be.graph8.com";
|
|
485
598
|
var createCampaignsClient = (apiKey, apiUrl) => {
|
|
486
599
|
const baseUrl = apiUrl || DEFAULT_API8;
|
|
487
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
488
600
|
return {
|
|
489
601
|
async list(page = 1, limit = 50) {
|
|
490
|
-
const resp = await
|
|
491
|
-
|
|
492
|
-
|
|
602
|
+
const resp = await request(baseUrl, "/api/v1/campaigns", apiKey, {
|
|
603
|
+
query: { page, limit }
|
|
604
|
+
});
|
|
605
|
+
return resp.data ?? resp;
|
|
493
606
|
},
|
|
494
607
|
async get(campaignId) {
|
|
495
|
-
const resp = await
|
|
496
|
-
|
|
497
|
-
return data.data || data;
|
|
608
|
+
const resp = await request(baseUrl, `/api/v1/campaigns/${campaignId}`, apiKey);
|
|
609
|
+
return resp.data ?? resp;
|
|
498
610
|
},
|
|
499
611
|
async create(config) {
|
|
500
|
-
const resp = await
|
|
612
|
+
const resp = await request(baseUrl, "/api/v1/campaigns", apiKey, {
|
|
501
613
|
method: "POST",
|
|
502
|
-
|
|
503
|
-
body: JSON.stringify(config)
|
|
614
|
+
body: config
|
|
504
615
|
});
|
|
505
|
-
|
|
506
|
-
return data.data || data;
|
|
616
|
+
return resp.data ?? resp;
|
|
507
617
|
},
|
|
508
618
|
async launch(campaignId) {
|
|
509
|
-
await
|
|
510
|
-
method: "POST",
|
|
511
|
-
headers: headers()
|
|
512
|
-
});
|
|
619
|
+
await request(baseUrl, `/api/v1/campaigns/${campaignId}/launch`, apiKey, { method: "POST" });
|
|
513
620
|
},
|
|
514
621
|
async stats(campaignId) {
|
|
515
|
-
const resp = await
|
|
516
|
-
|
|
517
|
-
return data.data || data;
|
|
622
|
+
const resp = await request(baseUrl, `/api/v1/campaigns/${campaignId}/stats`, apiKey);
|
|
623
|
+
return resp.data ?? resp;
|
|
518
624
|
}
|
|
519
625
|
};
|
|
520
626
|
};
|
|
@@ -523,25 +629,21 @@ var createCampaignsClient = (apiKey, apiUrl) => {
|
|
|
523
629
|
var DEFAULT_API9 = "https://be.graph8.com";
|
|
524
630
|
var createIntegrationsClient = (apiKey, apiUrl) => {
|
|
525
631
|
const baseUrl = apiUrl || DEFAULT_API9;
|
|
526
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
527
632
|
return {
|
|
528
633
|
async list() {
|
|
529
|
-
const resp = await
|
|
530
|
-
|
|
531
|
-
return data.data || data;
|
|
634
|
+
const resp = await request(baseUrl, "/api/v1/integrations", apiKey);
|
|
635
|
+
return resp.data ?? resp;
|
|
532
636
|
},
|
|
533
637
|
async connect(provider, config) {
|
|
534
|
-
await
|
|
638
|
+
await request(baseUrl, "/api/v1/integrations/connect", apiKey, {
|
|
535
639
|
method: "POST",
|
|
536
|
-
|
|
537
|
-
body: JSON.stringify({ provider, ...config })
|
|
640
|
+
body: { provider, ...config }
|
|
538
641
|
});
|
|
539
642
|
},
|
|
540
643
|
async sync(provider, config) {
|
|
541
|
-
await
|
|
644
|
+
await request(baseUrl, "/api/v1/integrations/sync", apiKey, {
|
|
542
645
|
method: "POST",
|
|
543
|
-
|
|
544
|
-
body: JSON.stringify({ provider, ...config })
|
|
646
|
+
body: { provider, ...config }
|
|
545
647
|
});
|
|
546
648
|
}
|
|
547
649
|
};
|
|
@@ -581,15 +683,12 @@ var createSignalsClient = (key, isApiKey, apiUrl) => {
|
|
|
581
683
|
var DEFAULT_API11 = "https://be.graph8.com";
|
|
582
684
|
var createAnalyticsClient = (apiKey, apiUrl) => {
|
|
583
685
|
const baseUrl = apiUrl || DEFAULT_API11;
|
|
584
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
585
686
|
return {
|
|
586
687
|
async overview(config) {
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const data = await resp.json();
|
|
592
|
-
return data.data || data;
|
|
688
|
+
const resp = await request(baseUrl, "/api/v1/analytics/overview", apiKey, {
|
|
689
|
+
query: { period: config?.period }
|
|
690
|
+
});
|
|
691
|
+
return resp.data ?? resp;
|
|
593
692
|
}
|
|
594
693
|
};
|
|
595
694
|
};
|
|
@@ -598,48 +697,37 @@ var createAnalyticsClient = (apiKey, apiUrl) => {
|
|
|
598
697
|
var DEFAULT_API12 = "https://be.graph8.com";
|
|
599
698
|
var createVoiceClient = (apiKey, apiUrl) => {
|
|
600
699
|
const baseUrl = apiUrl || DEFAULT_API12;
|
|
601
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
602
700
|
const listeners = /* @__PURE__ */ new Map();
|
|
603
|
-
const toQuery = (params) => {
|
|
604
|
-
const qs = new URLSearchParams();
|
|
605
|
-
for (const [k, v] of Object.entries(params)) {
|
|
606
|
-
if (v != null) qs.set(k, String(v));
|
|
607
|
-
}
|
|
608
|
-
const s = qs.toString();
|
|
609
|
-
return s ? `?${s}` : "";
|
|
610
|
-
};
|
|
611
701
|
const dialer = {
|
|
612
702
|
/** List parallel-dialer sessions with filters + pagination. */
|
|
613
703
|
async listSessions(params = {}) {
|
|
614
|
-
const resp = await
|
|
615
|
-
|
|
616
|
-
|
|
704
|
+
const resp = await request(
|
|
705
|
+
baseUrl,
|
|
706
|
+
"/api/v1/voice/dialer/sessions",
|
|
707
|
+
apiKey,
|
|
708
|
+
{ query: params }
|
|
617
709
|
);
|
|
618
|
-
|
|
619
|
-
return data.data || data;
|
|
710
|
+
return resp.data ?? resp;
|
|
620
711
|
},
|
|
621
712
|
/** Create a parallel-dialer session in PAUSED state. SDR opens UI to start dialing. */
|
|
622
713
|
async createSession(payload) {
|
|
623
|
-
const resp = await
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
return
|
|
714
|
+
const resp = await request(
|
|
715
|
+
baseUrl,
|
|
716
|
+
"/api/v1/voice/dialer/sessions",
|
|
717
|
+
apiKey,
|
|
718
|
+
{ method: "POST", body: payload }
|
|
719
|
+
);
|
|
720
|
+
return resp.data ?? resp;
|
|
630
721
|
},
|
|
631
722
|
/** Pause / resume / stop a dialer session via status flip. */
|
|
632
723
|
async updateSessionStatus(sessionId, status) {
|
|
633
|
-
const resp = await
|
|
634
|
-
|
|
635
|
-
{
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
body: JSON.stringify({ status })
|
|
639
|
-
}
|
|
724
|
+
const resp = await request(
|
|
725
|
+
baseUrl,
|
|
726
|
+
`/api/v1/voice/dialer/sessions/${sessionId}/status`,
|
|
727
|
+
apiKey,
|
|
728
|
+
{ method: "PATCH", body: { status } }
|
|
640
729
|
);
|
|
641
|
-
|
|
642
|
-
return data.data || data;
|
|
730
|
+
return resp.data ?? resp;
|
|
643
731
|
},
|
|
644
732
|
/**
|
|
645
733
|
* Resume a PAUSED dialer session. Auto-fetches the next batch from the source list,
|
|
@@ -647,94 +735,97 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
647
735
|
* @param maxContacts 1-4 (voice caps parallel dialing at 4). Default 4.
|
|
648
736
|
*/
|
|
649
737
|
async resumeSession(sessionId, maxContacts = 4) {
|
|
650
|
-
const resp = await
|
|
651
|
-
|
|
652
|
-
{
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
body: JSON.stringify({ max_contacts: maxContacts })
|
|
656
|
-
}
|
|
738
|
+
const resp = await request(
|
|
739
|
+
baseUrl,
|
|
740
|
+
`/api/v1/voice/dialer/sessions/${sessionId}/resume`,
|
|
741
|
+
apiKey,
|
|
742
|
+
{ method: "POST", body: { max_contacts: maxContacts } }
|
|
657
743
|
);
|
|
658
|
-
|
|
659
|
-
return data.data || data;
|
|
744
|
+
return resp.data ?? resp;
|
|
660
745
|
},
|
|
661
746
|
/** Aggregated dialer analytics (daily breakdown or total). */
|
|
662
747
|
async stats(params = {}) {
|
|
663
|
-
const resp = await
|
|
664
|
-
|
|
665
|
-
|
|
748
|
+
const resp = await request(
|
|
749
|
+
baseUrl,
|
|
750
|
+
"/api/v1/voice/dialer/stats",
|
|
751
|
+
apiKey,
|
|
752
|
+
{ query: params }
|
|
666
753
|
);
|
|
667
|
-
|
|
668
|
-
return data.data || data;
|
|
754
|
+
return resp.data ?? resp;
|
|
669
755
|
},
|
|
670
756
|
/** List dialer-eligible phone numbers with 7-day stats + daily limits. */
|
|
671
757
|
async numbers(userEmail) {
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
758
|
+
const resp = await request(
|
|
759
|
+
baseUrl,
|
|
760
|
+
"/api/v1/voice/dialer/numbers",
|
|
761
|
+
apiKey,
|
|
762
|
+
{ query: userEmail ? { user_email: userEmail } : {} }
|
|
676
763
|
);
|
|
677
|
-
|
|
678
|
-
return data.data || data;
|
|
764
|
+
return resp.data ?? resp;
|
|
679
765
|
},
|
|
680
766
|
/** List missed inbound callbacks with caller / contact info. */
|
|
681
767
|
async missedCallbacks(limit = 50) {
|
|
682
|
-
const resp = await
|
|
683
|
-
|
|
684
|
-
|
|
768
|
+
const resp = await request(
|
|
769
|
+
baseUrl,
|
|
770
|
+
"/api/v1/voice/dialer/missed-callbacks",
|
|
771
|
+
apiKey,
|
|
772
|
+
{ query: { limit } }
|
|
685
773
|
);
|
|
686
|
-
|
|
687
|
-
return data.data || data;
|
|
774
|
+
return resp.data ?? resp;
|
|
688
775
|
},
|
|
689
776
|
/** AI grading for a single dialer call (returns "pending" while in progress). */
|
|
690
777
|
async callGrading(roomName) {
|
|
691
|
-
const resp = await
|
|
692
|
-
|
|
693
|
-
{
|
|
778
|
+
const resp = await request(
|
|
779
|
+
baseUrl,
|
|
780
|
+
`/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/grading`,
|
|
781
|
+
apiKey
|
|
694
782
|
);
|
|
695
|
-
|
|
696
|
-
return data.data || data;
|
|
783
|
+
return resp.data ?? resp;
|
|
697
784
|
},
|
|
698
785
|
/** List voice agents available for dialer sessions (capped at 100; no pagination). */
|
|
699
786
|
async agents(params = {}) {
|
|
700
|
-
const resp = await
|
|
701
|
-
|
|
702
|
-
|
|
787
|
+
const resp = await request(
|
|
788
|
+
baseUrl,
|
|
789
|
+
"/api/v1/voice/dialer/agents",
|
|
790
|
+
apiKey,
|
|
791
|
+
{ query: params }
|
|
703
792
|
);
|
|
704
|
-
|
|
705
|
-
return data.data || data;
|
|
793
|
+
return resp.data ?? resp;
|
|
706
794
|
},
|
|
707
795
|
/** Fetch the full transcript for a single dialer call. */
|
|
708
796
|
async callTranscript(roomName) {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
{
|
|
797
|
+
return request(
|
|
798
|
+
baseUrl,
|
|
799
|
+
`/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/transcript`,
|
|
800
|
+
apiKey
|
|
712
801
|
);
|
|
713
|
-
return resp.json();
|
|
714
802
|
},
|
|
715
803
|
/** List dialer calls — pass `contact_id` or `user_email` to scope. */
|
|
716
804
|
async listCalls(params = {}) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
805
|
+
return request(
|
|
806
|
+
baseUrl,
|
|
807
|
+
"/api/v1/voice/dialer/calls",
|
|
808
|
+
apiKey,
|
|
809
|
+
{ query: params }
|
|
720
810
|
);
|
|
721
|
-
return resp.json();
|
|
722
811
|
},
|
|
723
812
|
/** Convenience: list calls for a single contact. */
|
|
724
813
|
async listCallsForContact(contactId, extra = {}) {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
814
|
+
return request(
|
|
815
|
+
baseUrl,
|
|
816
|
+
"/api/v1/voice/dialer/calls",
|
|
817
|
+
apiKey,
|
|
818
|
+
{ query: { contact_id: contactId, ...extra } }
|
|
728
819
|
);
|
|
729
|
-
return resp.json();
|
|
730
820
|
},
|
|
731
821
|
/** Convenience: list calls placed by a specific SDR. */
|
|
732
822
|
async listCallsForSdr(userEmail, extra = {}) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
823
|
+
return request(
|
|
824
|
+
baseUrl,
|
|
825
|
+
"/api/v1/voice/dialer/calls",
|
|
826
|
+
apiKey,
|
|
827
|
+
{ query: { user_email: userEmail, ...extra } }
|
|
736
828
|
);
|
|
737
|
-
return resp.json();
|
|
738
829
|
}
|
|
739
830
|
};
|
|
740
831
|
return {
|
|
@@ -743,22 +834,25 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
743
834
|
* @deprecated Preview surface — for parallel-dialer flows use `voice.dialer.createSession()`.
|
|
744
835
|
*/
|
|
745
836
|
async start(config) {
|
|
746
|
-
const resp = await
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
return
|
|
837
|
+
const resp = await request(
|
|
838
|
+
baseUrl,
|
|
839
|
+
"/api/v1/voice/sessions",
|
|
840
|
+
apiKey,
|
|
841
|
+
{ method: "POST", body: config }
|
|
842
|
+
);
|
|
843
|
+
return resp.data ?? resp;
|
|
753
844
|
},
|
|
754
845
|
/**
|
|
755
846
|
* Get call analysis for a completed session.
|
|
756
847
|
* @deprecated Preview surface — for dialer-call grading use `voice.dialer.callGrading(roomName)`.
|
|
757
848
|
*/
|
|
758
849
|
async analysis(sessionId) {
|
|
759
|
-
const resp = await
|
|
760
|
-
|
|
761
|
-
|
|
850
|
+
const resp = await request(
|
|
851
|
+
baseUrl,
|
|
852
|
+
`/api/v1/voice/sessions/${sessionId}/analysis`,
|
|
853
|
+
apiKey
|
|
854
|
+
);
|
|
855
|
+
return resp.data ?? resp;
|
|
762
856
|
},
|
|
763
857
|
/** Listen for voice events. */
|
|
764
858
|
on(event, callback) {
|
|
@@ -774,75 +868,128 @@ var createVoiceClient = (apiKey, apiUrl) => {
|
|
|
774
868
|
var DEFAULT_API13 = "https://be.graph8.com";
|
|
775
869
|
var createPagesClient = (apiKey, apiUrl) => {
|
|
776
870
|
const baseUrl = apiUrl || DEFAULT_API13;
|
|
777
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
778
871
|
return {
|
|
779
872
|
/** Clone a landing page from any URL. */
|
|
780
873
|
async clone(url) {
|
|
781
|
-
const resp = await
|
|
874
|
+
const resp = await request(baseUrl, "/api/v1/landing-pages/clone-url", apiKey, {
|
|
782
875
|
method: "POST",
|
|
783
|
-
|
|
784
|
-
body: JSON.stringify({ url })
|
|
876
|
+
body: { url }
|
|
785
877
|
});
|
|
786
|
-
|
|
787
|
-
return data.data || data;
|
|
878
|
+
return resp.data ?? resp;
|
|
788
879
|
},
|
|
789
880
|
/** Create a landing page from a template. */
|
|
790
881
|
async create(config) {
|
|
791
|
-
const resp = await
|
|
882
|
+
const resp = await request(baseUrl, "/api/v1/landing-pages", apiKey, {
|
|
792
883
|
method: "POST",
|
|
793
|
-
|
|
794
|
-
body: JSON.stringify(config)
|
|
884
|
+
body: config
|
|
795
885
|
});
|
|
796
|
-
|
|
797
|
-
return data.data || data;
|
|
886
|
+
return resp.data ?? resp;
|
|
798
887
|
},
|
|
799
888
|
/** Publish a landing page to CDN. */
|
|
800
889
|
async publish(pageId) {
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
890
|
+
const data = await request(
|
|
891
|
+
baseUrl,
|
|
892
|
+
`/api/v1/landing-pages/${pageId}/publish`,
|
|
893
|
+
apiKey,
|
|
894
|
+
{ method: "POST" }
|
|
895
|
+
);
|
|
806
896
|
return { url: data.published_url || data.data?.published_url || "" };
|
|
807
897
|
}
|
|
808
898
|
};
|
|
809
899
|
};
|
|
810
900
|
|
|
811
901
|
// src/webhooks.ts
|
|
902
|
+
var import_node_crypto = require("crypto");
|
|
812
903
|
var DEFAULT_API14 = "https://be.graph8.com";
|
|
813
|
-
var
|
|
904
|
+
var KNOWN_WEBHOOK_EVENTS = [
|
|
905
|
+
"campaign.created",
|
|
906
|
+
"campaign.updated",
|
|
907
|
+
"campaign.deleted",
|
|
908
|
+
"campaign.launched",
|
|
909
|
+
"campaign.paused",
|
|
910
|
+
"campaign.completed",
|
|
911
|
+
"campaign.status_changed",
|
|
912
|
+
"campaign.content_ready",
|
|
913
|
+
"document.generated",
|
|
914
|
+
"document.failed",
|
|
915
|
+
"intelligence.completed",
|
|
916
|
+
"intelligence.failed",
|
|
917
|
+
"company.enriched",
|
|
918
|
+
"company_intelligence.completed",
|
|
919
|
+
"audience.ready",
|
|
920
|
+
"audience.failed",
|
|
921
|
+
"sequence.deployed",
|
|
922
|
+
"sequence.started",
|
|
923
|
+
"sequence.paused",
|
|
924
|
+
"sequence.completed",
|
|
925
|
+
"engagement.email_sent",
|
|
926
|
+
"engagement.email_replied",
|
|
927
|
+
"engagement.email_bounced",
|
|
928
|
+
"engagement.email_skipped",
|
|
929
|
+
"engagement.call_dispatched",
|
|
930
|
+
"engagement.sms_sent",
|
|
931
|
+
"engagement.sms_replied",
|
|
932
|
+
"engagement.whatsapp_sent",
|
|
933
|
+
"engagement.linkedin_connection_sent",
|
|
934
|
+
"engagement.linkedin_message_sent",
|
|
935
|
+
"engagement.linkedin_inmail_sent",
|
|
936
|
+
"engagement.linkedin_reply_received",
|
|
937
|
+
"engagement.linkedin_connection_accepted",
|
|
938
|
+
"meeting.booked",
|
|
939
|
+
"meeting.cancelled",
|
|
940
|
+
"meeting.rescheduled"
|
|
941
|
+
];
|
|
942
|
+
var WebhookSignatureError = class extends Error {
|
|
943
|
+
constructor(message) {
|
|
944
|
+
super(message);
|
|
945
|
+
this.name = "WebhookSignatureError";
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
function timingSafeEqualHex(a, b) {
|
|
949
|
+
if (a.length !== b.length) return false;
|
|
950
|
+
try {
|
|
951
|
+
const enc = new TextEncoder();
|
|
952
|
+
return (0, import_node_crypto.timingSafeEqual)(enc.encode(a), enc.encode(b));
|
|
953
|
+
} catch {
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
function constructEvent(payload, signature, timestamp, secret, opts = {}) {
|
|
958
|
+
if (!signature) throw new WebhookSignatureError("Missing X-Studio-Signature header");
|
|
959
|
+
if (timestamp === void 0 || timestamp === null || timestamp === "") {
|
|
960
|
+
throw new WebhookSignatureError("Missing X-Studio-Timestamp header");
|
|
961
|
+
}
|
|
962
|
+
if (!secret) throw new WebhookSignatureError("Missing signing secret");
|
|
963
|
+
const ts = typeof timestamp === "number" ? timestamp : parseInt(timestamp, 10);
|
|
964
|
+
if (!Number.isFinite(ts)) throw new WebhookSignatureError("Invalid X-Studio-Timestamp header");
|
|
965
|
+
const tolerance = opts.toleranceSeconds ?? 0;
|
|
966
|
+
if (tolerance > 0) {
|
|
967
|
+
const ageSeconds = Math.floor(Date.now() / 1e3) - ts;
|
|
968
|
+
if (Math.abs(ageSeconds) > tolerance) {
|
|
969
|
+
throw new WebhookSignatureError(`Timestamp outside tolerance (${ageSeconds}s > ${tolerance}s)`);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
const expected = (0, import_node_crypto.createHmac)("sha256", secret).update(`${ts}.${payload}`).digest("hex");
|
|
973
|
+
const provided = signature.startsWith("sha256=") ? signature.slice(7) : signature;
|
|
974
|
+
if (!timingSafeEqualHex(expected, provided)) {
|
|
975
|
+
throw new WebhookSignatureError("Signature verification failed");
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
return JSON.parse(payload);
|
|
979
|
+
} catch {
|
|
980
|
+
throw new WebhookSignatureError("Invalid JSON payload");
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
var createWebhooksClient = (_apiKey, apiUrl) => {
|
|
814
984
|
const baseUrl = apiUrl || DEFAULT_API14;
|
|
815
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
816
|
-
const listeners = /* @__PURE__ */ new Map();
|
|
817
|
-
let polling = false;
|
|
818
|
-
let pollInterval = null;
|
|
819
985
|
return {
|
|
820
|
-
/**
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
try {
|
|
828
|
-
const resp = await fetch(`${baseUrl}/api/v1/webhooks/events?since=30s`, { headers: headers() });
|
|
829
|
-
if (!resp.ok) return;
|
|
830
|
-
const data = await resp.json();
|
|
831
|
-
const events = data.data || data || [];
|
|
832
|
-
for (const evt of events) {
|
|
833
|
-
const cbs = listeners.get(evt.type);
|
|
834
|
-
if (cbs) cbs.forEach((cb) => cb(evt));
|
|
835
|
-
}
|
|
836
|
-
} catch {
|
|
837
|
-
}
|
|
838
|
-
}, 3e4);
|
|
839
|
-
}
|
|
840
|
-
},
|
|
841
|
-
/** Stop all webhook polling. */
|
|
842
|
-
stop() {
|
|
843
|
-
if (pollInterval) clearInterval(pollInterval);
|
|
844
|
-
polling = false;
|
|
845
|
-
listeners.clear();
|
|
986
|
+
/** Base URL the webhook subscription API lives under. */
|
|
987
|
+
baseUrl,
|
|
988
|
+
/** Known event types (for autocomplete / validation). */
|
|
989
|
+
knownEvents: KNOWN_WEBHOOK_EVENTS,
|
|
990
|
+
/** Verify an incoming webhook's HMAC signature and return the parsed event. */
|
|
991
|
+
constructEvent(payload, signature, timestamp, secret, opts) {
|
|
992
|
+
return constructEvent(payload, signature, timestamp, secret, opts);
|
|
846
993
|
}
|
|
847
994
|
};
|
|
848
995
|
};
|
|
@@ -851,75 +998,59 @@ var createWebhooksClient = (apiKey, apiUrl) => {
|
|
|
851
998
|
var DEFAULT_API15 = "https://be.graph8.com";
|
|
852
999
|
var createContactsClient = (apiKey, apiUrl) => {
|
|
853
1000
|
const baseUrl = apiUrl || DEFAULT_API15;
|
|
854
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
855
|
-
const toQuery = (params) => {
|
|
856
|
-
const qs = new URLSearchParams();
|
|
857
|
-
for (const [k, v] of Object.entries(params)) {
|
|
858
|
-
if (v != null) qs.set(k, String(v));
|
|
859
|
-
}
|
|
860
|
-
const s = qs.toString();
|
|
861
|
-
return s ? `?${s}` : "";
|
|
862
|
-
};
|
|
863
1001
|
return {
|
|
864
1002
|
/** List contacts with optional filters. */
|
|
865
1003
|
async list(params = {}) {
|
|
866
|
-
|
|
867
|
-
|
|
1004
|
+
return request(baseUrl, "/api/v1/contacts", apiKey, {
|
|
1005
|
+
query: params
|
|
1006
|
+
});
|
|
868
1007
|
},
|
|
869
1008
|
/** Get a single contact by ID. */
|
|
870
1009
|
async get(contactId) {
|
|
871
|
-
const resp = await
|
|
872
|
-
|
|
873
|
-
return data.data || data;
|
|
1010
|
+
const resp = await request(baseUrl, `/api/v1/contacts/${contactId}`, apiKey);
|
|
1011
|
+
return resp.data ?? resp;
|
|
874
1012
|
},
|
|
875
|
-
/**
|
|
876
|
-
|
|
877
|
-
|
|
1013
|
+
/**
|
|
1014
|
+
* Create a new contact. Pass `idempotencyKey` to make a retry safe — the
|
|
1015
|
+
* same key returns the first result instead of creating a duplicate (A6).
|
|
1016
|
+
*/
|
|
1017
|
+
async create(contact, idempotencyKey) {
|
|
1018
|
+
const resp = await request(baseUrl, "/api/v1/contacts", apiKey, {
|
|
878
1019
|
method: "POST",
|
|
879
|
-
|
|
880
|
-
|
|
1020
|
+
body: contact,
|
|
1021
|
+
idempotencyKey
|
|
881
1022
|
});
|
|
882
|
-
|
|
883
|
-
return data.data || data;
|
|
1023
|
+
return resp.data ?? resp;
|
|
884
1024
|
},
|
|
885
1025
|
/** Update a contact (partial). */
|
|
886
1026
|
async update(contactId, fields) {
|
|
887
|
-
|
|
1027
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}`, apiKey, {
|
|
888
1028
|
method: "PATCH",
|
|
889
|
-
|
|
890
|
-
body: JSON.stringify(fields)
|
|
1029
|
+
body: fields
|
|
891
1030
|
});
|
|
892
|
-
return resp.json();
|
|
893
1031
|
},
|
|
894
1032
|
/** Delete a contact (soft-delete). */
|
|
895
1033
|
async delete(contactId) {
|
|
896
|
-
|
|
897
|
-
method: "DELETE",
|
|
898
|
-
headers: headers()
|
|
899
|
-
});
|
|
900
|
-
return resp.json();
|
|
1034
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}`, apiKey, { method: "DELETE" });
|
|
901
1035
|
},
|
|
902
1036
|
/** List custom contact columns. Pass listId to include list-specific columns. */
|
|
903
1037
|
async listColumns(listId) {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1038
|
+
return request(baseUrl, "/api/v1/contacts/columns", apiKey, {
|
|
1039
|
+
query: listId != null ? { list_id: listId } : void 0
|
|
1040
|
+
});
|
|
907
1041
|
},
|
|
908
1042
|
/** Create a custom contact column. Global if list_id is omitted, list-scoped otherwise. */
|
|
909
1043
|
async createColumn(params) {
|
|
910
|
-
const
|
|
911
|
-
title: params.title,
|
|
912
|
-
data_type: params.data_type || "text",
|
|
913
|
-
list_id: params.list_id ?? null,
|
|
914
|
-
created_by: params.created_by
|
|
915
|
-
};
|
|
916
|
-
const resp = await fetch(`${baseUrl}/api/v1/contacts/columns/create`, {
|
|
1044
|
+
const resp = await request(baseUrl, "/api/v1/contacts/columns/create", apiKey, {
|
|
917
1045
|
method: "POST",
|
|
918
|
-
|
|
919
|
-
|
|
1046
|
+
body: {
|
|
1047
|
+
title: params.title,
|
|
1048
|
+
data_type: params.data_type || "text",
|
|
1049
|
+
list_id: params.list_id ?? null,
|
|
1050
|
+
created_by: params.created_by
|
|
1051
|
+
}
|
|
920
1052
|
});
|
|
921
|
-
|
|
922
|
-
return data.data || data;
|
|
1053
|
+
return resp.data ?? resp;
|
|
923
1054
|
}
|
|
924
1055
|
};
|
|
925
1056
|
};
|
|
@@ -928,73 +1059,46 @@ var createContactsClient = (apiKey, apiUrl) => {
|
|
|
928
1059
|
var DEFAULT_API16 = "https://be.graph8.com";
|
|
929
1060
|
var createCompaniesClient = (apiKey, apiUrl) => {
|
|
930
1061
|
const baseUrl = apiUrl || DEFAULT_API16;
|
|
931
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
932
|
-
const toQuery = (params) => {
|
|
933
|
-
const qs = new URLSearchParams();
|
|
934
|
-
for (const [k, v] of Object.entries(params)) {
|
|
935
|
-
if (v != null) qs.set(k, String(v));
|
|
936
|
-
}
|
|
937
|
-
const s = qs.toString();
|
|
938
|
-
return s ? `?${s}` : "";
|
|
939
|
-
};
|
|
940
1062
|
return {
|
|
941
1063
|
/** List companies with optional filters. */
|
|
942
1064
|
async list(params = {}) {
|
|
943
|
-
|
|
944
|
-
return resp.json();
|
|
1065
|
+
return request(baseUrl, "/api/v1/companies", apiKey, { query: params });
|
|
945
1066
|
},
|
|
946
1067
|
/** Get a single company by ID. */
|
|
947
1068
|
async get(companyId) {
|
|
948
|
-
const resp = await
|
|
949
|
-
|
|
950
|
-
return data.data || data;
|
|
1069
|
+
const resp = await request(baseUrl, `/api/v1/companies/${companyId}`, apiKey);
|
|
1070
|
+
return resp.data ?? resp;
|
|
951
1071
|
},
|
|
952
1072
|
/** Get contacts belonging to a company. */
|
|
953
1073
|
async contacts(companyId, limit = 50, offset = 0) {
|
|
954
|
-
|
|
955
|
-
`${baseUrl}/api/v1/companies/${companyId}/contacts?limit=${limit}&offset=${offset}`,
|
|
956
|
-
{ headers: headers() }
|
|
957
|
-
);
|
|
958
|
-
return resp.json();
|
|
1074
|
+
return request(baseUrl, `/api/v1/companies/${companyId}/contacts`, apiKey, { query: { limit, offset } });
|
|
959
1075
|
},
|
|
960
1076
|
/** Update a company (partial). */
|
|
961
1077
|
async update(companyId, fields) {
|
|
962
|
-
|
|
963
|
-
method: "PATCH",
|
|
964
|
-
headers: headers(),
|
|
965
|
-
body: JSON.stringify(fields)
|
|
966
|
-
});
|
|
967
|
-
return resp.json();
|
|
1078
|
+
return request(baseUrl, `/api/v1/companies/${companyId}`, apiKey, { method: "PATCH", body: fields });
|
|
968
1079
|
},
|
|
969
1080
|
/** Delete a company (soft-delete). */
|
|
970
1081
|
async delete(companyId) {
|
|
971
|
-
|
|
972
|
-
method: "DELETE",
|
|
973
|
-
headers: headers()
|
|
974
|
-
});
|
|
975
|
-
return resp.json();
|
|
1082
|
+
return request(baseUrl, `/api/v1/companies/${companyId}`, apiKey, { method: "DELETE" });
|
|
976
1083
|
},
|
|
977
1084
|
/** List custom company columns. Pass listId to include list-specific columns. */
|
|
978
1085
|
async listColumns(listId) {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1086
|
+
return request(baseUrl, "/api/v1/companies/columns", apiKey, {
|
|
1087
|
+
query: listId != null ? { list_id: listId } : void 0
|
|
1088
|
+
});
|
|
982
1089
|
},
|
|
983
1090
|
/** Create a custom company column. Global if list_id is omitted, list-scoped otherwise. */
|
|
984
1091
|
async createColumn(params) {
|
|
985
|
-
const
|
|
986
|
-
title: params.title,
|
|
987
|
-
data_type: params.data_type || "text",
|
|
988
|
-
list_id: params.list_id ?? null,
|
|
989
|
-
created_by: params.created_by
|
|
990
|
-
};
|
|
991
|
-
const resp = await fetch(`${baseUrl}/api/v1/companies/columns/create`, {
|
|
1092
|
+
const resp = await request(baseUrl, "/api/v1/companies/columns/create", apiKey, {
|
|
992
1093
|
method: "POST",
|
|
993
|
-
|
|
994
|
-
|
|
1094
|
+
body: {
|
|
1095
|
+
title: params.title,
|
|
1096
|
+
data_type: params.data_type || "text",
|
|
1097
|
+
list_id: params.list_id ?? null,
|
|
1098
|
+
created_by: params.created_by
|
|
1099
|
+
}
|
|
995
1100
|
});
|
|
996
|
-
|
|
997
|
-
return data.data || data;
|
|
1101
|
+
return resp.data ?? resp;
|
|
998
1102
|
}
|
|
999
1103
|
};
|
|
1000
1104
|
};
|
|
@@ -1003,56 +1107,40 @@ var createCompaniesClient = (apiKey, apiUrl) => {
|
|
|
1003
1107
|
var DEFAULT_API17 = "https://be.graph8.com";
|
|
1004
1108
|
var createListsClient = (apiKey, apiUrl) => {
|
|
1005
1109
|
const baseUrl = apiUrl || DEFAULT_API17;
|
|
1006
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1007
1110
|
return {
|
|
1008
1111
|
/** List all lists. */
|
|
1009
1112
|
async list(page = 1, limit = 50) {
|
|
1010
|
-
|
|
1011
|
-
return resp.json();
|
|
1113
|
+
return request(baseUrl, "/api/v1/lists", apiKey, { query: { page, limit } });
|
|
1012
1114
|
},
|
|
1013
1115
|
/** Create a new list. */
|
|
1014
1116
|
async create(title, type = "contacts") {
|
|
1015
|
-
const resp = await
|
|
1117
|
+
const resp = await request(baseUrl, "/api/v1/lists", apiKey, {
|
|
1016
1118
|
method: "POST",
|
|
1017
|
-
|
|
1018
|
-
body: JSON.stringify({ title, type })
|
|
1119
|
+
body: { title, type }
|
|
1019
1120
|
});
|
|
1020
|
-
|
|
1021
|
-
return data.data || data;
|
|
1121
|
+
return resp.data ?? resp;
|
|
1022
1122
|
},
|
|
1023
1123
|
/** Delete a list (soft-delete). */
|
|
1024
1124
|
async delete(listId) {
|
|
1025
|
-
|
|
1026
|
-
method: "DELETE",
|
|
1027
|
-
headers: headers()
|
|
1028
|
-
});
|
|
1029
|
-
return resp.json();
|
|
1125
|
+
return request(baseUrl, `/api/v1/lists/${listId}`, apiKey, { method: "DELETE" });
|
|
1030
1126
|
},
|
|
1031
1127
|
/** Get contacts in a list. */
|
|
1032
1128
|
async contacts(listId, page = 1, limit = 50) {
|
|
1033
|
-
|
|
1034
|
-
`${baseUrl}/api/v1/lists/${listId}/contacts?page=${page}&limit=${limit}`,
|
|
1035
|
-
{ headers: headers() }
|
|
1036
|
-
);
|
|
1037
|
-
return resp.json();
|
|
1129
|
+
return request(baseUrl, `/api/v1/lists/${listId}/contacts`, apiKey, { query: { page, limit } });
|
|
1038
1130
|
},
|
|
1039
1131
|
/** Add contacts to a list. */
|
|
1040
1132
|
async addContacts(listId, contactIds) {
|
|
1041
|
-
|
|
1133
|
+
return request(baseUrl, `/api/v1/lists/${listId}/contacts`, apiKey, {
|
|
1042
1134
|
method: "POST",
|
|
1043
|
-
|
|
1044
|
-
body: JSON.stringify({ contact_ids: contactIds })
|
|
1135
|
+
body: { contact_ids: contactIds }
|
|
1045
1136
|
});
|
|
1046
|
-
return resp.json();
|
|
1047
1137
|
},
|
|
1048
1138
|
/** Remove contacts from a list. */
|
|
1049
1139
|
async removeContacts(listId, contactIds) {
|
|
1050
|
-
|
|
1140
|
+
return request(baseUrl, `/api/v1/lists/${listId}/contacts`, apiKey, {
|
|
1051
1141
|
method: "DELETE",
|
|
1052
|
-
|
|
1053
|
-
body: JSON.stringify({ contact_ids: contactIds })
|
|
1142
|
+
body: { contact_ids: contactIds }
|
|
1054
1143
|
});
|
|
1055
|
-
return resp.json();
|
|
1056
1144
|
}
|
|
1057
1145
|
};
|
|
1058
1146
|
};
|
|
@@ -1061,40 +1149,30 @@ var createListsClient = (apiKey, apiUrl) => {
|
|
|
1061
1149
|
var DEFAULT_API18 = "https://be.graph8.com";
|
|
1062
1150
|
var createNotesClient = (apiKey, apiUrl) => {
|
|
1063
1151
|
const baseUrl = apiUrl || DEFAULT_API18;
|
|
1064
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1065
1152
|
return {
|
|
1066
1153
|
/** List all notes on a contact. */
|
|
1067
1154
|
async list(contactId) {
|
|
1068
|
-
|
|
1069
|
-
return resp.json();
|
|
1155
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}/notes`, apiKey);
|
|
1070
1156
|
},
|
|
1071
1157
|
/** Create a note on a contact. */
|
|
1072
1158
|
async create(contactId, content) {
|
|
1073
|
-
const resp = await
|
|
1159
|
+
const resp = await request(baseUrl, `/api/v1/contacts/${contactId}/notes`, apiKey, {
|
|
1074
1160
|
method: "POST",
|
|
1075
|
-
|
|
1076
|
-
body: JSON.stringify({ content })
|
|
1161
|
+
body: { content }
|
|
1077
1162
|
});
|
|
1078
|
-
|
|
1079
|
-
return data.data || data;
|
|
1163
|
+
return resp.data ?? resp;
|
|
1080
1164
|
},
|
|
1081
1165
|
/** Update a note's content. */
|
|
1082
1166
|
async update(noteId, content) {
|
|
1083
|
-
const resp = await
|
|
1167
|
+
const resp = await request(baseUrl, `/api/v1/notes/${noteId}`, apiKey, {
|
|
1084
1168
|
method: "PATCH",
|
|
1085
|
-
|
|
1086
|
-
body: JSON.stringify({ content })
|
|
1169
|
+
body: { content }
|
|
1087
1170
|
});
|
|
1088
|
-
|
|
1089
|
-
return data.data || data;
|
|
1171
|
+
return resp.data ?? resp;
|
|
1090
1172
|
},
|
|
1091
1173
|
/** Delete a note. */
|
|
1092
1174
|
async delete(noteId) {
|
|
1093
|
-
|
|
1094
|
-
method: "DELETE",
|
|
1095
|
-
headers: headers()
|
|
1096
|
-
});
|
|
1097
|
-
return resp.json();
|
|
1175
|
+
return request(baseUrl, `/api/v1/notes/${noteId}`, apiKey, { method: "DELETE" });
|
|
1098
1176
|
}
|
|
1099
1177
|
};
|
|
1100
1178
|
};
|
|
@@ -1103,54 +1181,36 @@ var createNotesClient = (apiKey, apiUrl) => {
|
|
|
1103
1181
|
var DEFAULT_API19 = "https://be.graph8.com";
|
|
1104
1182
|
var createTasksClient = (apiKey, apiUrl) => {
|
|
1105
1183
|
const baseUrl = apiUrl || DEFAULT_API19;
|
|
1106
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1107
|
-
const toQuery = (params) => {
|
|
1108
|
-
const qs = new URLSearchParams();
|
|
1109
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1110
|
-
if (v != null) qs.set(k, String(v));
|
|
1111
|
-
}
|
|
1112
|
-
const s = qs.toString();
|
|
1113
|
-
return s ? `?${s}` : "";
|
|
1114
|
-
};
|
|
1115
1184
|
return {
|
|
1116
1185
|
/** List tasks on a single contact. Optional status filter ("open" | "completed"). */
|
|
1117
1186
|
async listForContact(contactId, status) {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1187
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}/tasks`, apiKey, {
|
|
1188
|
+
query: status ? { status } : void 0
|
|
1189
|
+
});
|
|
1121
1190
|
},
|
|
1122
1191
|
/** List all tasks org-wide with optional filters. */
|
|
1123
1192
|
async list(params = {}) {
|
|
1124
|
-
|
|
1125
|
-
return resp.json();
|
|
1193
|
+
return request(baseUrl, "/api/v1/tasks", apiKey, { query: params });
|
|
1126
1194
|
},
|
|
1127
1195
|
/** Create a task on a contact. */
|
|
1128
1196
|
async create(contactId, task) {
|
|
1129
|
-
const resp = await
|
|
1197
|
+
const resp = await request(baseUrl, `/api/v1/contacts/${contactId}/tasks`, apiKey, {
|
|
1130
1198
|
method: "POST",
|
|
1131
|
-
|
|
1132
|
-
body: JSON.stringify(task)
|
|
1199
|
+
body: task
|
|
1133
1200
|
});
|
|
1134
|
-
|
|
1135
|
-
return data.data || data;
|
|
1201
|
+
return resp.data ?? resp;
|
|
1136
1202
|
},
|
|
1137
1203
|
/** Update a task (partial). */
|
|
1138
1204
|
async update(taskId, fields) {
|
|
1139
|
-
const resp = await
|
|
1205
|
+
const resp = await request(baseUrl, `/api/v1/tasks/${taskId}`, apiKey, {
|
|
1140
1206
|
method: "PATCH",
|
|
1141
|
-
|
|
1142
|
-
body: JSON.stringify(fields)
|
|
1207
|
+
body: fields
|
|
1143
1208
|
});
|
|
1144
|
-
|
|
1145
|
-
return data.data || data;
|
|
1209
|
+
return resp.data ?? resp;
|
|
1146
1210
|
},
|
|
1147
1211
|
/** Delete a task. */
|
|
1148
1212
|
async delete(taskId) {
|
|
1149
|
-
|
|
1150
|
-
method: "DELETE",
|
|
1151
|
-
headers: headers()
|
|
1152
|
-
});
|
|
1153
|
-
return resp.json();
|
|
1213
|
+
return request(baseUrl, `/api/v1/tasks/${taskId}`, apiKey, { method: "DELETE" });
|
|
1154
1214
|
}
|
|
1155
1215
|
};
|
|
1156
1216
|
};
|
|
@@ -1159,67 +1219,42 @@ var createTasksClient = (apiKey, apiUrl) => {
|
|
|
1159
1219
|
var DEFAULT_API20 = "https://be.graph8.com";
|
|
1160
1220
|
var createFieldsClient = (apiKey, apiUrl) => {
|
|
1161
1221
|
const baseUrl = apiUrl || DEFAULT_API20;
|
|
1162
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1163
|
-
const toQuery = (params) => {
|
|
1164
|
-
const qs = new URLSearchParams();
|
|
1165
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1166
|
-
if (v != null) qs.set(k, String(v));
|
|
1167
|
-
}
|
|
1168
|
-
const s = qs.toString();
|
|
1169
|
-
return s ? `?${s}` : "";
|
|
1170
|
-
};
|
|
1171
1222
|
return {
|
|
1172
1223
|
/** List contact fields (base + custom). Pass listId to include list-specific custom fields. */
|
|
1173
1224
|
async listContactFields(listId) {
|
|
1174
|
-
|
|
1175
|
-
const resp = await fetch(`${baseUrl}/api/v1/fields${qs}`, { headers: headers() });
|
|
1176
|
-
return resp.json();
|
|
1225
|
+
return request(baseUrl, "/api/v1/fields", apiKey, { query: listId != null ? { list_id: listId } : void 0 });
|
|
1177
1226
|
},
|
|
1178
1227
|
/** List company fields (base + custom). Pass listId to include list-specific custom fields. */
|
|
1179
1228
|
async listCompanyFields(listId) {
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1229
|
+
return request(baseUrl, "/api/v1/fields/companies", apiKey, {
|
|
1230
|
+
query: listId != null ? { list_id: listId } : void 0
|
|
1231
|
+
});
|
|
1183
1232
|
},
|
|
1184
1233
|
/** Create a custom field on contacts (default) or companies. */
|
|
1185
1234
|
async create(params) {
|
|
1186
|
-
const
|
|
1187
|
-
title: params.title,
|
|
1188
|
-
data_type: params.data_type || "text",
|
|
1189
|
-
list_id: params.list_id ?? null,
|
|
1190
|
-
entity: params.entity || "contacts"
|
|
1191
|
-
};
|
|
1192
|
-
const resp = await fetch(`${baseUrl}/api/v1/fields`, {
|
|
1235
|
+
const resp = await request(baseUrl, "/api/v1/fields", apiKey, {
|
|
1193
1236
|
method: "POST",
|
|
1194
|
-
|
|
1195
|
-
|
|
1237
|
+
body: {
|
|
1238
|
+
title: params.title,
|
|
1239
|
+
data_type: params.data_type || "text",
|
|
1240
|
+
list_id: params.list_id ?? null,
|
|
1241
|
+
entity: params.entity || "contacts"
|
|
1242
|
+
}
|
|
1196
1243
|
});
|
|
1197
|
-
|
|
1198
|
-
return data.data || data;
|
|
1244
|
+
return resp.data ?? resp;
|
|
1199
1245
|
},
|
|
1200
1246
|
/** Delete a custom field (soft-delete). Pass list_id to scope-guard against cross-list deletion. */
|
|
1201
1247
|
async delete(columnId, params = {}) {
|
|
1202
|
-
const
|
|
1203
|
-
if (params.list_id != null)
|
|
1204
|
-
|
|
1205
|
-
method: "DELETE",
|
|
1206
|
-
headers: headers()
|
|
1207
|
-
});
|
|
1208
|
-
return resp.json();
|
|
1248
|
+
const query = { entity: params.entity || "contacts" };
|
|
1249
|
+
if (params.list_id != null) query.list_id = params.list_id;
|
|
1250
|
+
return request(baseUrl, `/api/v1/fields/${columnId}`, apiKey, { method: "DELETE", query });
|
|
1209
1251
|
},
|
|
1210
1252
|
/** Set a custom field value on a single contact or company row. Pass value=null to clear. */
|
|
1211
1253
|
async setValue(columnId, params) {
|
|
1212
|
-
|
|
1213
|
-
record_id: params.record_id,
|
|
1214
|
-
value: params.value ?? null,
|
|
1215
|
-
entity: params.entity || "contacts"
|
|
1216
|
-
};
|
|
1217
|
-
const resp = await fetch(`${baseUrl}/api/v1/fields/${columnId}/values`, {
|
|
1254
|
+
return request(baseUrl, `/api/v1/fields/${columnId}/values`, apiKey, {
|
|
1218
1255
|
method: "PATCH",
|
|
1219
|
-
|
|
1220
|
-
body: JSON.stringify(body)
|
|
1256
|
+
body: { record_id: params.record_id, value: params.value ?? null, entity: params.entity || "contacts" }
|
|
1221
1257
|
});
|
|
1222
|
-
return resp.json();
|
|
1223
1258
|
}
|
|
1224
1259
|
};
|
|
1225
1260
|
};
|
|
@@ -1228,69 +1263,44 @@ var createFieldsClient = (apiKey, apiUrl) => {
|
|
|
1228
1263
|
var DEFAULT_API21 = "https://be.graph8.com";
|
|
1229
1264
|
var createDealsClient = (apiKey, apiUrl) => {
|
|
1230
1265
|
const baseUrl = apiUrl || DEFAULT_API21;
|
|
1231
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1232
|
-
const toQuery = (params) => {
|
|
1233
|
-
const qs = new URLSearchParams();
|
|
1234
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1235
|
-
if (v != null) qs.set(k, String(v));
|
|
1236
|
-
}
|
|
1237
|
-
const s = qs.toString();
|
|
1238
|
-
return s ? `?${s}` : "";
|
|
1239
|
-
};
|
|
1240
1266
|
return {
|
|
1241
1267
|
/** List all deal pipelines and their stages. */
|
|
1242
1268
|
async pipelines() {
|
|
1243
|
-
|
|
1244
|
-
return resp.json();
|
|
1269
|
+
return request(baseUrl, "/api/v1/deals/pipelines", apiKey);
|
|
1245
1270
|
},
|
|
1246
1271
|
/** List deals org-wide with optional filters and pagination. */
|
|
1247
1272
|
async list(params = {}) {
|
|
1248
|
-
|
|
1249
|
-
return resp.json();
|
|
1273
|
+
return request(baseUrl, "/api/v1/deals", apiKey, { query: params });
|
|
1250
1274
|
},
|
|
1251
1275
|
/** Create a new deal. */
|
|
1252
1276
|
async create(deal) {
|
|
1253
|
-
const resp = await
|
|
1254
|
-
|
|
1255
|
-
headers: headers(),
|
|
1256
|
-
body: JSON.stringify(deal)
|
|
1257
|
-
});
|
|
1258
|
-
const data = await resp.json();
|
|
1259
|
-
return data.data || data;
|
|
1277
|
+
const resp = await request(baseUrl, "/api/v1/deals", apiKey, { method: "POST", body: deal });
|
|
1278
|
+
return resp.data ?? resp;
|
|
1260
1279
|
},
|
|
1261
1280
|
/** Get a single deal by ID. */
|
|
1262
1281
|
async get(dealId) {
|
|
1263
|
-
const resp = await
|
|
1264
|
-
|
|
1265
|
-
return data.data || data;
|
|
1282
|
+
const resp = await request(baseUrl, `/api/v1/deals/${dealId}`, apiKey);
|
|
1283
|
+
return resp.data ?? resp;
|
|
1266
1284
|
},
|
|
1267
1285
|
/** Update a deal (partial). */
|
|
1268
1286
|
async update(dealId, fields) {
|
|
1269
|
-
const resp = await
|
|
1287
|
+
const resp = await request(baseUrl, `/api/v1/deals/${dealId}`, apiKey, {
|
|
1270
1288
|
method: "PATCH",
|
|
1271
|
-
|
|
1272
|
-
body: JSON.stringify(fields)
|
|
1289
|
+
body: fields
|
|
1273
1290
|
});
|
|
1274
|
-
|
|
1275
|
-
return data.data || data;
|
|
1291
|
+
return resp.data ?? resp;
|
|
1276
1292
|
},
|
|
1277
1293
|
/** Delete a deal. */
|
|
1278
1294
|
async delete(dealId) {
|
|
1279
|
-
|
|
1280
|
-
method: "DELETE",
|
|
1281
|
-
headers: headers()
|
|
1282
|
-
});
|
|
1283
|
-
return resp.json();
|
|
1295
|
+
return request(baseUrl, `/api/v1/deals/${dealId}`, apiKey, { method: "DELETE" });
|
|
1284
1296
|
},
|
|
1285
1297
|
/** Get all deals associated with a contact. */
|
|
1286
1298
|
async forContact(contactId) {
|
|
1287
|
-
|
|
1288
|
-
return resp.json();
|
|
1299
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}/deals`, apiKey);
|
|
1289
1300
|
},
|
|
1290
1301
|
/** Get all deals associated with a company. */
|
|
1291
1302
|
async forCompany(companyId) {
|
|
1292
|
-
|
|
1293
|
-
return resp.json();
|
|
1303
|
+
return request(baseUrl, `/api/v1/companies/${companyId}/deals`, apiKey);
|
|
1294
1304
|
}
|
|
1295
1305
|
};
|
|
1296
1306
|
};
|
|
@@ -1299,77 +1309,53 @@ var createDealsClient = (apiKey, apiUrl) => {
|
|
|
1299
1309
|
var DEFAULT_API22 = "https://be.graph8.com";
|
|
1300
1310
|
var createInboxClient = (apiKey, apiUrl) => {
|
|
1301
1311
|
const baseUrl = apiUrl || DEFAULT_API22;
|
|
1302
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1303
|
-
const toQuery = (params) => {
|
|
1304
|
-
const qs = new URLSearchParams();
|
|
1305
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1306
|
-
if (v != null) qs.set(k, String(v));
|
|
1307
|
-
}
|
|
1308
|
-
const s = qs.toString();
|
|
1309
|
-
return s ? `?${s}` : "";
|
|
1310
|
-
};
|
|
1311
1312
|
return {
|
|
1312
1313
|
/** List inbox threads across email, SMS, and LinkedIn. */
|
|
1313
1314
|
async list(params = {}) {
|
|
1314
|
-
|
|
1315
|
-
return resp.json();
|
|
1315
|
+
return request(baseUrl, "/api/v1/inbox", apiKey, { query: params });
|
|
1316
1316
|
},
|
|
1317
1317
|
/** Get a single inbox thread. Defaults to email channel. */
|
|
1318
1318
|
async get(replyId, channel = "email") {
|
|
1319
|
-
const resp = await
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
const data = await resp.json();
|
|
1324
|
-
return data.data || data;
|
|
1319
|
+
const resp = await request(baseUrl, `/api/v1/inbox/${replyId}`, apiKey, {
|
|
1320
|
+
query: { channel }
|
|
1321
|
+
});
|
|
1322
|
+
return resp.data ?? resp;
|
|
1325
1323
|
},
|
|
1326
1324
|
/** Assign a user to an inbox thread. */
|
|
1327
1325
|
async assign(replyId, assigneeEmail, channel = "email") {
|
|
1328
|
-
const resp = await
|
|
1329
|
-
|
|
1330
|
-
{
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
}
|
|
1335
|
-
);
|
|
1336
|
-
const data = await resp.json();
|
|
1337
|
-
return data.data || data;
|
|
1326
|
+
const resp = await request(baseUrl, `/api/v1/inbox/${replyId}/assign`, apiKey, {
|
|
1327
|
+
method: "POST",
|
|
1328
|
+
query: { channel },
|
|
1329
|
+
body: { assignee_email: assigneeEmail }
|
|
1330
|
+
});
|
|
1331
|
+
return resp.data ?? resp;
|
|
1338
1332
|
},
|
|
1339
1333
|
/** Attach tag IDs to an inbox thread. */
|
|
1340
1334
|
async tag(replyId, tagIds, channel = "email") {
|
|
1341
|
-
const resp = await
|
|
1342
|
-
|
|
1343
|
-
{
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
}
|
|
1348
|
-
);
|
|
1349
|
-
const data = await resp.json();
|
|
1350
|
-
return data.data || data;
|
|
1335
|
+
const resp = await request(baseUrl, `/api/v1/inbox/${replyId}/tag`, apiKey, {
|
|
1336
|
+
method: "POST",
|
|
1337
|
+
query: { channel },
|
|
1338
|
+
body: { tag_ids: tagIds }
|
|
1339
|
+
});
|
|
1340
|
+
return resp.data ?? resp;
|
|
1351
1341
|
},
|
|
1352
1342
|
/**
|
|
1353
1343
|
* Generate an AI draft reply for a thread.
|
|
1354
1344
|
* Charges credits — server returns 402 if balance is insufficient.
|
|
1355
1345
|
*/
|
|
1356
1346
|
async draft(replyId, channel = "email") {
|
|
1357
|
-
const resp = await
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
const data = await resp.json();
|
|
1362
|
-
return data.data || data;
|
|
1347
|
+
const resp = await request(baseUrl, `/api/v1/inbox/${replyId}/draft`, apiKey, {
|
|
1348
|
+
query: { channel }
|
|
1349
|
+
});
|
|
1350
|
+
return resp.data ?? resp;
|
|
1363
1351
|
},
|
|
1364
1352
|
/** Send a reply through email, SMS, or LinkedIn. */
|
|
1365
1353
|
async send(replyId, payload) {
|
|
1366
|
-
const resp = await
|
|
1354
|
+
const resp = await request(baseUrl, `/api/v1/inbox/${replyId}/send`, apiKey, {
|
|
1367
1355
|
method: "POST",
|
|
1368
|
-
|
|
1369
|
-
body: JSON.stringify(payload)
|
|
1356
|
+
body: payload
|
|
1370
1357
|
});
|
|
1371
|
-
|
|
1372
|
-
return data.data || data;
|
|
1358
|
+
return resp.data ?? resp;
|
|
1373
1359
|
}
|
|
1374
1360
|
};
|
|
1375
1361
|
};
|
|
@@ -1378,104 +1364,72 @@ var createInboxClient = (apiKey, apiUrl) => {
|
|
|
1378
1364
|
var DEFAULT_API23 = "https://be.graph8.com";
|
|
1379
1365
|
var createQuotesClient = (apiKey, apiUrl) => {
|
|
1380
1366
|
const baseUrl = apiUrl || DEFAULT_API23;
|
|
1381
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1382
|
-
const toQuery = (params) => {
|
|
1383
|
-
const qs = new URLSearchParams();
|
|
1384
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1385
|
-
if (v != null) qs.set(k, String(v));
|
|
1386
|
-
}
|
|
1387
|
-
const s = qs.toString();
|
|
1388
|
-
return s ? `?${s}` : "";
|
|
1389
|
-
};
|
|
1390
1367
|
return {
|
|
1391
1368
|
/** List quotes org-wide with optional filters and pagination. */
|
|
1392
1369
|
async list(params = {}) {
|
|
1393
|
-
|
|
1394
|
-
return resp.json();
|
|
1370
|
+
return request(baseUrl, "/api/v1/quotes", apiKey, { query: params });
|
|
1395
1371
|
},
|
|
1396
1372
|
/** Get full details for a single quote. */
|
|
1397
1373
|
async get(quoteId) {
|
|
1398
|
-
const resp = await
|
|
1399
|
-
|
|
1400
|
-
return data.data || data;
|
|
1374
|
+
const resp = await request(baseUrl, `/api/v1/quotes/${quoteId}`, apiKey);
|
|
1375
|
+
return resp.data ?? resp;
|
|
1401
1376
|
},
|
|
1402
1377
|
/** Create a new quote from line items. */
|
|
1403
1378
|
async create(quote) {
|
|
1404
|
-
const resp = await
|
|
1379
|
+
const resp = await request(baseUrl, "/api/v1/quotes", apiKey, {
|
|
1405
1380
|
method: "POST",
|
|
1406
|
-
|
|
1407
|
-
body: JSON.stringify(quote)
|
|
1381
|
+
body: quote
|
|
1408
1382
|
});
|
|
1409
|
-
|
|
1410
|
-
return data.data || data;
|
|
1383
|
+
return resp.data ?? resp;
|
|
1411
1384
|
},
|
|
1412
1385
|
/** Update a draft quote (line items, expiry, notes). */
|
|
1413
1386
|
async update(quoteId, fields) {
|
|
1414
|
-
const resp = await
|
|
1387
|
+
const resp = await request(baseUrl, `/api/v1/quotes/${quoteId}`, apiKey, {
|
|
1415
1388
|
method: "PUT",
|
|
1416
|
-
|
|
1417
|
-
body: JSON.stringify(fields)
|
|
1389
|
+
body: fields
|
|
1418
1390
|
});
|
|
1419
|
-
|
|
1420
|
-
return data.data || data;
|
|
1391
|
+
return resp.data ?? resp;
|
|
1421
1392
|
},
|
|
1422
1393
|
/** Delete a draft quote (irreversible). */
|
|
1423
1394
|
async delete(quoteId) {
|
|
1424
|
-
|
|
1425
|
-
method: "DELETE",
|
|
1426
|
-
headers: headers()
|
|
1427
|
-
});
|
|
1428
|
-
return resp.json();
|
|
1395
|
+
return request(baseUrl, `/api/v1/quotes/${quoteId}`, apiKey, { method: "DELETE" });
|
|
1429
1396
|
},
|
|
1430
1397
|
/** Duplicate an existing quote (all line items copied into a new draft). */
|
|
1431
1398
|
async duplicate(quoteId) {
|
|
1432
|
-
const resp = await
|
|
1399
|
+
const resp = await request(baseUrl, `/api/v1/quotes/${quoteId}/duplicate`, apiKey, {
|
|
1433
1400
|
method: "POST",
|
|
1434
|
-
|
|
1435
|
-
body: JSON.stringify({})
|
|
1401
|
+
body: {}
|
|
1436
1402
|
});
|
|
1437
|
-
|
|
1438
|
-
return data.data || data;
|
|
1403
|
+
return resp.data ?? resp;
|
|
1439
1404
|
},
|
|
1440
1405
|
/** Convert a signed / sent quote back to editable draft state. */
|
|
1441
1406
|
async editAsDraft(quoteId) {
|
|
1442
|
-
|
|
1443
|
-
method: "POST",
|
|
1444
|
-
headers: headers(),
|
|
1445
|
-
body: JSON.stringify({})
|
|
1446
|
-
});
|
|
1447
|
-
return resp.json();
|
|
1407
|
+
return request(baseUrl, `/api/v1/quotes/${quoteId}/edit-as-draft`, apiKey, { method: "POST", body: {} });
|
|
1448
1408
|
},
|
|
1449
1409
|
/** Send a quote to its recipient via email (with signature + optional payment link). */
|
|
1450
1410
|
async send(quoteId, params) {
|
|
1451
|
-
const resp = await
|
|
1411
|
+
const resp = await request(baseUrl, `/api/v1/quotes/${quoteId}/send`, apiKey, {
|
|
1452
1412
|
method: "POST",
|
|
1453
|
-
|
|
1454
|
-
body: JSON.stringify(params)
|
|
1413
|
+
body: params
|
|
1455
1414
|
});
|
|
1456
|
-
|
|
1457
|
-
return data.data || data;
|
|
1415
|
+
return resp.data ?? resp;
|
|
1458
1416
|
},
|
|
1459
1417
|
/** List products available for line items. */
|
|
1460
1418
|
async products() {
|
|
1461
|
-
|
|
1462
|
-
return resp.json();
|
|
1419
|
+
return request(baseUrl, "/api/v1/quotable-products", apiKey);
|
|
1463
1420
|
},
|
|
1464
1421
|
/** Get org-level quote settings (currency, tax rate, payment providers, logo). */
|
|
1465
1422
|
async settings() {
|
|
1466
|
-
const resp = await
|
|
1467
|
-
|
|
1468
|
-
return data.data || data;
|
|
1423
|
+
const resp = await request(baseUrl, "/api/v1/quote-settings", apiKey);
|
|
1424
|
+
return resp.data ?? resp;
|
|
1469
1425
|
},
|
|
1470
1426
|
/** Get all quotes associated with a contact. */
|
|
1471
1427
|
async forContact(contactId) {
|
|
1472
|
-
|
|
1473
|
-
return resp.json();
|
|
1428
|
+
return request(baseUrl, `/api/v1/contacts/${contactId}/quotes`, apiKey);
|
|
1474
1429
|
},
|
|
1475
1430
|
/** Get all quotes associated with a company. */
|
|
1476
1431
|
async forCompany(companyId) {
|
|
1477
|
-
|
|
1478
|
-
return resp.json();
|
|
1432
|
+
return request(baseUrl, `/api/v1/companies/${companyId}/quotes`, apiKey);
|
|
1479
1433
|
}
|
|
1480
1434
|
};
|
|
1481
1435
|
};
|
|
@@ -1484,107 +1438,82 @@ var createQuotesClient = (apiKey, apiUrl) => {
|
|
|
1484
1438
|
var DEFAULT_API24 = "https://be.graph8.com";
|
|
1485
1439
|
var createPipelinesClient = (apiKey, apiUrl) => {
|
|
1486
1440
|
const baseUrl = apiUrl || DEFAULT_API24;
|
|
1487
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1488
1441
|
return {
|
|
1489
1442
|
/** List all stage-checklist pipelines with stages, evidence, scripts. */
|
|
1490
1443
|
async list() {
|
|
1491
|
-
|
|
1492
|
-
return resp.json();
|
|
1444
|
+
return request(baseUrl, "/api/v1/pipelines", apiKey);
|
|
1493
1445
|
},
|
|
1494
1446
|
/** Get a single pipeline by ID. */
|
|
1495
1447
|
async get(pipelineId) {
|
|
1496
|
-
const resp = await
|
|
1497
|
-
|
|
1498
|
-
return data.data || data;
|
|
1448
|
+
const resp = await request(baseUrl, `/api/v1/pipelines/${pipelineId}`, apiKey);
|
|
1449
|
+
return resp.data ?? resp;
|
|
1499
1450
|
},
|
|
1500
1451
|
/** Get the canonical evidence-key library (used when defining stages). */
|
|
1501
1452
|
async evidenceLibrary() {
|
|
1502
|
-
|
|
1503
|
-
return resp.json();
|
|
1453
|
+
return request(baseUrl, "/api/v1/pipelines/evidence-library", apiKey);
|
|
1504
1454
|
},
|
|
1505
1455
|
/** Create a new pipeline. Defaults to a templated set of stages; pass blank=true for empty. */
|
|
1506
1456
|
async create(params) {
|
|
1507
|
-
const resp = await
|
|
1457
|
+
const resp = await request(baseUrl, "/api/v1/pipelines", apiKey, {
|
|
1508
1458
|
method: "POST",
|
|
1509
|
-
|
|
1510
|
-
body: JSON.stringify(params)
|
|
1459
|
+
body: params
|
|
1511
1460
|
});
|
|
1512
|
-
|
|
1513
|
-
return data.data || data;
|
|
1461
|
+
return resp.data ?? resp;
|
|
1514
1462
|
},
|
|
1515
1463
|
/** Update pipeline metadata (name, target). */
|
|
1516
1464
|
async update(pipelineId, fields) {
|
|
1517
|
-
const resp = await
|
|
1465
|
+
const resp = await request(baseUrl, `/api/v1/pipelines/${pipelineId}`, apiKey, {
|
|
1518
1466
|
method: "PUT",
|
|
1519
|
-
|
|
1520
|
-
body: JSON.stringify(fields)
|
|
1467
|
+
body: fields
|
|
1521
1468
|
});
|
|
1522
|
-
|
|
1523
|
-
return data.data || data;
|
|
1469
|
+
return resp.data ?? resp;
|
|
1524
1470
|
},
|
|
1525
1471
|
/** Delete a pipeline. Only allowed when no deals reference it. */
|
|
1526
1472
|
async delete(pipelineId) {
|
|
1527
|
-
|
|
1528
|
-
method: "DELETE",
|
|
1529
|
-
headers: headers()
|
|
1530
|
-
});
|
|
1531
|
-
return resp.json();
|
|
1473
|
+
return request(baseUrl, `/api/v1/pipelines/${pipelineId}`, apiKey, { method: "DELETE" });
|
|
1532
1474
|
},
|
|
1533
1475
|
/** Add a new stage to a pipeline. */
|
|
1534
1476
|
async createStage(pipelineId, stage) {
|
|
1535
|
-
const resp = await
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
return
|
|
1477
|
+
const resp = await request(
|
|
1478
|
+
baseUrl,
|
|
1479
|
+
`/api/v1/pipelines/${pipelineId}/stages`,
|
|
1480
|
+
apiKey,
|
|
1481
|
+
{ method: "POST", body: stage }
|
|
1482
|
+
);
|
|
1483
|
+
return resp.data ?? resp;
|
|
1542
1484
|
},
|
|
1543
1485
|
/** Update a stage (evidence, scripts, position). */
|
|
1544
1486
|
async updateStage(pipelineId, stageId, fields) {
|
|
1545
|
-
const resp = await
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
return
|
|
1487
|
+
const resp = await request(
|
|
1488
|
+
baseUrl,
|
|
1489
|
+
`/api/v1/pipelines/${pipelineId}/stages/${stageId}`,
|
|
1490
|
+
apiKey,
|
|
1491
|
+
{ method: "PUT", body: fields }
|
|
1492
|
+
);
|
|
1493
|
+
return resp.data ?? resp;
|
|
1552
1494
|
},
|
|
1553
1495
|
/** Reorder stages within a pipeline (pass full ordered list of stage IDs). */
|
|
1554
1496
|
async reorderStages(pipelineId, stageIds) {
|
|
1555
|
-
|
|
1497
|
+
return request(baseUrl, `/api/v1/pipelines/${pipelineId}/stages/reorder`, apiKey, {
|
|
1556
1498
|
method: "PUT",
|
|
1557
|
-
|
|
1558
|
-
body: JSON.stringify({ stage_ids: stageIds })
|
|
1499
|
+
body: { stage_ids: stageIds }
|
|
1559
1500
|
});
|
|
1560
|
-
return resp.json();
|
|
1561
1501
|
},
|
|
1562
1502
|
/** Delete a stage from a pipeline. */
|
|
1563
1503
|
async deleteStage(pipelineId, stageId) {
|
|
1564
|
-
|
|
1565
|
-
method: "DELETE",
|
|
1566
|
-
headers: headers()
|
|
1567
|
-
});
|
|
1568
|
-
return resp.json();
|
|
1504
|
+
return request(baseUrl, `/api/v1/pipelines/${pipelineId}/stages/${stageId}`, apiKey, { method: "DELETE" });
|
|
1569
1505
|
},
|
|
1570
1506
|
/** Get an AI-suggested pipeline based on org context (brand, ICP, messaging). */
|
|
1571
1507
|
async suggest() {
|
|
1572
|
-
|
|
1573
|
-
method: "POST",
|
|
1574
|
-
headers: headers(),
|
|
1575
|
-
body: JSON.stringify({})
|
|
1576
|
-
});
|
|
1577
|
-
return resp.json();
|
|
1508
|
+
return request(baseUrl, "/api/v1/pipelines/suggest", apiKey, { method: "POST", body: {} });
|
|
1578
1509
|
},
|
|
1579
1510
|
/** Create a real pipeline from an AI suggestion (optionally with overrides). */
|
|
1580
1511
|
async fromSuggestion(suggestionId, overrides) {
|
|
1581
|
-
const resp = await
|
|
1512
|
+
const resp = await request(baseUrl, "/api/v1/pipelines/from-suggestion", apiKey, {
|
|
1582
1513
|
method: "POST",
|
|
1583
|
-
|
|
1584
|
-
body: JSON.stringify({ suggestion_id: suggestionId, ...overrides || {} })
|
|
1514
|
+
body: { suggestion_id: suggestionId, ...overrides || {} }
|
|
1585
1515
|
});
|
|
1586
|
-
|
|
1587
|
-
return data.data || data;
|
|
1516
|
+
return resp.data ?? resp;
|
|
1588
1517
|
}
|
|
1589
1518
|
};
|
|
1590
1519
|
};
|
|
@@ -1593,36 +1522,23 @@ var createPipelinesClient = (apiKey, apiUrl) => {
|
|
|
1593
1522
|
var DEFAULT_API25 = "https://be.graph8.com";
|
|
1594
1523
|
var createWorkflowsClient = (apiKey, apiUrl) => {
|
|
1595
1524
|
const baseUrl = apiUrl || DEFAULT_API25;
|
|
1596
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1597
|
-
const toQuery = (params) => {
|
|
1598
|
-
const qs = new URLSearchParams();
|
|
1599
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1600
|
-
if (v != null) qs.set(k, String(v));
|
|
1601
|
-
}
|
|
1602
|
-
const s = qs.toString();
|
|
1603
|
-
return s ? `?${s}` : "";
|
|
1604
|
-
};
|
|
1605
1525
|
return {
|
|
1606
1526
|
/** List workflows org-wide. */
|
|
1607
1527
|
async list(params = {}) {
|
|
1608
|
-
|
|
1609
|
-
return resp.json();
|
|
1528
|
+
return request(baseUrl, "/api/v1/workflows", apiKey, { query: params });
|
|
1610
1529
|
},
|
|
1611
1530
|
/** Get full workflow definition (nodes, connections, trigger, execution state). */
|
|
1612
1531
|
async get(workflowId) {
|
|
1613
|
-
const resp = await
|
|
1614
|
-
|
|
1615
|
-
return data.data || data;
|
|
1532
|
+
const resp = await request(baseUrl, `/api/v1/workflows/${workflowId}`, apiKey);
|
|
1533
|
+
return resp.data ?? resp;
|
|
1616
1534
|
},
|
|
1617
1535
|
/** Create a new workflow. */
|
|
1618
1536
|
async create(params) {
|
|
1619
|
-
const resp = await
|
|
1537
|
+
const resp = await request(baseUrl, "/api/v1/workflows", apiKey, {
|
|
1620
1538
|
method: "POST",
|
|
1621
|
-
|
|
1622
|
-
body: JSON.stringify(params)
|
|
1539
|
+
body: params
|
|
1623
1540
|
});
|
|
1624
|
-
|
|
1625
|
-
return data.data || data;
|
|
1541
|
+
return resp.data ?? resp;
|
|
1626
1542
|
},
|
|
1627
1543
|
/**
|
|
1628
1544
|
* Update a workflow. Pass the full `config` (nodes + connections) to edit
|
|
@@ -1630,129 +1546,92 @@ var createWorkflowsClient = (apiKey, apiUrl) => {
|
|
|
1630
1546
|
* config and submitting the updated record.
|
|
1631
1547
|
*/
|
|
1632
1548
|
async update(workflowId, fields) {
|
|
1633
|
-
const resp = await
|
|
1549
|
+
const resp = await request(baseUrl, `/api/v1/workflows/${workflowId}`, apiKey, {
|
|
1634
1550
|
method: "PUT",
|
|
1635
|
-
|
|
1636
|
-
body: JSON.stringify(fields)
|
|
1551
|
+
body: fields
|
|
1637
1552
|
});
|
|
1638
|
-
|
|
1639
|
-
return data.data || data;
|
|
1553
|
+
return resp.data ?? resp;
|
|
1640
1554
|
},
|
|
1641
1555
|
/** Delete a workflow. */
|
|
1642
1556
|
async delete(workflowId) {
|
|
1643
|
-
|
|
1644
|
-
method: "DELETE",
|
|
1645
|
-
headers: headers()
|
|
1646
|
-
});
|
|
1647
|
-
return resp.json();
|
|
1557
|
+
return request(baseUrl, `/api/v1/workflows/${workflowId}`, apiKey, { method: "DELETE" });
|
|
1648
1558
|
},
|
|
1649
1559
|
/** Validate a workflow definition (orphans, dangling connections, required fields). */
|
|
1650
1560
|
async validate(workflow) {
|
|
1651
|
-
|
|
1652
|
-
method: "POST",
|
|
1653
|
-
headers: headers(),
|
|
1654
|
-
body: JSON.stringify(workflow)
|
|
1655
|
-
});
|
|
1656
|
-
return resp.json();
|
|
1561
|
+
return request(baseUrl, "/api/v1/workflows/validate", apiKey, { method: "POST", body: workflow });
|
|
1657
1562
|
},
|
|
1658
1563
|
/** Execute a workflow immediately with a trigger payload. */
|
|
1659
1564
|
async execute(workflowId, triggerPayload = {}) {
|
|
1660
|
-
const resp = await
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
return
|
|
1565
|
+
const resp = await request(
|
|
1566
|
+
baseUrl,
|
|
1567
|
+
`/api/v1/workflows/${workflowId}/execute`,
|
|
1568
|
+
apiKey,
|
|
1569
|
+
{ method: "POST", body: { trigger_payload: triggerPayload } }
|
|
1570
|
+
);
|
|
1571
|
+
return resp.data ?? resp;
|
|
1667
1572
|
},
|
|
1668
|
-
/** Get the status +
|
|
1573
|
+
/** Get the status + outputs of a single execution. */
|
|
1669
1574
|
async getExecution(executionId) {
|
|
1670
|
-
const resp = await
|
|
1671
|
-
|
|
1672
|
-
|
|
1575
|
+
const resp = await request(
|
|
1576
|
+
baseUrl,
|
|
1577
|
+
`/api/v1/workflows/executions/${executionId}`,
|
|
1578
|
+
apiKey
|
|
1579
|
+
);
|
|
1580
|
+
return resp.data ?? resp;
|
|
1673
1581
|
},
|
|
1674
|
-
/** Pause
|
|
1582
|
+
/** Pause a running execution. */
|
|
1675
1583
|
async pauseExecution(executionId) {
|
|
1676
|
-
|
|
1677
|
-
method: "POST",
|
|
1678
|
-
headers: headers(),
|
|
1679
|
-
body: JSON.stringify({})
|
|
1680
|
-
});
|
|
1681
|
-
return resp.json();
|
|
1584
|
+
return request(baseUrl, `/api/v1/workflows/executions/${executionId}/pause`, apiKey, { method: "POST" });
|
|
1682
1585
|
},
|
|
1683
1586
|
/** Resume a paused execution. */
|
|
1684
1587
|
async resumeExecution(executionId) {
|
|
1685
|
-
|
|
1686
|
-
method: "POST",
|
|
1687
|
-
headers: headers(),
|
|
1688
|
-
body: JSON.stringify({})
|
|
1689
|
-
});
|
|
1690
|
-
return resp.json();
|
|
1588
|
+
return request(baseUrl, `/api/v1/workflows/executions/${executionId}/resume`, apiKey, { method: "POST" });
|
|
1691
1589
|
},
|
|
1692
|
-
/** Stop an execution
|
|
1590
|
+
/** Stop an execution. */
|
|
1693
1591
|
async stopExecution(executionId) {
|
|
1694
|
-
|
|
1695
|
-
method: "POST",
|
|
1696
|
-
headers: headers(),
|
|
1697
|
-
body: JSON.stringify({})
|
|
1698
|
-
});
|
|
1699
|
-
return resp.json();
|
|
1592
|
+
return request(baseUrl, `/api/v1/workflows/executions/${executionId}/stop`, apiKey, { method: "POST" });
|
|
1700
1593
|
},
|
|
1701
|
-
/** Get the status
|
|
1594
|
+
/** Get the trigger status (e.g. schedule / webhook wiring) for a workflow. */
|
|
1702
1595
|
async getTriggerStatus(workflowId) {
|
|
1703
|
-
|
|
1704
|
-
return resp.json();
|
|
1596
|
+
return request(baseUrl, `/api/v1/workflows/${workflowId}/trigger-status`, apiKey);
|
|
1705
1597
|
},
|
|
1706
|
-
/** Reset
|
|
1598
|
+
/** Reset a workflow's trigger cursor / state. */
|
|
1707
1599
|
async resetTrigger(workflowId) {
|
|
1708
|
-
|
|
1709
|
-
method: "POST",
|
|
1710
|
-
headers: headers(),
|
|
1711
|
-
body: JSON.stringify({})
|
|
1712
|
-
});
|
|
1713
|
-
return resp.json();
|
|
1600
|
+
return request(baseUrl, `/api/v1/workflows/${workflowId}/trigger-reset`, apiKey, { method: "POST" });
|
|
1714
1601
|
},
|
|
1715
|
-
/**
|
|
1716
|
-
* List available node types with schemas. Pass a `type` param to fetch one type's full schema.
|
|
1717
|
-
*/
|
|
1602
|
+
/** Catalog of available workflow node types with config + output schemas. */
|
|
1718
1603
|
async nodeTypes(params = {}) {
|
|
1719
|
-
|
|
1720
|
-
|
|
1604
|
+
return request(baseUrl, "/api/v1/workflows/node-types/schema", apiKey, {
|
|
1605
|
+
query: params
|
|
1606
|
+
});
|
|
1721
1607
|
},
|
|
1722
|
-
/** Slack
|
|
1608
|
+
/** Slack users available to workflow nodes. */
|
|
1723
1609
|
async listSlackUsers() {
|
|
1724
|
-
|
|
1725
|
-
return resp.json();
|
|
1610
|
+
return request(baseUrl, "/api/v1/workflows/integrations/slack/users", apiKey);
|
|
1726
1611
|
},
|
|
1727
|
-
/** Slack channels. */
|
|
1612
|
+
/** Slack channels available to workflow nodes. */
|
|
1728
1613
|
async listSlackChannels() {
|
|
1729
|
-
|
|
1730
|
-
return resp.json();
|
|
1614
|
+
return request(baseUrl, "/api/v1/workflows/integrations/slack/channels", apiKey);
|
|
1731
1615
|
},
|
|
1732
|
-
/** Roam
|
|
1616
|
+
/** Roam users available to workflow nodes. */
|
|
1733
1617
|
async listRoamUsers() {
|
|
1734
|
-
|
|
1735
|
-
return resp.json();
|
|
1618
|
+
return request(baseUrl, "/api/v1/workflows/integrations/roam/users", apiKey);
|
|
1736
1619
|
},
|
|
1737
|
-
/** Roam
|
|
1620
|
+
/** Roam groups available to workflow nodes. */
|
|
1738
1621
|
async listRoamGroups() {
|
|
1739
|
-
|
|
1740
|
-
return resp.json();
|
|
1622
|
+
return request(baseUrl, "/api/v1/workflows/integrations/roam/groups", apiKey);
|
|
1741
1623
|
},
|
|
1742
|
-
/**
|
|
1624
|
+
/** MCP servers available to workflow nodes. */
|
|
1743
1625
|
async listMcpServers() {
|
|
1744
|
-
|
|
1745
|
-
return resp.json();
|
|
1626
|
+
return request(baseUrl, "/api/v1/workflows/mcp-servers", apiKey);
|
|
1746
1627
|
},
|
|
1747
|
-
/**
|
|
1628
|
+
/** Disposition options available to workflow nodes. */
|
|
1748
1629
|
async listDispositions() {
|
|
1749
|
-
|
|
1750
|
-
return resp.json();
|
|
1630
|
+
return request(baseUrl, "/api/v1/workflows/dispositions", apiKey);
|
|
1751
1631
|
},
|
|
1752
|
-
/** Form field
|
|
1632
|
+
/** Form field definitions for a given form (used by form-trigger nodes). */
|
|
1753
1633
|
async listFormFields(formId) {
|
|
1754
|
-
|
|
1755
|
-
return resp.json();
|
|
1634
|
+
return request(baseUrl, `/api/v1/workflows/forms/${formId}/fields`, apiKey);
|
|
1756
1635
|
}
|
|
1757
1636
|
};
|
|
1758
1637
|
};
|
|
@@ -1761,127 +1640,87 @@ var createWorkflowsClient = (apiKey, apiUrl) => {
|
|
|
1761
1640
|
var DEFAULT_API26 = "https://be.graph8.com";
|
|
1762
1641
|
var createSkillsClient = (apiKey, apiUrl) => {
|
|
1763
1642
|
const baseUrl = apiUrl || DEFAULT_API26;
|
|
1764
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
1765
|
-
const toQuery = (params) => {
|
|
1766
|
-
const qs = new URLSearchParams();
|
|
1767
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1768
|
-
if (v != null) qs.set(k, String(v));
|
|
1769
|
-
}
|
|
1770
|
-
const s = qs.toString();
|
|
1771
|
-
return s ? `?${s}` : "";
|
|
1772
|
-
};
|
|
1773
1643
|
return {
|
|
1774
1644
|
/** List skills. */
|
|
1775
1645
|
async list(params = {}) {
|
|
1776
|
-
|
|
1777
|
-
return resp.json();
|
|
1646
|
+
return request(baseUrl, "/api/v1/skills", apiKey, { query: params });
|
|
1778
1647
|
},
|
|
1779
1648
|
/** Get a skill by ID. */
|
|
1780
1649
|
async get(skillId) {
|
|
1781
|
-
const resp = await
|
|
1782
|
-
|
|
1783
|
-
return data.data || data;
|
|
1650
|
+
const resp = await request(baseUrl, `/api/v1/skills/${skillId}`, apiKey);
|
|
1651
|
+
return resp.data ?? resp;
|
|
1784
1652
|
},
|
|
1785
1653
|
/** Get the variables required by a skill (extracted from prompt or body template). */
|
|
1786
1654
|
async getVariables(skillId) {
|
|
1787
|
-
|
|
1788
|
-
return resp.json();
|
|
1655
|
+
return request(baseUrl, `/api/v1/skills/${skillId}/variables`, apiKey);
|
|
1789
1656
|
},
|
|
1790
1657
|
/** List available LLM models. */
|
|
1791
1658
|
async listModels() {
|
|
1792
|
-
|
|
1793
|
-
return resp.json();
|
|
1659
|
+
return request(baseUrl, "/api/v1/skills/models", apiKey);
|
|
1794
1660
|
},
|
|
1795
1661
|
/** List skill templates. */
|
|
1796
1662
|
async listTemplates(params = {}) {
|
|
1797
|
-
|
|
1798
|
-
return resp.json();
|
|
1663
|
+
return request(baseUrl, "/api/v1/skills/templates", apiKey, { query: params });
|
|
1799
1664
|
},
|
|
1800
1665
|
/** Create an LLM skill (prompt + model + schemas). */
|
|
1801
1666
|
async createLLM(params) {
|
|
1802
|
-
const resp = await
|
|
1667
|
+
const resp = await request(baseUrl, "/api/v1/skills", apiKey, {
|
|
1803
1668
|
method: "POST",
|
|
1804
|
-
|
|
1805
|
-
body: JSON.stringify({ ...params, type: "llm" })
|
|
1669
|
+
body: { ...params, type: "llm" }
|
|
1806
1670
|
});
|
|
1807
|
-
|
|
1808
|
-
return data.data || data;
|
|
1671
|
+
return resp.data ?? resp;
|
|
1809
1672
|
},
|
|
1810
1673
|
/** Create an API skill (HTTP request wrapper). */
|
|
1811
1674
|
async createAPI(params) {
|
|
1812
|
-
const resp = await
|
|
1675
|
+
const resp = await request(baseUrl, "/api/v1/skills", apiKey, {
|
|
1813
1676
|
method: "POST",
|
|
1814
|
-
|
|
1815
|
-
body: JSON.stringify({ ...params, type: "api" })
|
|
1677
|
+
body: { ...params, type: "api" }
|
|
1816
1678
|
});
|
|
1817
|
-
|
|
1818
|
-
return data.data || data;
|
|
1679
|
+
return resp.data ?? resp;
|
|
1819
1680
|
},
|
|
1820
1681
|
/** Create a skill from a built-in template. */
|
|
1821
1682
|
async createFromTemplate(params) {
|
|
1822
|
-
const resp = await
|
|
1683
|
+
const resp = await request(baseUrl, "/api/v1/skills/from-template", apiKey, {
|
|
1823
1684
|
method: "POST",
|
|
1824
|
-
|
|
1825
|
-
body: JSON.stringify(params)
|
|
1685
|
+
body: params
|
|
1826
1686
|
});
|
|
1827
|
-
|
|
1828
|
-
return data.data || data;
|
|
1687
|
+
return resp.data ?? resp;
|
|
1829
1688
|
},
|
|
1830
1689
|
/** Lift a workflow node into a reusable skill. */
|
|
1831
1690
|
async createFromNode(params) {
|
|
1832
|
-
const resp = await
|
|
1691
|
+
const resp = await request(baseUrl, "/api/v1/skills/from-node", apiKey, {
|
|
1833
1692
|
method: "POST",
|
|
1834
|
-
|
|
1835
|
-
body: JSON.stringify(params)
|
|
1693
|
+
body: params
|
|
1836
1694
|
});
|
|
1837
|
-
|
|
1838
|
-
return data.data || data;
|
|
1695
|
+
return resp.data ?? resp;
|
|
1839
1696
|
},
|
|
1840
1697
|
/** Update an LLM skill. */
|
|
1841
1698
|
async updateLLM(skillId, fields) {
|
|
1842
|
-
const resp = await
|
|
1699
|
+
const resp = await request(baseUrl, `/api/v1/skills/${skillId}`, apiKey, {
|
|
1843
1700
|
method: "PUT",
|
|
1844
|
-
|
|
1845
|
-
body: JSON.stringify({ ...fields, type: "llm" })
|
|
1701
|
+
body: { ...fields, type: "llm" }
|
|
1846
1702
|
});
|
|
1847
|
-
|
|
1848
|
-
return data.data || data;
|
|
1703
|
+
return resp.data ?? resp;
|
|
1849
1704
|
},
|
|
1850
1705
|
/** Update an API skill. */
|
|
1851
1706
|
async updateAPI(skillId, fields) {
|
|
1852
|
-
const resp = await
|
|
1707
|
+
const resp = await request(baseUrl, `/api/v1/skills/${skillId}`, apiKey, {
|
|
1853
1708
|
method: "PUT",
|
|
1854
|
-
|
|
1855
|
-
body: JSON.stringify({ ...fields, type: "api" })
|
|
1709
|
+
body: { ...fields, type: "api" }
|
|
1856
1710
|
});
|
|
1857
|
-
|
|
1858
|
-
return data.data || data;
|
|
1711
|
+
return resp.data ?? resp;
|
|
1859
1712
|
},
|
|
1860
1713
|
/** Delete a skill (irreversible if in-use workflows exist). */
|
|
1861
1714
|
async delete(skillId) {
|
|
1862
|
-
|
|
1863
|
-
method: "DELETE",
|
|
1864
|
-
headers: headers()
|
|
1865
|
-
});
|
|
1866
|
-
return resp.json();
|
|
1715
|
+
return request(baseUrl, `/api/v1/skills/${skillId}`, apiKey, { method: "DELETE" });
|
|
1867
1716
|
},
|
|
1868
1717
|
/** Validate a skill definition (without saving). */
|
|
1869
1718
|
async validate(skill) {
|
|
1870
|
-
|
|
1871
|
-
method: "POST",
|
|
1872
|
-
headers: headers(),
|
|
1873
|
-
body: JSON.stringify(skill)
|
|
1874
|
-
});
|
|
1875
|
-
return resp.json();
|
|
1719
|
+
return request(baseUrl, "/api/v1/skills/validate", apiKey, { method: "POST", body: skill });
|
|
1876
1720
|
},
|
|
1877
1721
|
/** Execute a skill immediately with an input payload (test / preview). */
|
|
1878
1722
|
async execute(skillId, inputPayload) {
|
|
1879
|
-
|
|
1880
|
-
method: "POST",
|
|
1881
|
-
headers: headers(),
|
|
1882
|
-
body: JSON.stringify(inputPayload)
|
|
1883
|
-
});
|
|
1884
|
-
return resp.json();
|
|
1723
|
+
return request(baseUrl, `/api/v1/skills/${skillId}/execute`, apiKey, { method: "POST", body: inputPayload });
|
|
1885
1724
|
}
|
|
1886
1725
|
};
|
|
1887
1726
|
};
|
|
@@ -1890,23 +1729,9 @@ var createSkillsClient = (apiKey, apiUrl) => {
|
|
|
1890
1729
|
var DEFAULT_API27 = "https://be.graph8.com";
|
|
1891
1730
|
var createIntentClient = (apiKey, apiUrl) => {
|
|
1892
1731
|
const baseUrl = apiUrl || DEFAULT_API27;
|
|
1893
|
-
const
|
|
1894
|
-
const
|
|
1895
|
-
|
|
1896
|
-
return resp.json();
|
|
1897
|
-
};
|
|
1898
|
-
const post = async (path, body = {}) => {
|
|
1899
|
-
const resp = await fetch(`${baseUrl}/api/v1${path}`, {
|
|
1900
|
-
method: "POST",
|
|
1901
|
-
headers: headers(),
|
|
1902
|
-
body: JSON.stringify(body)
|
|
1903
|
-
});
|
|
1904
|
-
return resp.json();
|
|
1905
|
-
};
|
|
1906
|
-
const del = async (path) => {
|
|
1907
|
-
const resp = await fetch(`${baseUrl}/api/v1${path}`, { method: "DELETE", headers: headers() });
|
|
1908
|
-
return resp.json();
|
|
1909
|
-
};
|
|
1732
|
+
const get = (path) => request(baseUrl, `/api/v1${path}`, apiKey);
|
|
1733
|
+
const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
|
|
1734
|
+
const del = (path) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "DELETE" });
|
|
1910
1735
|
return {
|
|
1911
1736
|
/** Org-level intent stats (totals over the last 30 days). */
|
|
1912
1737
|
async stats() {
|
|
@@ -1963,12 +1788,10 @@ var createIntentClient = (apiKey, apiUrl) => {
|
|
|
1963
1788
|
* of the intent surface — we call it directly here instead of through the shared `post()` helper.
|
|
1964
1789
|
*/
|
|
1965
1790
|
async urlCompanies(url, params = {}) {
|
|
1966
|
-
|
|
1791
|
+
return request(baseUrl, "/intent-search/url-companies", apiKey, {
|
|
1967
1792
|
method: "POST",
|
|
1968
|
-
|
|
1969
|
-
body: JSON.stringify({ url, ...params })
|
|
1793
|
+
body: { url, ...params }
|
|
1970
1794
|
});
|
|
1971
|
-
return resp.json();
|
|
1972
1795
|
}
|
|
1973
1796
|
};
|
|
1974
1797
|
};
|
|
@@ -1977,19 +1800,7 @@ var createIntentClient = (apiKey, apiUrl) => {
|
|
|
1977
1800
|
var DEFAULT_API28 = "https://be.graph8.com";
|
|
1978
1801
|
var createStudioClient = (apiKey, apiUrl) => {
|
|
1979
1802
|
const baseUrl = apiUrl || DEFAULT_API28;
|
|
1980
|
-
const
|
|
1981
|
-
const toQuery = (params) => {
|
|
1982
|
-
const qs = new URLSearchParams();
|
|
1983
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1984
|
-
if (v != null) qs.set(k, String(v));
|
|
1985
|
-
}
|
|
1986
|
-
const s = qs.toString();
|
|
1987
|
-
return s ? `?${s}` : "";
|
|
1988
|
-
};
|
|
1989
|
-
const get = async (path, params = {}) => {
|
|
1990
|
-
const resp = await fetch(`${baseUrl}/api/v1${path}${toQuery(params)}`, { headers: headers() });
|
|
1991
|
-
return resp.json();
|
|
1992
|
-
};
|
|
1803
|
+
const get = (path, params = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { query: params });
|
|
1993
1804
|
return {
|
|
1994
1805
|
/** Org-level Studio documents (brand_brief, value_props, messaging_house, etc.).
|
|
1995
1806
|
* `include_content` defaults to true server-side, so each document includes
|
|
@@ -2020,33 +1831,187 @@ var createStudioClient = (apiKey, apiUrl) => {
|
|
|
2020
1831
|
var DEFAULT_API29 = "https://be.graph8.com";
|
|
2021
1832
|
var createMeetingsClient = (apiKey, apiUrl) => {
|
|
2022
1833
|
const baseUrl = apiUrl || DEFAULT_API29;
|
|
2023
|
-
const headers = () => ({ "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` });
|
|
2024
|
-
const toQuery = (params) => {
|
|
2025
|
-
const qs = new URLSearchParams();
|
|
2026
|
-
for (const [k, v] of Object.entries(params)) {
|
|
2027
|
-
if (v != null) qs.set(k, String(v));
|
|
2028
|
-
}
|
|
2029
|
-
const s = qs.toString();
|
|
2030
|
-
return s ? `?${s}` : "";
|
|
2031
|
-
};
|
|
2032
1834
|
return {
|
|
2033
1835
|
/** List meetings with optional filters. Returns summary rows without transcript / analysis. */
|
|
2034
1836
|
async list(params = {}) {
|
|
2035
|
-
|
|
2036
|
-
return resp.json();
|
|
1837
|
+
return request(baseUrl, "/api/v1/inbox/meetings", apiKey, { query: params });
|
|
2037
1838
|
},
|
|
2038
1839
|
/** Get full meeting detail including transcript + AI analysis (transcript available 1-5 min after meeting ends). */
|
|
2039
1840
|
async get(meetingId) {
|
|
2040
|
-
const resp = await
|
|
2041
|
-
|
|
2042
|
-
|
|
1841
|
+
const resp = await request(baseUrl, `/api/v1/inbox/meetings/${meetingId}`, apiKey);
|
|
1842
|
+
return resp.data ?? resp;
|
|
1843
|
+
}
|
|
1844
|
+
};
|
|
1845
|
+
};
|
|
1846
|
+
|
|
1847
|
+
// src/audiences.ts
|
|
1848
|
+
var DEFAULT_API30 = "https://be.graph8.com";
|
|
1849
|
+
var createAudiencesClient = (apiKey, apiUrl) => {
|
|
1850
|
+
const baseUrl = apiUrl || DEFAULT_API30;
|
|
1851
|
+
const base = "/api/v1/audience-syncs";
|
|
1852
|
+
return {
|
|
1853
|
+
/** List all audience syncs for the organization. */
|
|
1854
|
+
async list() {
|
|
1855
|
+
return request(baseUrl, base, apiKey);
|
|
1856
|
+
},
|
|
1857
|
+
/** Create a new audience sync to an ad platform. */
|
|
1858
|
+
async create(params) {
|
|
1859
|
+
const resp = await request(baseUrl, base, apiKey, {
|
|
1860
|
+
method: "POST",
|
|
1861
|
+
body: params
|
|
1862
|
+
});
|
|
1863
|
+
return resp.data ?? resp;
|
|
1864
|
+
},
|
|
1865
|
+
/** Get a single audience sync by ID. */
|
|
1866
|
+
async get(configId) {
|
|
1867
|
+
const resp = await request(baseUrl, `${base}/${configId}`, apiKey);
|
|
1868
|
+
return resp.data ?? resp;
|
|
1869
|
+
},
|
|
1870
|
+
/** Update an audience sync (partial). */
|
|
1871
|
+
async update(configId, fields) {
|
|
1872
|
+
const resp = await request(baseUrl, `${base}/${configId}`, apiKey, {
|
|
1873
|
+
method: "PATCH",
|
|
1874
|
+
body: fields
|
|
1875
|
+
});
|
|
1876
|
+
return resp.data ?? resp;
|
|
1877
|
+
},
|
|
1878
|
+
/** Delete an audience sync. */
|
|
1879
|
+
async delete(configId) {
|
|
1880
|
+
return request(baseUrl, `${base}/${configId}`, apiKey, { method: "DELETE" });
|
|
1881
|
+
},
|
|
1882
|
+
/** Trigger an immediate sync run for a config. */
|
|
1883
|
+
async trigger(configId) {
|
|
1884
|
+
return request(baseUrl, `${base}/${configId}/trigger`, apiKey, { method: "POST" });
|
|
1885
|
+
},
|
|
1886
|
+
/** List recent sync runs for a config (most recent first). */
|
|
1887
|
+
async runs(configId) {
|
|
1888
|
+
return request(baseUrl, `${base}/${configId}/runs`, apiKey);
|
|
1889
|
+
},
|
|
1890
|
+
/** List recent sync errors for a config. */
|
|
1891
|
+
async errors(configId) {
|
|
1892
|
+
return request(baseUrl, `${base}/${configId}/errors`, apiKey);
|
|
1893
|
+
}
|
|
1894
|
+
};
|
|
1895
|
+
};
|
|
1896
|
+
|
|
1897
|
+
// src/search.ts
|
|
1898
|
+
var DEFAULT_API31 = "https://be.graph8.com";
|
|
1899
|
+
var createSearchClient = (apiKey, apiUrl) => {
|
|
1900
|
+
const baseUrl = apiUrl || DEFAULT_API31;
|
|
1901
|
+
const body = (p) => ({ filters: [], page: 1, limit: 25, ...p });
|
|
1902
|
+
return {
|
|
1903
|
+
/** Search open-data contacts by filter. */
|
|
1904
|
+
async contacts(params = {}) {
|
|
1905
|
+
return request(baseUrl, "/api/v1/search/contacts", apiKey, { method: "POST", body: body(params) });
|
|
1906
|
+
},
|
|
1907
|
+
/** Search open-data companies by filter. */
|
|
1908
|
+
async companies(params = {}) {
|
|
1909
|
+
return request(baseUrl, "/api/v1/search/companies", apiKey, { method: "POST", body: body(params) });
|
|
1910
|
+
},
|
|
1911
|
+
/** Search contacts and save the matches into a new list. */
|
|
1912
|
+
async saveContacts(params) {
|
|
1913
|
+
const resp = await request(baseUrl, "/api/v1/search/contacts/save", apiKey, {
|
|
1914
|
+
method: "POST",
|
|
1915
|
+
body: { filters: [], page: 1, limit: 25, max_results: 1e3, ...params }
|
|
1916
|
+
});
|
|
1917
|
+
return resp.data ?? resp;
|
|
1918
|
+
},
|
|
1919
|
+
/** Search companies and save the matches into a new list. */
|
|
1920
|
+
async saveCompanies(params) {
|
|
1921
|
+
const resp = await request(baseUrl, "/api/v1/search/companies/save", apiKey, {
|
|
1922
|
+
method: "POST",
|
|
1923
|
+
body: { filters: [], page: 1, limit: 25, max_results: 1e3, ...params }
|
|
1924
|
+
});
|
|
1925
|
+
return resp.data ?? resp;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
};
|
|
1929
|
+
|
|
1930
|
+
// src/agency.ts
|
|
1931
|
+
var DEFAULT_API32 = "https://be.graph8.com";
|
|
1932
|
+
var createAgencyClient = (apiKey, apiUrl) => {
|
|
1933
|
+
const baseUrl = apiUrl || DEFAULT_API32;
|
|
1934
|
+
return {
|
|
1935
|
+
/** Describe the agency credential: agency org + authorized client count. */
|
|
1936
|
+
async me() {
|
|
1937
|
+
const resp = await request(baseUrl, "/api/v1/agency/me", apiKey);
|
|
1938
|
+
return resp.data ?? resp;
|
|
1939
|
+
},
|
|
1940
|
+
/** List the client orgs this agency key may target via `X-Target-Org-Id`. */
|
|
1941
|
+
async clients() {
|
|
1942
|
+
return request(baseUrl, "/api/v1/agency/clients", apiKey);
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1945
|
+
};
|
|
1946
|
+
|
|
1947
|
+
// src/marketplace.ts
|
|
1948
|
+
var DEFAULT_API33 = "https://be.graph8.com";
|
|
1949
|
+
var createMarketplaceClient = (apiKey, apiUrl) => {
|
|
1950
|
+
const baseUrl = apiUrl || DEFAULT_API33;
|
|
1951
|
+
const base = "/api/v1/marketplace";
|
|
1952
|
+
return {
|
|
1953
|
+
/** Your own marketplace SDR profile. */
|
|
1954
|
+
async profile() {
|
|
1955
|
+
const resp = await request(baseUrl, `${base}/me/profile`, apiKey);
|
|
1956
|
+
return resp.data ?? resp;
|
|
1957
|
+
},
|
|
1958
|
+
/** Pending hire offers you can accept or reject. */
|
|
1959
|
+
async offers() {
|
|
1960
|
+
const resp = await request(
|
|
1961
|
+
baseUrl,
|
|
1962
|
+
`${base}/me/offers`,
|
|
1963
|
+
apiKey
|
|
1964
|
+
);
|
|
1965
|
+
return resp.data ?? resp;
|
|
1966
|
+
},
|
|
1967
|
+
/** Accept a pending hire offer (by hiring id). */
|
|
1968
|
+
async acceptOffer(hiringId) {
|
|
1969
|
+
const resp = await request(
|
|
1970
|
+
baseUrl,
|
|
1971
|
+
`${base}/me/offers/${hiringId}/accept`,
|
|
1972
|
+
apiKey,
|
|
1973
|
+
{ method: "POST" }
|
|
1974
|
+
);
|
|
1975
|
+
return resp.data ?? resp;
|
|
1976
|
+
},
|
|
1977
|
+
/** Reject a pending hire offer (by hiring id). */
|
|
1978
|
+
async rejectOffer(hiringId) {
|
|
1979
|
+
const resp = await request(
|
|
1980
|
+
baseUrl,
|
|
1981
|
+
`${base}/me/offers/${hiringId}/reject`,
|
|
1982
|
+
apiKey,
|
|
1983
|
+
{ method: "POST" }
|
|
1984
|
+
);
|
|
1985
|
+
return resp.data ?? resp;
|
|
1986
|
+
},
|
|
1987
|
+
/** Your active hiring contracts. */
|
|
1988
|
+
async hirings() {
|
|
1989
|
+
const resp = await request(
|
|
1990
|
+
baseUrl,
|
|
1991
|
+
`${base}/me/hirings`,
|
|
1992
|
+
apiKey
|
|
1993
|
+
);
|
|
1994
|
+
return resp.data ?? resp;
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
};
|
|
1998
|
+
|
|
1999
|
+
// src/snippet.ts
|
|
2000
|
+
var DEFAULT_API34 = "https://be.graph8.com";
|
|
2001
|
+
var createSnippetClient = (apiKey, apiUrl) => {
|
|
2002
|
+
const baseUrl = apiUrl || DEFAULT_API34;
|
|
2003
|
+
return {
|
|
2004
|
+
/** Get your org's tracking snippet (write key + React/script-tag embeds + config). */
|
|
2005
|
+
async get() {
|
|
2006
|
+
const resp = await request(baseUrl, "/api/v1/snippet", apiKey);
|
|
2007
|
+
return resp.data ?? resp;
|
|
2043
2008
|
}
|
|
2044
2009
|
};
|
|
2045
2010
|
};
|
|
2046
2011
|
|
|
2047
2012
|
// src/core.ts
|
|
2048
2013
|
var DEFAULT_HOST = "https://t.graph8.com";
|
|
2049
|
-
var
|
|
2014
|
+
var DEFAULT_API35 = "https://be.graph8.com";
|
|
2050
2015
|
var G8 = class {
|
|
2051
2016
|
constructor() {
|
|
2052
2017
|
/** @internal */
|
|
@@ -2111,6 +2076,16 @@ var G8 = class {
|
|
|
2111
2076
|
this._studio = null;
|
|
2112
2077
|
/** @internal */
|
|
2113
2078
|
this._meetings = null;
|
|
2079
|
+
/** @internal */
|
|
2080
|
+
this._audiences = null;
|
|
2081
|
+
/** @internal */
|
|
2082
|
+
this._search = null;
|
|
2083
|
+
/** @internal */
|
|
2084
|
+
this._agency = null;
|
|
2085
|
+
/** @internal */
|
|
2086
|
+
this._marketplace = null;
|
|
2087
|
+
/** @internal */
|
|
2088
|
+
this._snippet = null;
|
|
2114
2089
|
}
|
|
2115
2090
|
/**
|
|
2116
2091
|
* Initialize the graph8 SDK. Must be called before any other method.
|
|
@@ -2125,7 +2100,7 @@ var G8 = class {
|
|
|
2125
2100
|
debug: config.debug
|
|
2126
2101
|
});
|
|
2127
2102
|
}
|
|
2128
|
-
const apiUrl = config.apiUrl ||
|
|
2103
|
+
const apiUrl = config.apiUrl || DEFAULT_API35;
|
|
2129
2104
|
const writeKey = config.writeKey || "";
|
|
2130
2105
|
const apiKey = config.apiKey || "";
|
|
2131
2106
|
if (writeKey) {
|
|
@@ -2160,6 +2135,11 @@ var G8 = class {
|
|
|
2160
2135
|
this._intent = createIntentClient(apiKey, apiUrl);
|
|
2161
2136
|
this._studio = createStudioClient(apiKey, apiUrl);
|
|
2162
2137
|
this._meetings = createMeetingsClient(apiKey, apiUrl);
|
|
2138
|
+
this._audiences = createAudiencesClient(apiKey, apiUrl);
|
|
2139
|
+
this._search = createSearchClient(apiKey, apiUrl);
|
|
2140
|
+
this._agency = createAgencyClient(apiKey, apiUrl);
|
|
2141
|
+
this._marketplace = createMarketplaceClient(apiKey, apiUrl);
|
|
2142
|
+
this._snippet = createSnippetClient(apiKey, apiUrl);
|
|
2163
2143
|
this._signals = createSignalsClient(apiKey, true, apiUrl);
|
|
2164
2144
|
}
|
|
2165
2145
|
}
|
|
@@ -2326,6 +2306,31 @@ var G8 = class {
|
|
|
2326
2306
|
this._assertKey("meetings");
|
|
2327
2307
|
return this._meetings;
|
|
2328
2308
|
}
|
|
2309
|
+
/** Audiences — sync audience lists to ad platforms (Meta, LinkedIn, Google, X) (requires API key). */
|
|
2310
|
+
get audiences() {
|
|
2311
|
+
this._assertKey("audiences");
|
|
2312
|
+
return this._audiences;
|
|
2313
|
+
}
|
|
2314
|
+
/** Search — prospect open-data contacts + companies by filter, optionally save to a list (requires API key). */
|
|
2315
|
+
get search() {
|
|
2316
|
+
this._assertKey("search");
|
|
2317
|
+
return this._search;
|
|
2318
|
+
}
|
|
2319
|
+
/** Agency — for agency keys: discover the agency credential + the client orgs it may target (requires API key). */
|
|
2320
|
+
get agency() {
|
|
2321
|
+
this._assertKey("agency");
|
|
2322
|
+
return this._agency;
|
|
2323
|
+
}
|
|
2324
|
+
/** Marketplace — for SDR/AE talent: profile, hire offers (accept/reject), active hirings (requires API key). */
|
|
2325
|
+
get marketplace() {
|
|
2326
|
+
this._assertKey("marketplace");
|
|
2327
|
+
return this._marketplace;
|
|
2328
|
+
}
|
|
2329
|
+
/** Snippet — fetch your org's tracking snippet (write key + React/script-tag embeds + config) for embedding (requires API key). */
|
|
2330
|
+
get snippet() {
|
|
2331
|
+
this._assertKey("snippet");
|
|
2332
|
+
return this._snippet;
|
|
2333
|
+
}
|
|
2329
2334
|
/** Whether the SDK has been initialized. */
|
|
2330
2335
|
get initialized() {
|
|
2331
2336
|
return this.config !== null;
|
|
@@ -2343,6 +2348,15 @@ var G8 = class {
|
|
|
2343
2348
|
var g8 = new G8();
|
|
2344
2349
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2345
2350
|
0 && (module.exports = {
|
|
2346
|
-
|
|
2351
|
+
G8Error,
|
|
2352
|
+
KNOWN_WEBHOOK_EVENTS,
|
|
2353
|
+
WebhookSignatureError,
|
|
2354
|
+
backoffDelayMs,
|
|
2355
|
+
constructEvent,
|
|
2356
|
+
g8,
|
|
2357
|
+
isRetryableStatus,
|
|
2358
|
+
paginate,
|
|
2359
|
+
parseRetryAfter,
|
|
2360
|
+
request
|
|
2347
2361
|
});
|
|
2348
2362
|
//# sourceMappingURL=index.js.map
|