@graph8/sdk 0.357.0 → 0.361.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.browser.js +1 -1
  3. package/dist/index.browser.js.map +1 -1
  4. package/dist/index.browser.mjs +1 -1
  5. package/dist/index.browser.mjs.map +1 -1
  6. package/dist/index.d.mts +115 -9
  7. package/dist/index.d.ts +115 -9
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +1 -1
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/react.browser.js +1 -1
  13. package/dist/react.browser.js.map +1 -1
  14. package/dist/react.browser.mjs +1 -1
  15. package/dist/react.browser.mjs.map +1 -1
  16. package/dist/react.d.mts +112 -6
  17. package/dist/react.d.ts +112 -6
  18. package/dist/react.js +1 -1
  19. package/dist/react.js.map +1 -1
  20. package/dist/react.mjs +1 -1
  21. package/dist/react.mjs.map +1 -1
  22. package/dist/types/core.d.ts +3 -2
  23. package/dist/types/react.d.ts +2 -0
  24. package/dist/types/studio.d.ts +48 -0
  25. package/dist/types/version.d.ts +2 -2
  26. package/docs/api/adCampaigns.d.ts +4 -0
  27. package/docs/api/adCampaigns.md +4 -0
  28. package/docs/api/enrichment.d.ts +18 -0
  29. package/docs/api/enrichment.md +25 -4
  30. package/docs/api/gtmCampaigns.d.ts +4 -0
  31. package/docs/api/gtmCampaigns.md +2 -0
  32. package/docs/api/gtmContext.d.ts +5 -1
  33. package/docs/api/gtmContext.md +15 -7
  34. package/docs/api/integrations.d.ts +29 -4
  35. package/docs/api/integrations.md +14 -0
  36. package/docs/api/revenueLifecycle.d.ts +3 -1
  37. package/docs/api/revenueLifecycle.md +12 -2
  38. package/docs/api/seo.d.ts +1 -1
  39. package/docs/api/seo.md +1 -1
  40. package/docs/api/workflows.md +46 -2
  41. package/docs/sdk-clients.md +1 -1
  42. package/package.json +1 -1
@@ -888,6 +888,8 @@ declare class G8 {
888
888
  category?: string;
889
889
  limit?: number;
890
890
  include_content?: boolean;
891
+ include_intelligence?: boolean;
892
+ include_research?: boolean;
891
893
  }): Promise<{
892
894
  data: import("./studio").GlobalContextDocument[];
893
895
  }>;
@@ -899,8 +901,7 @@ declare class G8 {
899
901
  }>;
900
902
  personas(params?: {
901
903
  status?: string;
902
- limit
903
- /** @internal */ ? /** @internal */: number;
904
+ limit?: number;
904
905
  }): Promise<{
905
906
  data: import("./studio").Persona[];
906
907
  }>;
@@ -824,6 +824,8 @@ export declare const useG8: () => {
824
824
  category?: string;
825
825
  limit?: number;
826
826
  include_content?: boolean;
827
+ include_intelligence?: boolean;
828
+ include_research?: boolean;
827
829
  }): Promise<{
828
830
  data: import("./studio").GlobalContextDocument[];
829
831
  }>;
@@ -6,6 +6,18 @@ export interface GlobalContextDocument {
6
6
  metadata: Record<string, unknown> | null;
7
7
  created_at: string | null;
8
8
  updated_at: string | null;
9
+ /** Fields the endpoint actually returns (the ones above predate them). */
10
+ display_name?: string | null;
11
+ file_type?: string | null;
12
+ folder_path?: string | null;
13
+ status?: string | null;
14
+ priority?: number | null;
15
+ version?: string | number | null;
16
+ /** The group the Studio Wiki shows the document under (TAM / ICP / Persona
17
+ * Research are stored as market/audience but shown under "targeting"). */
18
+ wiki_category?: string;
19
+ /** Which Wiki bucket the row came from. */
20
+ workflow?: "context" | "intelligence" | "research";
9
21
  }
10
22
  export interface Persona {
11
23
  id: string;
@@ -16,6 +28,20 @@ export interface Persona {
16
28
  goals: string[];
17
29
  channels: string[];
18
30
  created_at: string | null;
31
+ /** Fields GET /personas actually returns (cb_personas columns). The persona's
32
+ * name is `title`, its "why" is `why_target`, its signals are `key_signals`. */
33
+ title?: string | null;
34
+ why_target?: string | null;
35
+ key_signals?: unknown[];
36
+ campaign_approach?: string | null;
37
+ recommended_goal?: string | null;
38
+ expected_receptivity?: string | null;
39
+ confidence?: string | null;
40
+ confidence_score?: number | null;
41
+ priority?: number | null;
42
+ pinned?: boolean | null;
43
+ source?: string | null;
44
+ updated_at?: string | null;
19
45
  }
20
46
  export interface ICP {
21
47
  id: string;
@@ -29,6 +55,24 @@ export interface ICP {
29
55
  revenue_max: number | null;
30
56
  countries: string[] | null;
31
57
  created_at: string | null;
58
+ /** Fields GET /icps actually returns (cb_icps columns). Industries and
59
+ * company sizes live in `firmographics.industries` / `firmographics.company_sizes`. */
60
+ firmographics?: {
61
+ industries?: string[];
62
+ company_sizes?: string[];
63
+ revenue_ranges?: string[];
64
+ geographies?: string[];
65
+ [key: string]: unknown;
66
+ };
67
+ tech_stack?: Record<string, unknown>;
68
+ buying_signals?: unknown[];
69
+ fit_score?: number | null;
70
+ opportunity_score?: number | null;
71
+ readiness_score?: number | null;
72
+ total_score?: number | null;
73
+ pinned?: boolean | null;
74
+ priority?: number | null;
75
+ updated_at?: string | null;
32
76
  }
33
77
  export interface IntelligenceData {
34
78
  id: string;
@@ -67,6 +111,10 @@ export declare const createStudioClient: (apiKey: string, apiUrl?: string) => {
67
111
  category?: string;
68
112
  limit?: number;
69
113
  include_content?: boolean;
114
+ /** Also list the Wiki's Intelligence documents (metadata only). */
115
+ include_intelligence?: boolean;
116
+ /** Also list the Wiki's Research reports. */
117
+ include_research?: boolean;
70
118
  }): Promise<{
71
119
  data: GlobalContextDocument[];
72
120
  }>;
@@ -5,6 +5,6 @@
5
5
  * both together (the version-parity gate already pins package.json, the
6
6
  * lockfile and the CHANGELOG to each other).
7
7
  */
8
- export declare const SDK_VERSION = "0.357.0";
8
+ export declare const SDK_VERSION = "0.361.0";
9
9
  /** Value of the `X-G8-Client` header every SDK request carries (I-13). */
10
- export declare const SDK_CLIENT_ID = "js-sdk/0.357.0";
10
+ export declare const SDK_CLIENT_ID = "js-sdk/0.361.0";
@@ -425,10 +425,14 @@ export interface AdCampaignResponse {
425
425
  launched_at?: string | null;
426
426
  name: string;
427
427
  objective?: string | null;
428
+ /** True when end_date is before today (UTC). Null when the campaign has no end date. */
429
+ past_end_date?: boolean | null;
428
430
  platform: string;
429
431
  platform_campaign_id?: string | null;
430
432
  start_date?: string | null;
431
433
  status: string;
434
+ /** Plain-language note when the stored status cannot be taken at face value, e.g. the end date has passed but the status still says pending. Null otherwise. */
435
+ status_note?: string | null;
432
436
  sync_config_id: number;
433
437
  }
434
438
 
@@ -324,8 +324,10 @@ Other envelope fields: `pagination` (PaginationMeta).
324
324
  | `google_campaign_subtype` | `string \| null` | no | |
325
325
  | `launched_at` | `string \| null` | no | |
326
326
  | `objective` | `string \| null` | no | |
327
+ | `past_end_date` | `boolean \| null` | no | True when end_date is before today (UTC). Null when the campaign has no end date. |
327
328
  | `platform_campaign_id` | `string \| null` | no | |
328
329
  | `start_date` | `string \| null` | no | |
330
+ | `status_note` | `string \| null` | no | Plain-language note when the stored status cannot be taken at face value, e.g. the end date has passed but the status still says pending. Null otherwise. |
329
331
 
330
332
  **Example**
331
333
 
@@ -598,8 +600,10 @@ Other envelope fields: `pagination` (PaginationMeta).
598
600
  | `google_campaign_subtype` | `string \| null` | no | |
599
601
  | `launched_at` | `string \| null` | no | |
600
602
  | `objective` | `string \| null` | no | |
603
+ | `past_end_date` | `boolean \| null` | no | True when end_date is before today (UTC). Null when the campaign has no end date. |
601
604
  | `platform_campaign_id` | `string \| null` | no | |
602
605
  | `start_date` | `string \| null` | no | |
606
+ | `status_note` | `string \| null` | no | Plain-language note when the stored status cannot be taken at face value, e.g. the end date has passed but the status still says pending. Null otherwise. |
603
607
 
604
608
  **Example**
605
609
 
@@ -355,6 +355,8 @@ export interface EnrichmentOperations {
355
355
  query?: {
356
356
  /** Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. */
357
357
  hard_delete?: boolean;
358
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
359
+ scope?: string | null;
358
360
  };
359
361
  headers?: {
360
362
  "X-Target-Org-Id"?: string | null;
@@ -376,6 +378,8 @@ export interface EnrichmentOperations {
376
378
  query?: {
377
379
  /** Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. */
378
380
  hard_delete?: boolean;
381
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
382
+ scope?: string | null;
379
383
  };
380
384
  headers?: {
381
385
  "X-Target-Org-Id"?: string | null;
@@ -414,6 +418,8 @@ export interface EnrichmentOperations {
414
418
  query?: {
415
419
  /** Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. */
416
420
  hard_delete?: boolean;
421
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
422
+ scope?: string | null;
417
423
  };
418
424
  headers?: {
419
425
  "X-Target-Org-Id"?: string | null;
@@ -1566,6 +1572,10 @@ export interface EnrichmentOperations {
1566
1572
  /** AI group id. */
1567
1573
  group_id: string;
1568
1574
  };
1575
+ query?: {
1576
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
1577
+ scope?: string | null;
1578
+ };
1569
1579
  headers?: {
1570
1580
  "X-Target-Org-Id"?: string | null;
1571
1581
  };
@@ -1829,6 +1839,10 @@ export interface EnrichmentOperations {
1829
1839
  /** The AI group id. */
1830
1840
  group_id: string;
1831
1841
  };
1842
+ query?: {
1843
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
1844
+ scope?: string | null;
1845
+ };
1832
1846
  headers?: {
1833
1847
  "X-Target-Org-Id"?: string | null;
1834
1848
  };
@@ -1883,6 +1897,10 @@ export interface EnrichmentOperations {
1883
1897
  /** Enrichment configuration id (UUID). */
1884
1898
  config_id: string;
1885
1899
  };
1900
+ query?: {
1901
+ /** Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. */
1902
+ scope?: string | null;
1903
+ };
1886
1904
  headers?: {
1887
1905
  "X-Target-Org-Id"?: string | null;
1888
1906
  };
@@ -802,7 +802,9 @@ const result = await g8.api.enrichment.createRoutingRule({ body: { name: "Exampl
802
802
  Drop ONE column from an AI group. The group and its other columns stay.
803
803
 
804
804
  Free. `columns` is plural here where the app writes `column`, so the path
805
- reads the same way as every other collection in this contract.
805
+ reads the same way as every other collection in this contract. A column of
806
+ a qualification group shared by every list answers 409 unless `scope=org`
807
+ (admin keys only).
806
808
 
807
809
  **Input**
808
810
 
@@ -811,6 +813,7 @@ reads the same way as every other collection in this contract.
811
813
  | `path.group_id` | `string` | yes | AI group id. |
812
814
  | `path.column_id` | `string` | yes | The single column to drop. |
813
815
  | `query.hard_delete` | `boolean` | no | Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. default `false` |
816
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
814
817
 
815
818
  **Returns** `ApiResponse_EnrichmentPayload_`: the envelope `{ data: EnrichmentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
816
819
 
@@ -838,12 +841,16 @@ const result = await g8.api.enrichment.deleteAiConfigByColumn({ path: { group_id
838
841
 
839
842
  Remove an AI group and every column it owns. Free.
840
843
 
844
+ A qualification group shared by every list answers 409 unless `scope=org`
845
+ (admin keys only).
846
+
841
847
  **Input**
842
848
 
843
849
  | Field | Type | Required | Description |
844
850
  |---|---|---|---|
845
851
  | `path.group_id` | `string` | yes | AI group id. |
846
852
  | `query.hard_delete` | `boolean` | no | Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. default `false` |
853
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
847
854
 
848
855
  **Returns** `ApiResponse_EnrichmentPayload_`: the envelope `{ data: EnrichmentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
849
856
 
@@ -903,12 +910,16 @@ const result = await g8.api.enrichment.deleteAutoEnrichmentConfig({ path: { conf
903
910
 
904
911
  Remove an enrichment configuration. Free.
905
912
 
913
+ A qualification configuration shared by every list answers 409 unless
914
+ `scope=org` (admin keys only).
915
+
906
916
  **Input**
907
917
 
908
918
  | Field | Type | Required | Description |
909
919
  |---|---|---|---|
910
920
  | `path.config_id` | `string` | yes | Enrichment configuration id (UUID). |
911
921
  | `query.hard_delete` | `boolean` | no | Remove the configuration permanently instead of deactivating it. The values it already wrote are kept either way. default `false` |
922
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
912
923
 
913
924
  **Returns** `ApiResponse_EnrichmentPayload_`: the envelope `{ data: EnrichmentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
914
925
 
@@ -3505,7 +3516,8 @@ const result = await g8.api.enrichment.previewRoutingRule({ body: { source_list_
3505
3516
  Rename the column an AI group writes into. Free.
3506
3517
 
3507
3518
  Display name only - the underlying column id does not move, so formulas and
3508
- mappings that reference it keep working.
3519
+ mappings that reference it keep working. A qualification group shared by
3520
+ every list answers 409 unless `scope=org` (admin keys only).
3509
3521
 
3510
3522
  **Input**
3511
3523
 
@@ -3513,6 +3525,7 @@ mappings that reference it keep working.
3513
3525
  |---|---|---|---|
3514
3526
  | `path.group_id` | `string` | yes | AI group id. |
3515
3527
  | `body` | `RenameAIColumnRequest` | yes | Request body; fields below. |
3528
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
3516
3529
 
3517
3530
  Body fields (`RenameAIColumnRequest`):
3518
3531
 
@@ -4006,6 +4019,10 @@ EVERY list in the organisation, not just `config.list_id`. That is the
4006
4019
  wider blast radius of the two and it is what you get by omission, so set it
4007
4020
  deliberately.
4008
4021
 
4022
+ A `config.group_id` naming a qualification group shared by every list (the
4023
+ ICP and Persona qualification groups) answers 409 with code
4024
+ `shared_qualification_group`: those groups cannot gain columns here.
4025
+
4009
4026
  **Input**
4010
4027
 
4011
4028
  | Field | Type | Required | Description |
@@ -4308,7 +4325,8 @@ const result = await g8.api.enrichment.unassignConfigFromList({
4308
4325
  Edit an AI group in place. Free: editing runs nothing.
4309
4326
 
4310
4327
  Output columns that already exist keep their data; the run condition is
4311
- validated before anything is saved.
4328
+ validated before anything is saved. A qualification group shared by every
4329
+ list answers 409 unless `scope=org` (admin keys only).
4312
4330
 
4313
4331
  **Input**
4314
4332
 
@@ -4316,6 +4334,7 @@ validated before anything is saved.
4316
4334
  |---|---|---|---|
4317
4335
  | `path.group_id` | `string` | yes | The AI group id. |
4318
4336
  | `body` | `UpdateAIConfigRequest` | yes | Request body; fields below. |
4337
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
4319
4338
 
4320
4339
  Body fields (`UpdateAIConfigRequest`):
4321
4340
 
@@ -4452,7 +4471,8 @@ Change fields on an enrichment configuration. Free.
4452
4471
  Whatever keys are sent are written - the app takes a free-form body here
4453
4472
  and this forwards it unchanged rather than narrowing what the browser can
4454
4473
  already do. `updated_by` is stamped from the calling key and cannot be
4455
- supplied.
4474
+ supplied. A qualification configuration shared by every list answers 409
4475
+ unless `scope=org` (admin keys only).
4456
4476
 
4457
4477
  **Input**
4458
4478
 
@@ -4460,6 +4480,7 @@ supplied.
4460
4480
  |---|---|---|---|
4461
4481
  | `path.config_id` | `string` | yes | Enrichment configuration id (UUID). |
4462
4482
  | `body` | `EnrichmentConfigUpdateRequest` | yes | Request body; fields below. |
4483
+ | `query.scope` | `string \| null` | no | Set to `org` to change or delete a qualification group shared by every list (the ICP and Persona qualification groups). Admin keys only. Without it such a call answers 409 with code `shared_qualification_group`. |
4463
4484
 
4464
4485
  Body fields (`EnrichmentConfigUpdateRequest`):
4465
4486
 
@@ -529,6 +529,8 @@ export interface CampaignFullPatchRequest {
529
529
  primary_hook?: string | null;
530
530
  /** If provided, replaces the sequence step ordering (same as PUT /sequence). */
531
531
  sequence_steps?: Array<SequenceStepRef> | null;
532
+ /** Replace the campaign's channels (email, linkedin, phone, voice_ai, sms). Omit to leave them unchanged. Same as PATCH /campaigns/{id}. */
533
+ target_channels?: Array<string> | null;
532
534
  target_persona?: string | null;
533
535
  /** Sequence IDs to UNLINK from this campaign. DELETEs ONLY rows where status='linked'. Launch-audit rows (status='pushed'/'superseded'/'failed') are never touched — those are an immutable historical record. */
534
536
  unlink_sequence_ids?: Array<string> | null;
@@ -659,6 +661,8 @@ export interface developer_api__interfaces__v1__gtm_campaigns_router__CampaignUp
659
661
  name?: string | null;
660
662
  /** Primary hook text */
661
663
  primary_hook?: string | null;
664
+ /** Replace the campaign's channels, e.g. ['email','linkedin']. Accepted values: email, linkedin, phone, voice_ai, sms. Omit to leave them unchanged. Existing documents and steps are not deleted. */
665
+ target_channels?: Array<string> | null;
662
666
  /** Target persona */
663
667
  target_persona?: string | null;
664
668
  }
@@ -816,6 +816,7 @@ Body fields (`CampaignFullPatchRequest`):
816
816
  | `body.name` | `string \| null` | no | max length 255 |
817
817
  | `body.primary_hook` | `string \| null` | no | |
818
818
  | `body.sequence_steps` | `Array<SequenceStepRef> \| null` | no | If provided, replaces the sequence step ordering (same as PUT /sequence). |
819
+ | `body.target_channels` | `Array<string> \| null` | no | Replace the campaign's channels (email, linkedin, phone, voice_ai, sms). Omit to leave them unchanged. Same as PATCH /campaigns/{id}. |
819
820
  | `body.target_persona` | `string \| null` | no | max length 200 |
820
821
  | `body.unlink_sequence_ids` | `Array<string> \| null` | no | Sequence IDs to UNLINK from this campaign. DELETEs ONLY rows where status='linked'. Launch-audit rows (status='pushed'/'superseded'/'failed') are never touched — those are an immutable historical record. |
821
822
 
@@ -862,6 +863,7 @@ Body fields (`developer_api__interfaces__v1__gtm_campaigns_router__CampaignUpdat
862
863
  | `body.goal` | `string \| null` | no | Campaign goal max length 255 |
863
864
  | `body.name` | `string \| null` | no | Campaign name max length 255 |
864
865
  | `body.primary_hook` | `string \| null` | no | Primary hook text |
866
+ | `body.target_channels` | `Array<string> \| null` | no | Replace the campaign's channels, e.g. ['email','linkedin']. Accepted values: email, linkedin, phone, voice_ai, sms. Omit to leave them unchanged. Existing documents and steps are not deleted. |
865
867
  | `body.target_persona` | `string \| null` | no | Target persona max length 200 |
866
868
 
867
869
  **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
@@ -399,10 +399,14 @@ export interface GtmContextOperations {
399
399
  list_global_context_documents_global_context_documents_get: {
400
400
  input: {
401
401
  query?: {
402
- /** Filter by context category */
402
+ /** Filter by context category: brand, audience, messaging, market, offer, targeting, data (case-insensitive). `targeting` matches the Studio Wiki's Targeting group (TAM / ICP / Persona Research). An unknown category that matches no document returns 422 listing the valid categories. */
403
403
  category?: string | null;
404
404
  /** Include each document's body text at `content` (read from meta_data.content). Default True preserves historical behavior (this endpoint has always returned content); pass false for a lighter metadata-only listing. */
405
405
  include_content?: boolean;
406
+ /** Also list the Wiki's Intelligence documents (website scrape, competitor discovery, organic keywords, brand news, ...) with `workflow`='intelligence' and category 'data'. Metadata only: read a body with GET /intelligence-data ?data_type=<file_type>&include_content=true. Default false (historical shape). */
407
+ include_intelligence?: boolean;
408
+ /** Also list the Wiki's Research reports with `workflow`='research' and category 'data'; `content` carries the report markdown when include_content is true. Default false (historical shape). */
409
+ include_research?: boolean;
406
410
  limit?: number;
407
411
  };
408
412
  headers?: {
@@ -915,21 +915,29 @@ const result = await g8.api.gtmContext.listActivities();
915
915
  List global context documents for the authenticated organization.
916
916
 
917
917
  Each row carries metadata (id, display_name, file_type, category,
918
- folder_path, status, priority, version, timestamps). When
919
- ``include_content`` is True (the default) the document body is included at
920
- ``content`` (sourced from ``meta_data.content``) so callers can read what a
921
- document actually says; pass ``include_content=false`` to omit the body for
922
- a cheaper listing. The default stays True for backwards compatibility — the
923
- MCP ``g8_gtm_get_global_context`` tool, the JS SDK ``studio.globalContext``
918
+ folder_path, status, priority, version, timestamps), plus `wiki_category`
919
+ (the group the Studio Wiki shows it under) and `workflow` (context,
920
+ intelligence or research). When ``include_content`` is True (the default)
921
+ the document body is included at ``content`` (sourced from
922
+ ``meta_data.content``) so callers can read what a document actually says;
923
+ pass ``include_content=false`` to omit the body for a cheaper listing. The
924
+ default stays True for backwards compatibility — the MCP
925
+ ``g8_gtm_get_global_context`` tool, the JS SDK ``studio.globalContext``
924
926
  client, and the ``g8://global-context`` resource surfaces have always relied
925
927
  on ``content`` being present.
926
928
 
929
+ ``include_intelligence`` / ``include_research`` add the Wiki's other two
930
+ buckets so a caller can see every Wiki document in one call; ``limit``
931
+ applies to each bucket.
932
+
927
933
  **Input**
928
934
 
929
935
  | Field | Type | Required | Description |
930
936
  |---|---|---|---|
931
- | `query.category` | `string \| null` | no | Filter by context category |
937
+ | `query.category` | `string \| null` | no | Filter by context category: brand, audience, messaging, market, offer, targeting, data (case-insensitive). `targeting` matches the Studio Wiki's Targeting group (TAM / ICP / Persona Research). An unknown category that matches no document returns 422 listing the valid categories. |
932
938
  | `query.include_content` | `boolean` | no | Include each document's body text at `content` (read from meta_data.content). Default True preserves historical behavior (this endpoint has always returned content); pass false for a lighter metadata-only listing. default `true` |
939
+ | `query.include_intelligence` | `boolean` | no | Also list the Wiki's Intelligence documents (website scrape, competitor discovery, organic keywords, brand news, ...) with `workflow`='intelligence' and category 'data'. Metadata only: read a body with GET /intelligence-data ?data_type=<file_type>&include_content=true. Default false (historical shape). default `false` |
940
+ | `query.include_research` | `boolean` | no | Also list the Wiki's Research reports with `workflow`='research' and category 'data'; `content` carries the report markdown when include_content is true. Default false (historical shape). default `false` |
933
941
  | `query.limit` | `integer` | no | default `50` |
934
942
 
935
943
  **Returns** `ApiResponse_list_dict__`: the envelope `{ data: Array<Record<string, unknown>>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
@@ -1549,7 +1549,7 @@ export interface IntegrationsOperations {
1549
1549
  };
1550
1550
  }
1551
1551
 
1552
- // 64 schemas referenced above (the same as G8Contract.<Name>).
1552
+ // 65 schemas referenced above (the same as G8Contract.<Name>).
1553
1553
 
1554
1554
  /**
1555
1555
  * A list of ad-platform objects.
@@ -1653,14 +1653,19 @@ export interface BatchGetByEmailRequest {
1653
1653
  * This is the irreversible half: records begin landing in graph8 and a
1654
1654
  * migration cannot be un-run, only cancelled part-way.
1655
1655
  *
1656
- * Both fields are OPTIONAL and omitting them accepts the discovery as
1656
+ * Every field is OPTIONAL and omitting them accepts the discovery as
1657
1657
  * proposed - which is the point of previewing it first. Send
1658
- * `field_mappings_override` to change where a CRM field lands, or
1659
- * `selected_list_ids` to import only some lists.
1658
+ * `field_mappings_override` to change where a CRM field lands,
1659
+ * `selected_list_ids` to import only some lists, or `owner_decisions` to say
1660
+ * what happens to the records of Salesforce owners who are not in graph8.
1661
+ * A Salesforce discovery with an `unmatched` owner needs a decision for that
1662
+ * owner: without one the confirm is refused with 422.
1660
1663
  */
1661
1664
  export interface ConfirmMigrationRequest {
1662
1665
  /** Per entity type, the mappings to use instead of the discovered ones. Omit to accept what discovery proposed. */
1663
1666
  field_mappings_override?: Record<string, Array<Record<string, unknown>>> | null;
1667
+ /** Salesforce only: one decision per record owner who is not a graph8 member (at most 500). Required for every owner whose `match.status` is `unmatched`; optional `assign` for a `placeholder` owner. `match` moves every record the owner has; `assign` moves only their open deals and open tasks. */
1668
+ owner_decisions?: Array<MigrationOwnerDecision> | null;
1664
1669
  /** Import only these CRM lists. Omit to take every discovered list. */
1665
1670
  selected_list_ids?: Array<string> | null;
1666
1671
  }
@@ -2025,6 +2030,26 @@ export interface LeadUpdateRequest {
2025
2030
  website?: string | null;
2026
2031
  }
2027
2032
 
2033
+ /**
2034
+ * What happens to the records of one Salesforce record owner who is not a graph8 member.
2035
+ *
2036
+ * Discovery lists every record owner in the status's `owners`, each with a
2037
+ * `match.status`. An owner whose status is `unmatched` needs a decision, or
2038
+ * the confirm is refused with 422. An owner whose status is `placeholder`
2039
+ * (inactive in Salesforce, a rep who left) may only be assigned; without a
2040
+ * decision their records stay on the placeholder, as history.
2041
+ */
2042
+ export interface MigrationOwnerDecision {
2043
+ /** `invite`: invite the owner to graph8 by email; their records are held for the invited address and become theirs when they first sign in. Invites go out in a member's name, so an API key's confirm with an `invite` decision is refused with 403. `assign`: move only their OPEN deals and OPEN tasks to the graph8 member `assign_to_team_member_id`; contacts, companies and closed records stay on the owner's placeholder. `match`: this Salesforce user IS the graph8 member `assign_to_team_member_id`; EVERY record they own moves to that member. `unassigned`: import their records with no owner. */
2044
+ action: "invite" | "assign" | "unassigned" | "match";
2045
+ /** `assign` and `match` only: the graph8 team member id who receives the records. */
2046
+ assign_to_team_member_id?: string | null;
2047
+ /** `invite` only: the address to invite. Omit to use the owner's Salesforce email. */
2048
+ invite_email?: string | null;
2049
+ /** The owner's Salesforce user id, as discovery listed it in `owners`. */
2050
+ sf_user_id: string;
2051
+ }
2052
+
2028
2053
  /**
2029
2054
  * Add and/or remove contacts from one CRM list, in a single call.
2030
2055
  *
@@ -268,6 +268,7 @@ Body fields (`ConfirmMigrationRequest`):
268
268
  | Field | Type | Required | Description |
269
269
  |---|---|---|---|
270
270
  | `body.field_mappings_override` | `Record<string, Array<Record<string, unknown>>> \| null` | no | Per entity type, the mappings to use instead of the discovered ones. Omit to accept what discovery proposed. |
271
+ | `body.owner_decisions` | `Array<MigrationOwnerDecision> \| null` | no | Salesforce only: one decision per record owner who is not a graph8 member (at most 500). Required for every owner whose `match.status` is `unmatched`; optional `assign` for a `placeholder` owner. `match` moves every record the owner has; `assign` moves only their open deals and open tasks. max items 500 |
271
272
  | `body.selected_list_ids` | `Array<string> \| null` | no | Import only these CRM lists. Omit to take every discovered list. |
272
273
 
273
274
  **Returns** `ApiResponse_ConnectionPayload_`: the envelope `{ data: ConnectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
@@ -3789,3 +3790,16 @@ One provider-side custom field. `field_name` is the CRM's API name, not its labe
3789
3790
  |---|---|---|---|
3790
3791
  | `phone` | `string` | yes | |
3791
3792
  | `phone_type` | `string \| null` | no | |
3793
+
3794
+ <a id="type-migrationownerdecision"></a>
3795
+
3796
+ ### `MigrationOwnerDecision`
3797
+
3798
+ What happens to the records of one Salesforce record owner who is not a graph8 member. Discovery lists every record owner in the status's `owners`, each with a `match.status`. An owner whose status is `unmatched` needs a decision, or the confirm is refused with 422. An owner whose status is `placeholder` (inactive in Salesforce, a rep who left) may only be assigned; without a decision their records stay on the placeholder, as history.
3799
+
3800
+ | Field | Type | Required | Description |
3801
+ |---|---|---|---|
3802
+ | `action` | `"invite" \| "assign" \| "unassigned" \| "match"` | yes | `invite`: invite the owner to graph8 by email; their records are held for the invited address and become theirs when they first sign in. Invites go out in a member's name, so an API key's confirm with an `invite` decision is refused with 403. `assign`: move only their OPEN deals and OPEN tasks to the graph8 member `assign_to_team_member_id`; contacts, companies and closed records stay on the owne… |
3803
+ | `sf_user_id` | `string` | yes | The owner's Salesforce user id, as discovery listed it in `owners`. min length 1, max length 64 |
3804
+ | `assign_to_team_member_id` | `string \| null` | no | `assign` and `match` only: the graph8 team member id who receives the records. max length 64 |
3805
+ | `invite_email` | `string \| null` | no | `invite` only: the address to invite. Omit to use the owner's Salesforce email. max length 320 |
@@ -153,7 +153,9 @@ export interface LifecycleRecordItem {
153
153
  }
154
154
 
155
155
  export interface LifecycleStageMoveRequest {
156
- /** Company moves only: run every check the move runs (company exists, stage known, Customers/Churned guards) and return the would-be transition without writing anything. Ignored for contact moves. */
156
+ /** Confirm a move to Customers of a company with no subscription (or a contact with no company or whose company has none). Without it such a move is refused with 409 and detail.code 'customers_without_subscription'. */
157
+ confirm_without_subscription?: boolean;
158
+ /** Run every check the move runs (record exists, stage known, Customers/Churned guards, the no-subscription confirmation) and return the would-be transition without writing anything. */
157
159
  dry_run?: boolean;
158
160
  /** Destination lifecycle slug, e.g. 'suspects', 'leads', 'trials', 'customers', 'churned'. Case and surrounding whitespace are ignored, and a stage's display name is accepted too. */
159
161
  target_slug: string;
@@ -191,6 +191,10 @@ with a 400 unless the company is or was a customer. `target_slug` ignores
191
191
  case and surrounding whitespace. `dry_run: true` runs every check and
192
192
  returns the would-be transition without writing anything.
193
193
 
194
+ A move to `customers` of a company with no subscription at all is a 409
195
+ (`detail.code` 'customers_without_subscription', `detail.message` names the
196
+ company) unless `confirm_without_subscription: true` is sent (R3-30).
197
+
194
198
  **Input**
195
199
 
196
200
  | Field | Type | Required | Description |
@@ -203,7 +207,8 @@ Body fields (`LifecycleStageMoveRequest`):
203
207
  | Field | Type | Required | Description |
204
208
  |---|---|---|---|
205
209
  | `body.target_slug` | `string` | yes | Destination lifecycle slug, e.g. 'suspects', 'leads', 'trials', 'customers', 'churned'. Case and surrounding whitespace are ignored, and a stage's display name is accepted too. |
206
- | `body.dry_run` | `boolean` | no | Company moves only: run every check the move runs (company exists, stage known, Customers/Churned guards) and return the would-be transition without writing anything. Ignored for contact moves. default `false` |
210
+ | `body.confirm_without_subscription` | `boolean` | no | Confirm a move to Customers of a company with no subscription (or a contact with no company or whose company has none). Without it such a move is refused with 409 and detail.code 'customers_without_subscription'. default `false` |
211
+ | `body.dry_run` | `boolean` | no | Run every check the move runs (record exists, stage known, Customers/Churned guards, the no-subscription confirmation) and return the would-be transition without writing anything. default `false` |
207
212
 
208
213
  **Returns** `ApiResponse_LifecycleStageMoveResponse_`: the envelope `{ data: LifecycleStageMoveResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
209
214
 
@@ -247,6 +252,10 @@ yet, which is common for Suspects-stage contacts), and records the same
247
252
  audit trail the in-app Move-Stage dialog's contact mode does. Returns no
248
253
  contact PII (see the module docstring) — only the status transition.
249
254
 
255
+ A move to `customers` of a contact with no company, or whose company has no
256
+ subscription, is a 409 (`detail.code` 'customers_without_subscription')
257
+ unless `confirm_without_subscription: true` is sent (R3-31).
258
+
250
259
  **Input**
251
260
 
252
261
  | Field | Type | Required | Description |
@@ -259,7 +268,8 @@ Body fields (`LifecycleStageMoveRequest`):
259
268
  | Field | Type | Required | Description |
260
269
  |---|---|---|---|
261
270
  | `body.target_slug` | `string` | yes | Destination lifecycle slug, e.g. 'suspects', 'leads', 'trials', 'customers', 'churned'. Case and surrounding whitespace are ignored, and a stage's display name is accepted too. |
262
- | `body.dry_run` | `boolean` | no | Company moves only: run every check the move runs (company exists, stage known, Customers/Churned guards) and return the would-be transition without writing anything. Ignored for contact moves. default `false` |
271
+ | `body.confirm_without_subscription` | `boolean` | no | Confirm a move to Customers of a company with no subscription (or a contact with no company or whose company has none). Without it such a move is refused with 409 and detail.code 'customers_without_subscription'. default `false` |
272
+ | `body.dry_run` | `boolean` | no | Run every check the move runs (record exists, stage known, Customers/Churned guards, the no-subscription confirmation) and return the would-be transition without writing anything. default `false` |
263
273
 
264
274
  **Returns** `ApiResponse_LifecycleStageMoveResponse_`: the envelope `{ data: LifecycleStageMoveResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
265
275
 
package/docs/api/seo.d.ts CHANGED
@@ -859,7 +859,7 @@ export interface SeoResearchKeywordsResponse {
859
859
  * refused with a 422 if it carries a scheme or a path.
860
860
  */
861
861
  export interface SeoSaveTrackedKeywordsRequest {
862
- cadence?: "daily" | "weekly";
862
+ cadence?: "daily" | "weekly" | "manual";
863
863
  domain: string;
864
864
  keywords: Array<SeoTrackKeywordItem>;
865
865
  language_code?: string;
package/docs/api/seo.md CHANGED
@@ -1025,7 +1025,7 @@ Body fields (`SeoSaveTrackedKeywordsRequest`):
1025
1025
  |---|---|---|---|
1026
1026
  | `body.domain` | `string` | yes | min length 3, max length 255 |
1027
1027
  | `body.keywords` | `Array<SeoTrackKeywordItem>` | yes | min items 1, max items 100 |
1028
- | `body.cadence` | `"daily" \| "weekly"` | no | default `"daily"` |
1028
+ | `body.cadence` | `"daily" \| "weekly" \| "manual"` | no | default `"daily"` |
1029
1029
  | `body.language_code` | `string` | no | default `"en"`, max length 10 |
1030
1030
  | `body.location_code` | `integer` | no | default `2840` |
1031
1031