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