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