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