@graph8/sdk 0.251.0 → 0.262.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 (350) hide show
  1. package/README.md +9 -2
  2. package/dist/cli.js +216 -0
  3. package/dist/index.d.mts +105 -7
  4. package/dist/index.d.ts +105 -7
  5. package/dist/index.js +44 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +44 -3
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/react.d.mts +103 -7
  10. package/dist/react.d.ts +103 -7
  11. package/dist/react.js +62 -11
  12. package/dist/react.js.map +1 -1
  13. package/dist/react.mjs +53 -12
  14. package/dist/react.mjs.map +1 -1
  15. package/dist/types/README.md +7 -0
  16. package/dist/types/agency.d.ts +20 -0
  17. package/dist/types/agentSetup.d.ts +57 -0
  18. package/dist/types/api.d.ts +127 -0
  19. package/dist/types/appClient.d.ts +99 -0
  20. package/dist/types/appPlatform.d.ts +269 -0
  21. package/dist/types/appTokens.d.ts +125 -0
  22. package/dist/types/apps.d.ts +130 -0
  23. package/dist/types/audiences.d.ts +88 -0
  24. package/dist/types/calendar.d.ts +55 -0
  25. package/dist/types/campaigns.d.ts +61 -0
  26. package/dist/types/chat.d.ts +35 -0
  27. package/dist/types/cli.d.ts +14 -0
  28. package/dist/types/companies.d.ts +123 -0
  29. package/dist/types/contacts.d.ts +200 -0
  30. package/dist/types/copilot.d.ts +31 -0
  31. package/dist/types/core.d.ts +1052 -0
  32. package/dist/types/deals.d.ts +215 -0
  33. package/dist/types/enrich.d.ts +51 -0
  34. package/dist/types/fields.d.ts +84 -0
  35. package/dist/types/forms.d.ts +16 -0
  36. package/dist/types/http.d.ts +141 -0
  37. package/dist/types/inbox.d.ts +123 -0
  38. package/dist/types/index.d.ts +63 -0
  39. package/dist/types/intent.d.ts +196 -0
  40. package/dist/types/lists.d.ts +44 -0
  41. package/dist/types/mailboxes.d.ts +240 -0
  42. package/dist/types/marketplace.d.ts +62 -0
  43. package/dist/types/meetings.d.ts +70 -0
  44. package/dist/types/newsletter.d.ts +212 -0
  45. package/dist/types/notes.d.ts +57 -0
  46. package/dist/types/objects.d.ts +281 -0
  47. package/dist/types/pipelines.d.ts +135 -0
  48. package/dist/types/quotes.d.ts +143 -0
  49. package/dist/types/react.d.ts +978 -0
  50. package/dist/types/search.d.ts +99 -0
  51. package/dist/types/sequences.d.ts +255 -0
  52. package/dist/types/signals.d.ts +28 -0
  53. package/dist/types/skills.d.ts +176 -0
  54. package/dist/types/snippet.d.ts +24 -0
  55. package/dist/types/studio.d.ts +161 -0
  56. package/dist/types/tasks.d.ts +101 -0
  57. package/dist/types/types.d.ts +45 -0
  58. package/dist/types/utils.d.ts +21 -0
  59. package/dist/types/version.d.ts +10 -0
  60. package/dist/types/visitors.d.ts +29 -0
  61. package/dist/types/voice.d.ts +304 -0
  62. package/dist/types/webhooks.d.ts +71 -0
  63. package/dist/types/workflows.d.ts +229 -0
  64. package/docs/agents.md +748 -0
  65. package/docs/api/README.md +165 -0
  66. package/docs/api/accounts.d.ts +396 -0
  67. package/docs/api/accounts.md +644 -0
  68. package/docs/api/adCampaigns.d.ts +707 -0
  69. package/docs/api/adCampaigns.md +1091 -0
  70. package/docs/api/adCreatives.d.ts +996 -0
  71. package/docs/api/adCreatives.md +1708 -0
  72. package/docs/api/agency.d.ts +556 -0
  73. package/docs/api/agency.md +845 -0
  74. package/docs/api/agent.d.ts +330 -0
  75. package/docs/api/agent.md +514 -0
  76. package/docs/api/agents.d.ts +1622 -0
  77. package/docs/api/agents.md +2860 -0
  78. package/docs/api/aiInbox.d.ts +1984 -0
  79. package/docs/api/aiInbox.md +3490 -0
  80. package/docs/api/analytics.d.ts +1273 -0
  81. package/docs/api/analytics.md +2095 -0
  82. package/docs/api/apiKeys.d.ts +252 -0
  83. package/docs/api/apiKeys.md +318 -0
  84. package/docs/api/appDeployments.d.ts +236 -0
  85. package/docs/api/appDeployments.md +471 -0
  86. package/docs/api/appDomains.d.ts +171 -0
  87. package/docs/api/appDomains.md +281 -0
  88. package/docs/api/appLogs.d.ts +120 -0
  89. package/docs/api/appLogs.md +159 -0
  90. package/docs/api/appObjects.d.ts +415 -0
  91. package/docs/api/appObjects.md +568 -0
  92. package/docs/api/appPages.d.ts +557 -0
  93. package/docs/api/appPages.md +796 -0
  94. package/docs/api/appPlatformTokens.d.ts +123 -0
  95. package/docs/api/appPlatformTokens.md +172 -0
  96. package/docs/api/appointments.d.ts +2361 -0
  97. package/docs/api/appointments.md +3917 -0
  98. package/docs/api/apps.d.ts +822 -0
  99. package/docs/api/apps.md +1342 -0
  100. package/docs/api/assertUpsert.d.ts +286 -0
  101. package/docs/api/assertUpsert.md +370 -0
  102. package/docs/api/audienceSyncs.d.ts +259 -0
  103. package/docs/api/audienceSyncs.md +395 -0
  104. package/docs/api/brandKit.d.ts +686 -0
  105. package/docs/api/brandKit.md +1133 -0
  106. package/docs/api/bugReports.d.ts +181 -0
  107. package/docs/api/bugReports.md +268 -0
  108. package/docs/api/by-path.md +3260 -0
  109. package/docs/api/calendarInvites.d.ts +117 -0
  110. package/docs/api/calendarInvites.md +148 -0
  111. package/docs/api/campaignWorkflows.d.ts +152 -0
  112. package/docs/api/campaignWorkflows.md +200 -0
  113. package/docs/api/campaigns.d.ts +721 -0
  114. package/docs/api/campaigns.md +1236 -0
  115. package/docs/api/channels.d.ts +171 -0
  116. package/docs/api/channels.md +235 -0
  117. package/docs/api/cliCampaigns.d.ts +205 -0
  118. package/docs/api/cliCampaigns.md +256 -0
  119. package/docs/api/cliPipelines.d.ts +324 -0
  120. package/docs/api/cliPipelines.md +562 -0
  121. package/docs/api/clickHouse.d.ts +115 -0
  122. package/docs/api/clickHouse.md +138 -0
  123. package/docs/api/companies.d.ts +1636 -0
  124. package/docs/api/companies.md +2211 -0
  125. package/docs/api/companyIntelligence.d.ts +299 -0
  126. package/docs/api/companyIntelligence.md +488 -0
  127. package/docs/api/contacts.d.ts +2173 -0
  128. package/docs/api/contacts.md +3143 -0
  129. package/docs/api/content.d.ts +968 -0
  130. package/docs/api/content.md +1667 -0
  131. package/docs/api/contentGridSkills.d.ts +177 -0
  132. package/docs/api/contentGridSkills.md +271 -0
  133. package/docs/api/copilot.d.ts +1017 -0
  134. package/docs/api/copilot.md +1765 -0
  135. package/docs/api/crmSyncs.d.ts +215 -0
  136. package/docs/api/crmSyncs.md +301 -0
  137. package/docs/api/customerSuccess.d.ts +491 -0
  138. package/docs/api/customerSuccess.md +776 -0
  139. package/docs/api/deals.d.ts +1697 -0
  140. package/docs/api/deals.md +2436 -0
  141. package/docs/api/deliverability.d.ts +418 -0
  142. package/docs/api/deliverability.md +677 -0
  143. package/docs/api/desk.d.ts +1765 -0
  144. package/docs/api/desk.md +3007 -0
  145. package/docs/api/dialer.d.ts +1185 -0
  146. package/docs/api/dialer.md +2166 -0
  147. package/docs/api/dialerAnalytics.d.ts +187 -0
  148. package/docs/api/dialerAnalytics.md +257 -0
  149. package/docs/api/documents.d.ts +895 -0
  150. package/docs/api/documents.md +1440 -0
  151. package/docs/api/duplicates.d.ts +195 -0
  152. package/docs/api/duplicates.md +315 -0
  153. package/docs/api/eSign.d.ts +38 -0
  154. package/docs/api/eSign.md +54 -0
  155. package/docs/api/eSignature.d.ts +242 -0
  156. package/docs/api/eSignature.md +341 -0
  157. package/docs/api/enrichment.d.ts +3207 -0
  158. package/docs/api/enrichment.md +5225 -0
  159. package/docs/api/events.d.ts +115 -0
  160. package/docs/api/events.md +105 -0
  161. package/docs/api/fields.d.ts +482 -0
  162. package/docs/api/fields.md +566 -0
  163. package/docs/api/forms.d.ts +1012 -0
  164. package/docs/api/forms.md +1542 -0
  165. package/docs/api/gtmCampaigns.d.ts +662 -0
  166. package/docs/api/gtmCampaigns.md +1044 -0
  167. package/docs/api/gtmContext.d.ts +1187 -0
  168. package/docs/api/gtmContext.md +2112 -0
  169. package/docs/api/gtmDeliverability.d.ts +60 -0
  170. package/docs/api/gtmDeliverability.md +63 -0
  171. package/docs/api/gtmKnowledgeBase.d.ts +76 -0
  172. package/docs/api/gtmKnowledgeBase.md +91 -0
  173. package/docs/api/gtmLaunchHelpers.d.ts +123 -0
  174. package/docs/api/gtmLaunchHelpers.md +148 -0
  175. package/docs/api/gtmLibrary.d.ts +448 -0
  176. package/docs/api/gtmLibrary.md +780 -0
  177. package/docs/api/health.d.ts +39 -0
  178. package/docs/api/health.md +58 -0
  179. package/docs/api/imageLibrary.d.ts +341 -0
  180. package/docs/api/imageLibrary.md +569 -0
  181. package/docs/api/imports.d.ts +157 -0
  182. package/docs/api/imports.md +174 -0
  183. package/docs/api/inbox.d.ts +709 -0
  184. package/docs/api/inbox.md +1067 -0
  185. package/docs/api/install.d.ts +213 -0
  186. package/docs/api/install.md +317 -0
  187. package/docs/api/installedApps.d.ts +131 -0
  188. package/docs/api/installedApps.md +241 -0
  189. package/docs/api/integrationStatus.d.ts +142 -0
  190. package/docs/api/integrationStatus.md +205 -0
  191. package/docs/api/integrations.d.ts +2327 -0
  192. package/docs/api/integrations.md +3791 -0
  193. package/docs/api/intent.d.ts +482 -0
  194. package/docs/api/intent.md +858 -0
  195. package/docs/api/knowledge.d.ts +501 -0
  196. package/docs/api/knowledge.md +843 -0
  197. package/docs/api/knowledgeBase.d.ts +84 -0
  198. package/docs/api/knowledgeBase.md +96 -0
  199. package/docs/api/landingPages.d.ts +1411 -0
  200. package/docs/api/landingPages.md +2488 -0
  201. package/docs/api/leads.d.ts +133 -0
  202. package/docs/api/leads.md +180 -0
  203. package/docs/api/library.d.ts +217 -0
  204. package/docs/api/library.md +338 -0
  205. package/docs/api/linkedIn.d.ts +227 -0
  206. package/docs/api/linkedIn.md +289 -0
  207. package/docs/api/linkedInOutreach.d.ts +727 -0
  208. package/docs/api/linkedInOutreach.md +990 -0
  209. package/docs/api/lists.d.ts +1106 -0
  210. package/docs/api/lists.md +1609 -0
  211. package/docs/api/logs.d.ts +71 -0
  212. package/docs/api/logs.md +70 -0
  213. package/docs/api/mailboxes.d.ts +1050 -0
  214. package/docs/api/mailboxes.md +1690 -0
  215. package/docs/api/marketingIntelligence.d.ts +256 -0
  216. package/docs/api/marketingIntelligence.md +454 -0
  217. package/docs/api/marketplace.d.ts +3173 -0
  218. package/docs/api/marketplace.md +5953 -0
  219. package/docs/api/mcp.d.ts +69 -0
  220. package/docs/api/mcp.md +69 -0
  221. package/docs/api/me.d.ts +54 -0
  222. package/docs/api/me.md +56 -0
  223. package/docs/api/meetings.d.ts +539 -0
  224. package/docs/api/meetings.md +747 -0
  225. package/docs/api/newsletter.d.ts +1613 -0
  226. package/docs/api/newsletter.md +2746 -0
  227. package/docs/api/notes.d.ts +517 -0
  228. package/docs/api/notes.md +888 -0
  229. package/docs/api/notifications.d.ts +94 -0
  230. package/docs/api/notifications.md +105 -0
  231. package/docs/api/objects.d.ts +621 -0
  232. package/docs/api/objects.md +1098 -0
  233. package/docs/api/openSearch.d.ts +234 -0
  234. package/docs/api/openSearch.md +297 -0
  235. package/docs/api/ops.d.ts +299 -0
  236. package/docs/api/ops.md +339 -0
  237. package/docs/api/orgGovernance.d.ts +393 -0
  238. package/docs/api/orgGovernance.md +623 -0
  239. package/docs/api/orgVideos.d.ts +184 -0
  240. package/docs/api/orgVideos.md +252 -0
  241. package/docs/api/organizationSettings.d.ts +626 -0
  242. package/docs/api/organizationSettings.md +911 -0
  243. package/docs/api/phoneNumbers.d.ts +484 -0
  244. package/docs/api/phoneNumbers.md +777 -0
  245. package/docs/api/profile.d.ts +329 -0
  246. package/docs/api/profile.md +540 -0
  247. package/docs/api/programmaticPages.d.ts +400 -0
  248. package/docs/api/programmaticPages.md +626 -0
  249. package/docs/api/providerDomains.d.ts +866 -0
  250. package/docs/api/providerDomains.md +1446 -0
  251. package/docs/api/providerUsage.d.ts +129 -0
  252. package/docs/api/providerUsage.md +186 -0
  253. package/docs/api/public.d.ts +69 -0
  254. package/docs/api/public.md +78 -0
  255. package/docs/api/publicCopilot.d.ts +67 -0
  256. package/docs/api/publicCopilot.md +80 -0
  257. package/docs/api/publicSignals.d.ts +66 -0
  258. package/docs/api/publicSignals.md +71 -0
  259. package/docs/api/publicVisitors.d.ts +97 -0
  260. package/docs/api/publicVisitors.md +118 -0
  261. package/docs/api/quotes.d.ts +1564 -0
  262. package/docs/api/quotes.md +2553 -0
  263. package/docs/api/radar.d.ts +808 -0
  264. package/docs/api/radar.md +1431 -0
  265. package/docs/api/radarReports.d.ts +208 -0
  266. package/docs/api/radarReports.md +306 -0
  267. package/docs/api/recordRoles.d.ts +143 -0
  268. package/docs/api/recordRoles.md +175 -0
  269. package/docs/api/repos.d.ts +146 -0
  270. package/docs/api/repos.md +211 -0
  271. package/docs/api/research.d.ts +295 -0
  272. package/docs/api/research.md +534 -0
  273. package/docs/api/revenue.d.ts +402 -0
  274. package/docs/api/revenue.md +608 -0
  275. package/docs/api/revenueAnalytics.d.ts +147 -0
  276. package/docs/api/revenueAnalytics.md +212 -0
  277. package/docs/api/revenueLifecycle.d.ts +207 -0
  278. package/docs/api/revenueLifecycle.md +274 -0
  279. package/docs/api/revenueRecords.d.ts +372 -0
  280. package/docs/api/revenueRecords.md +563 -0
  281. package/docs/api/roles.d.ts +431 -0
  282. package/docs/api/roles.md +812 -0
  283. package/docs/api/salesCoach.d.ts +877 -0
  284. package/docs/api/salesCoach.md +1540 -0
  285. package/docs/api/sandbox.d.ts +210 -0
  286. package/docs/api/sandbox.md +380 -0
  287. package/docs/api/scans.d.ts +104 -0
  288. package/docs/api/scans.md +136 -0
  289. package/docs/api/scheduleBuy.d.ts +293 -0
  290. package/docs/api/scheduleBuy.md +431 -0
  291. package/docs/api/scraping.d.ts +266 -0
  292. package/docs/api/scraping.md +383 -0
  293. package/docs/api/sdrAnalytics.d.ts +138 -0
  294. package/docs/api/sdrAnalytics.md +246 -0
  295. package/docs/api/search.d.ts +598 -0
  296. package/docs/api/search.md +866 -0
  297. package/docs/api/seo.d.ts +447 -0
  298. package/docs/api/seo.md +660 -0
  299. package/docs/api/sequenceLifecycle.d.ts +439 -0
  300. package/docs/api/sequenceLifecycle.md +513 -0
  301. package/docs/api/sequences.d.ts +1936 -0
  302. package/docs/api/sequences.md +3232 -0
  303. package/docs/api/settings.d.ts +448 -0
  304. package/docs/api/settings.md +731 -0
  305. package/docs/api/signals.d.ts +1441 -0
  306. package/docs/api/signals.md +2526 -0
  307. package/docs/api/signatures.d.ts +719 -0
  308. package/docs/api/signatures.md +1247 -0
  309. package/docs/api/skills.d.ts +230 -0
  310. package/docs/api/skills.md +466 -0
  311. package/docs/api/snippet.d.ts +85 -0
  312. package/docs/api/snippet.md +106 -0
  313. package/docs/api/socialPublishing.d.ts +824 -0
  314. package/docs/api/socialPublishing.md +1245 -0
  315. package/docs/api/studioDocuments.d.ts +244 -0
  316. package/docs/api/studioDocuments.md +348 -0
  317. package/docs/api/support.d.ts +90 -0
  318. package/docs/api/support.md +76 -0
  319. package/docs/api/suppressions.d.ts +241 -0
  320. package/docs/api/suppressions.md +343 -0
  321. package/docs/api/surveys.d.ts +847 -0
  322. package/docs/api/surveys.md +1223 -0
  323. package/docs/api/tasks.d.ts +813 -0
  324. package/docs/api/tasks.md +1344 -0
  325. package/docs/api/teamMembers.d.ts +668 -0
  326. package/docs/api/teamMembers.md +1040 -0
  327. package/docs/api/teams.d.ts +784 -0
  328. package/docs/api/teams.md +1395 -0
  329. package/docs/api/usage.d.ts +277 -0
  330. package/docs/api/usage.md +389 -0
  331. package/docs/api/visitors.d.ts +690 -0
  332. package/docs/api/visitors.md +1075 -0
  333. package/docs/api/voice.d.ts +4661 -0
  334. package/docs/api/voice.md +7905 -0
  335. package/docs/api/webAnalytics.d.ts +964 -0
  336. package/docs/api/webAnalytics.md +1452 -0
  337. package/docs/api/webChat.d.ts +1704 -0
  338. package/docs/api/webChat.md +2048 -0
  339. package/docs/api/webhooks.d.ts +251 -0
  340. package/docs/api/webhooks.md +386 -0
  341. package/docs/api/websiteEditor.d.ts +324 -0
  342. package/docs/api/websiteEditor.md +517 -0
  343. package/docs/api/work.d.ts +2298 -0
  344. package/docs/api/work.md +3096 -0
  345. package/docs/api/workbench.d.ts +2962 -0
  346. package/docs/api/workbench.md +4884 -0
  347. package/docs/api/workflows.d.ts +1218 -0
  348. package/docs/api/workflows.md +2302 -0
  349. package/docs/sdk-clients.md +4339 -0
  350. package/package.json +10 -3
@@ -0,0 +1,3143 @@
1
+ <!-- Generated by sdk/js/scripts/generate-agent-docs.ts from developer-contract/openapi.json. Regenerated on every build. -->
2
+
3
+ # `g8.api.contacts`: Contacts
4
+
5
+ 70 operations (36 read, 19 write, 7 destructive, 8 billable).
6
+
7
+ 7 of these also have a hand-written method (`g8.contacts`), marked **★** below. Prefer the hand-written method when one exists: it unwraps the `data` envelope and takes friendlier arguments. See [../sdk-clients.md](../sdk-clients.md).
8
+
9
+ Every example below assumes this setup (server-side, API key):
10
+
11
+ ```ts
12
+ import { g8 } from "@graph8/sdk";
13
+
14
+ g8.init({ apiKey: process.env.G8_API_KEY! });
15
+ ```
16
+
17
+ Example values are placeholders that match each field's type. Only required fields are shown. Every example is type-checked against the SDK in CI.
18
+
19
+ Exact TypeScript types for every operation on this page, and every schema they use: [contacts.d.ts](contacts.d.ts).
20
+
21
+ ## Operations
22
+
23
+ | Call | HTTP | Tier | Scope | Summary |
24
+ |---|---|---|---|---|
25
+ | [`assignContactOwner`](#op-assigncontactowner) | `POST /api/v1/contacts/assign-owner` | write | `contacts:write` | Assign Contact Owner |
26
+ | [`assignContactTags`](#op-assigncontacttags) | `POST /api/v1/contacts/tags/assign` | write | `contacts:write` | Assign Contact Tags |
27
+ | [`batchContactRelated`](#op-batchcontactrelated) | `POST /api/v1/contacts/related` | read | `contacts:read` | Batch Contact Related |
28
+ | [`bulkGetContacts`](#op-bulkgetcontacts) | `POST /api/v1/contacts/bulk-get` | read | `contacts:read` | Bulk Get Contacts |
29
+ | [`bulkUpdateContacts`](#op-bulkupdatecontacts) | `POST /api/v1/contacts/bulk-update` | write | `contacts:write` | Bulk Update Contacts |
30
+ | [`cancelRecordWorkflowExecution`](#op-cancelrecordworkflowexecution) | `POST /api/v1/contacts/workflow-executions/{execution_id}/cancel` | destructive | `contacts:delete` | Cancel Record Workflow Execution |
31
+ | [`createContactColumn`](#op-createcontactcolumn) ★ | `POST /api/v1/contacts/columns/create` | write | `contacts:write` | Create Contact Column |
32
+ | [`createContactTag`](#op-createcontacttag) | `POST /api/v1/contacts/tags` | write | `contacts:write` | Create Contact Tag |
33
+ | [`createContacts`](#op-createcontacts) ★ | `POST /api/v1/contacts` | write | `contacts:write` | Create Contacts |
34
+ | [`decideRecordWorkflowExecution`](#op-deciderecordworkflowexecution) | `POST /api/v1/contacts/workflow-executions/{execution_id}/approve` | write | `contacts:write` | Decide Record Workflow Execution |
35
+ | [`deleteContact`](#op-deletecontact) ★ | `DELETE /api/v1/contacts/{contact_id}` | destructive | `contacts:delete` | Delete Contact |
36
+ | [`deleteContactColumn`](#op-deletecontactcolumn) | `DELETE /api/v1/contacts/columns/{column_id}` | destructive | `contacts:delete` | Delete Contact Column |
37
+ | [`deleteContactDocument`](#op-deletecontactdocument) | `DELETE /api/v1/contacts/{contact_id}/documents/{document_id}` | destructive | `contacts:delete` | Delete Contact Document |
38
+ | [`deleteContactTag`](#op-deletecontacttag) | `DELETE /api/v1/contacts/tags/{tag_id}` | destructive | `contacts:delete` | Delete Contact Tag |
39
+ | [`fetchContacts`](#op-fetchcontacts) | `POST /api/v1/contacts/fetch` | read | `contacts:read` | Fetch Contacts |
40
+ | [`generateAllContactDocuments`](#op-generateallcontactdocuments) | `POST /api/v1/contacts/{contact_id}/documents/generate-all` | billable | `enrichment:run` | Generate All Contact Documents |
41
+ | [`generateContactDocument`](#op-generatecontactdocument) | `POST /api/v1/contacts/{contact_id}/documents/types/{doc_type}/generate` | billable | `enrichment:run` | Generate Contact Document |
42
+ | [`getActivityFeed`](#op-getactivityfeed) | `GET /api/v1/activity-feed` | read | `contacts:read` | Get Activity Feed |
43
+ | [`getContact`](#op-getcontact) ★ | `GET /api/v1/contacts/{contact_id}` | read | `contacts:read` | Get Contact |
44
+ | [`getContactAnalysis`](#op-getcontactanalysis) | `GET /api/v1/contacts/{contact_id}/analysis` | read | `contacts:read` | Get Contact Analysis |
45
+ | [`getContactDashboard`](#op-getcontactdashboard) | `GET /api/v1/contacts/{contact_id}/dashboard` | read | `contacts:read` | Get Contact Dashboard |
46
+ | [`getContactDashboardStats`](#op-getcontactdashboardstats) | `GET /api/v1/contacts/dashboard-stats` | read | `contacts:read` | Get Contact Dashboard Stats |
47
+ | [`getContactDetail`](#op-getcontactdetail) | `GET /api/v1/contacts/{contact_id}/detail` | read | `contacts:read` | Get Contact Detail |
48
+ | [`getContactDocument`](#op-getcontactdocument) | `GET /api/v1/contacts/{contact_id}/documents/types/{doc_type}` | read | `contacts:read` | Get Contact Document |
49
+ | [`getContactEngagementSummary`](#op-getcontactengagementsummary) | `GET /api/v1/contacts/{contact_id}/engagement-summary` | read | `contacts:read` | Get Contact Engagement Summary |
50
+ | [`getContactFormFields`](#op-getcontactformfields) | `GET /api/v1/contacts/form-fields` | read | `contacts:read` | Get Contact Form Fields |
51
+ | [`getContactGenerationStatus`](#op-getcontactgenerationstatus) | `GET /api/v1/contacts/{contact_id}/documents/generation-status` | read | `contacts:read` | Get Contact Generation Status |
52
+ | [`getContactLists`](#op-getcontactlists) | `GET /api/v1/contacts/{contact_id}/lists` | read | `contacts:read` | Get Contact Lists |
53
+ | [`getContactMeetings`](#op-getcontactmeetings) | `GET /api/v1/contacts/{contact_id}/meetings` | read | `contacts:read` | Get Contact Meetings |
54
+ | [`getContactNextBestStep`](#op-getcontactnextbeststep) | `GET /api/v1/contacts/{contact_id}/next-best-step` | billable | `enrichment:run` | Get Contact Next Best Step |
55
+ | [`getContactProfilePictures`](#op-getcontactprofilepictures) | `POST /api/v1/contacts/profile-pictures` | read | `contacts:read` | Get Contact Profile Pictures |
56
+ | [`getContactRowDetail`](#op-getcontactrowdetail) | `GET /api/v1/contacts/row-detail/{record_id}` | read | `contacts:read` | Get Contact Row Detail |
57
+ | [`getContactSequences`](#op-getcontactsequences) | `GET /api/v1/contacts/{contact_id}/sequences` | read | `contacts:read` | Get Contact Sequences |
58
+ | [`getContactSignals`](#op-getcontactsignals) | `GET /api/v1/contacts/{contact_id}/signals` | read | `contacts:read` | Get Contact Signals |
59
+ | [`getContactSitesVisited`](#op-getcontactsitesvisited) | `GET /api/v1/contacts/{contact_id}/sites-visited` | read | `contacts:read` | Get Contact Sites Visited |
60
+ | [`getContactTagIds`](#op-getcontacttagids) | `GET /api/v1/contacts/{contact_id}/tags` | read | `contacts:read` | Get Contact Tag Ids |
61
+ | [`getDuplicateSettings`](#op-getduplicatesettings) | `GET /api/v1/duplicates/settings` | read | `contacts:read` | Get Duplicate Settings |
62
+ | [`getRecordColumnValues`](#op-getrecordcolumnvalues) | `POST /api/v1/contacts/column-values` | read | `contacts:read` | Get Record Column Values |
63
+ | [`listBaseColumns`](#op-listbasecolumns) | `GET /api/v1/contacts/base-columns` | read | `contacts:read` | List Base Columns |
64
+ | [`listColumnNames`](#op-listcolumnnames) | `GET /api/v1/contacts/column-names` | read | `contacts:read` | List Column Names |
65
+ | [`listContactColumnDefinitions`](#op-listcontactcolumndefinitions) | `GET /api/v1/contacts/column-definitions` | read | `contacts:read` | List Contact Column Definitions |
66
+ | [`listContactColumns`](#op-listcontactcolumns) ★ | `GET /api/v1/contacts/columns` | read | `contacts:read` | List Contact Columns |
67
+ | [`listContactDocuments`](#op-listcontactdocuments) | `GET /api/v1/contacts/{contact_id}/documents` | read | `contacts:read` | List Contact Documents |
68
+ | [`listContactTags`](#op-listcontacttags) | `GET /api/v1/contacts/tags` | read | `contacts:read` | List Contact Tags |
69
+ | [`listContacts`](#op-listcontacts) ★ | `GET /api/v1/contacts` | read | `contacts:read` | List Contacts |
70
+ | [`listCustomColumnDefinitions`](#op-listcustomcolumndefinitions) | `GET /api/v1/contacts/custom-column-definitions` | read | `contacts:read` | List Custom Column Definitions |
71
+ | [`listDuplicateDetectionRuns`](#op-listduplicatedetectionruns) | `GET /api/v1/duplicates/detection/runs` | read | `contacts:read` | List Duplicate Detection Runs |
72
+ | [`listRecordWorkflowExecutions`](#op-listrecordworkflowexecutions) | `GET /api/v1/contacts/workflow-executions` | read | `contacts:read` | List Record Workflow Executions |
73
+ | [`listSearchableFields`](#op-listsearchablefields) | `GET /api/v1/contacts/searchable-fields` | read | `contacts:read` | List Searchable Fields |
74
+ | [`mergeContact`](#op-mergecontact) | `POST /api/v1/contacts/{contact_id}/merge` | destructive | `contacts:delete` | Merge Contact |
75
+ | [`mergeContactTags`](#op-mergecontacttags) | `POST /api/v1/contacts/tags/merge` | write | `contacts:write` | Merge Contact Tags |
76
+ | [`mergeFilteredContacts`](#op-mergefilteredcontacts) | `POST /api/v1/contacts/merge-filtered` | write | `contacts:write` | Merge Filtered Contacts |
77
+ | [`pauseRecordWorkflowExecution`](#op-pauserecordworkflowexecution) | `POST /api/v1/contacts/workflow-executions/{execution_id}/pause` | write | `contacts:write` | Pause Record Workflow Execution |
78
+ | [`previewContactMerge`](#op-previewcontactmerge) | `GET /api/v1/contacts/{contact_id}/merge/preview` | read | `contacts:read` | Preview Contact Merge |
79
+ | [`previewDetectionRule`](#op-previewdetectionrule) | `POST /api/v1/duplicates/settings/preview-detection-rule` | read | `contacts:read` | Preview Detection Rule |
80
+ | [`regenerateContactDocument`](#op-regeneratecontactdocument) | `POST /api/v1/contacts/{contact_id}/documents/types/{doc_type}/regenerate` | billable | `enrichment:run` | Regenerate Contact Document |
81
+ | [`resumeRecordWorkflowExecution`](#op-resumerecordworkflowexecution) | `POST /api/v1/contacts/workflow-executions/{execution_id}/resume` | write | `contacts:write` | Resume Record Workflow Execution |
82
+ | [`runDuplicateDetection`](#op-runduplicatedetection) | `POST /api/v1/duplicates/detection/run` | write | `contacts:write` | Run Duplicate Detection |
83
+ | [`runRecordWorkflow`](#op-runrecordworkflow) | `POST /api/v1/contacts/workflow-executions/run` | billable | `enrichment:run` | Run Record Workflow |
84
+ | [`saveSkillResultToContact`](#op-saveskillresulttocontact) | `POST /api/v1/contacts/{contact_id}/documents/from-skill` | write | `contacts:write` | Save Skill Result To Contact |
85
+ | [`triggerAutoMerge`](#op-triggerautomerge) | `POST /api/v1/duplicates/auto-merge` | destructive | `contacts:delete` | Trigger Auto Merge |
86
+ | [`unassignContactTags`](#op-unassigncontacttags) | `POST /api/v1/contacts/tags/unassign` | write | `contacts:write` | Unassign Contact Tags |
87
+ | [`unlockContactInfo`](#op-unlockcontactinfo) | `POST /api/v1/contacts/unlock-info` | billable | `enrichment:run` | Unlock Contact Info |
88
+ | [`updateContact`](#op-updatecontact) ★ | `PATCH /api/v1/contacts/{contact_id}` | write | `contacts:write` | Update Contact |
89
+ | [`updateContactDocument`](#op-updatecontactdocument) | `PUT /api/v1/contacts/{contact_id}/documents/{document_id}` | write | `contacts:write` | Update Contact Document |
90
+ | [`updateContactTag`](#op-updatecontacttag) | `PATCH /api/v1/contacts/tags/{tag_id}` | write | `contacts:write` | Update Contact Tag |
91
+ | [`updateDuplicateSettings`](#op-updateduplicatesettings) | `PUT /api/v1/duplicates/settings` | write | `contacts:write` | Update Duplicate Settings |
92
+ | [`verifyContactEmails`](#op-verifycontactemails) | `POST /api/v1/contacts/verify-email` | billable | `enrichment:run` | Verify Contact Emails |
93
+ | [`verifyContactEmailsAsync`](#op-verifycontactemailsasync) | `POST /api/v1/contacts/verify-email/async` | billable | `enrichment:run` | Verify Contact Emails Async |
94
+ | [`withdrawContactsFromSequences`](#op-withdrawcontactsfromsequences) | `POST /api/v1/contacts/withdraw-from-sequences` | write | `contacts:write` | Withdraw Contacts From Sequences |
95
+
96
+ ---
97
+
98
+ <a id="op-assigncontactowner"></a>
99
+
100
+ ### `g8.api.contacts.assignContactOwner(input)`
101
+
102
+ **Assign Contact Owner**
103
+
104
+ - HTTP: `POST /api/v1/contacts/assign-owner`
105
+ - operationId: `assign_contact_owner_contacts_assign_owner_post` (also callable as `g8.api.call("assign_contact_owner_contacts_assign_owner_post", input)`)
106
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
107
+ - API-key scope: `contacts:write`
108
+
109
+ Set the owner on EVERY contact matching a selection.
110
+
111
+ The selection is resolved server-side, so the number of contacts affected
112
+ is not bounded by anything in the request. A null `owner_id` UNASSIGNS
113
+ them all.
114
+
115
+ **Input**
116
+
117
+ | Field | Type | Required | Description |
118
+ |---|---|---|---|
119
+ | `body` | `AssignOwnerMatchingRequest` | yes | Request body; fields below. |
120
+
121
+ Body fields (`AssignOwnerMatchingRequest`):
122
+
123
+ | Field | Type | Required | Description |
124
+ |---|---|---|---|
125
+ | `body.filterModel` | `Record<string, unknown>` | no | Per-column filters. |
126
+ | `body.list_id` | `integer \| null` | no | Restrict the selection to this list. |
127
+ | `body.owner_id` | `string \| null` | no | Owner to assign. Null clears the owner on every match. |
128
+ | `body.segmentFilter` | `SegmentFilterGroup \| null` | no | Advanced AND/OR filter tree. |
129
+
130
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
131
+
132
+ Other envelope fields: `pagination` (PaginationMeta).
133
+
134
+ **Example**
135
+
136
+ ```ts
137
+ const result = await g8.api.contacts.assignContactOwner({ body: {} });
138
+ ```
139
+
140
+ ---
141
+
142
+ <a id="op-assigncontacttags"></a>
143
+
144
+ ### `g8.api.contacts.assignContactTags(input)`
145
+
146
+ **Assign Contact Tags**
147
+
148
+ - HTTP: `POST /api/v1/contacts/tags/assign`
149
+ - operationId: `assign_contact_tags_contacts_tags_assign_post` (also callable as `g8.api.call("assign_contact_tags_contacts_tags_assign_post", input)`)
150
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
151
+ - API-key scope: `contacts:write`
152
+
153
+ Add tags to contacts. Idempotent - re-assigning is not an error.
154
+
155
+ **Input**
156
+
157
+ | Field | Type | Required | Description |
158
+ |---|---|---|---|
159
+ | `body` | `ContactTagAssignRequest` | yes | Request body; fields below. |
160
+
161
+ Body fields (`ContactTagAssignRequest`):
162
+
163
+ | Field | Type | Required | Description |
164
+ |---|---|---|---|
165
+ | `body.tag_ids` | `Array<string>` | yes | min items 1 |
166
+ | `body.contact_ids` | `Array<integer>` | no | Contacts to tag. |
167
+
168
+ **Returns** `ApiResponse_ContactTagWriteResult_`: the envelope `{ data: ContactTagWriteResult, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
169
+
170
+ Other envelope fields: `pagination` (PaginationMeta).
171
+
172
+ **Example**
173
+
174
+ ```ts
175
+ const result = await g8.api.contacts.assignContactTags({ body: { tag_ids: ["id"] } });
176
+ ```
177
+
178
+ ---
179
+
180
+ <a id="op-batchcontactrelated"></a>
181
+
182
+ ### `g8.api.contacts.batchContactRelated(input)`
183
+
184
+ **Batch Contact Related**
185
+
186
+ - HTTP: `POST /api/v1/contacts/related`
187
+ - operationId: `batch_contact_related_contacts_related_post` (also callable as `g8.api.call("batch_contact_related_contacts_related_post", input)`)
188
+ - Tier: `read`: reads data; safe to call and to retry
189
+ - API-key scope: `contacts:read`
190
+
191
+ Sequences and/or lists for up to 100 contacts in ONE request. Writes nothing.
192
+
193
+ Use this instead of looping `GET /contacts/{contact_id}/sequences` or
194
+ `/lists` per contact: the loop spends one rate-limit slot per contact and
195
+ hits 429 on a large book; this spends one per 100.
196
+
197
+ Each contact gets exactly what its per-contact route returns, through the
198
+ same access check. A contact that does not exist or is outside the key's
199
+ scope for any requested include comes back `found: false` with no related
200
+ records, rather than failing the batch. POST only because the ids are a
201
+ body; it is tiered as a read.
202
+
203
+ **Input**
204
+
205
+ | Field | Type | Required | Description |
206
+ |---|---|---|---|
207
+ | `body` | `ContactRelatedBatchRequest` | yes | Request body; fields below. |
208
+
209
+ Body fields (`ContactRelatedBatchRequest`):
210
+
211
+ | Field | Type | Required | Description |
212
+ |---|---|---|---|
213
+ | `body.contact_ids` | `Array<integer>` | yes | Up to 100 contact ids, the same ids the per-contact routes take. Duplicates are read once; the response keeps first-seen order. min items 1, max items 100 |
214
+ | `body.include` | `Array<"sequences" \| "lists">` | no | Related records to return per contact. `sequences` matches `GET /contacts/{contact_id}/sequences`; `lists` matches `GET /contacts/{contact_id}/lists` (keyed on the contact primary key). min items 1 |
215
+
216
+ **Returns** `ApiResponse_ContactRelatedBatchResponse_`: the envelope `{ data: ContactRelatedBatchResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
217
+
218
+ Other envelope fields: `pagination` (PaginationMeta).
219
+
220
+ `ContactRelatedBatchResponse` fields:
221
+
222
+ | Field | Type | Required | Description |
223
+ |---|---|---|---|
224
+ | `items` | `Array<ContactRelatedItem>` | no | |
225
+
226
+ **Example**
227
+
228
+ ```ts
229
+ const result = await g8.api.contacts.batchContactRelated({ body: { contact_ids: [123] } });
230
+ ```
231
+
232
+ ---
233
+
234
+ <a id="op-bulkgetcontacts"></a>
235
+
236
+ ### `g8.api.contacts.bulkGetContacts(input)`
237
+
238
+ **Bulk Get Contacts**
239
+
240
+ - HTTP: `POST /api/v1/contacts/bulk-get`
241
+ - operationId: `bulk_get_contacts_contacts_bulk_get_post` (also callable as `g8.api.call("bulk_get_contacts_contacts_bulk_get_post", input)`)
242
+ - Tier: `read`: reads data; safe to call and to retry
243
+ - API-key scope: `contacts:read`
244
+
245
+ Full records for up to 100 contacts in ONE request. Writes nothing.
246
+
247
+ Use this instead of looping `GET /contacts/{contact_id}`: `GET /contacts`
248
+ returns 17 fields per contact, and the loop spends one rate-limit slot per
249
+ contact to get the other fields. Each item is exactly what the per-contact
250
+ route returns, through the same access check. A contact that does not exist
251
+ or is outside the key's scope comes back `found: false`, rather than failing
252
+ the batch. POST only because the ids are a body; it is tiered as a read.
253
+
254
+ **Input**
255
+
256
+ | Field | Type | Required | Description |
257
+ |---|---|---|---|
258
+ | `body` | `ContactBulkGetRequest` | yes | Request body; fields below. |
259
+
260
+ Body fields (`ContactBulkGetRequest`):
261
+
262
+ | Field | Type | Required | Description |
263
+ |---|---|---|---|
264
+ | `body.contact_ids` | `Array<integer>` | yes | Up to 100 contact ids, the ids `GET /contacts` returns. Duplicates are read once; the response keeps first-seen order. min items 1, max items 100 |
265
+ | `body.include_custom_fields` | `boolean` | no | When true, each found contact includes a `custom_fields` object keyed by column slug, as `GET /contacts/{contact_id}?include_custom_fields=true` does. default `false` |
266
+
267
+ **Returns** `ApiResponse_ContactBulkGetResponse_`: the envelope `{ data: ContactBulkGetResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
268
+
269
+ Other envelope fields: `pagination` (PaginationMeta).
270
+
271
+ `ContactBulkGetResponse` fields:
272
+
273
+ | Field | Type | Required | Description |
274
+ |---|---|---|---|
275
+ | `items` | `Array<ContactBulkGetItem>` | no | |
276
+
277
+ **Example**
278
+
279
+ ```ts
280
+ const result = await g8.api.contacts.bulkGetContacts({ body: { contact_ids: [123] } });
281
+ ```
282
+
283
+ ---
284
+
285
+ <a id="op-bulkupdatecontacts"></a>
286
+
287
+ ### `g8.api.contacts.bulkUpdateContacts(input)`
288
+
289
+ **Bulk Update Contacts**
290
+
291
+ - HTTP: `POST /api/v1/contacts/bulk-update`
292
+ - operationId: `bulk_update_contacts_contacts_bulk_update_post` (also callable as `g8.api.call("bulk_update_contacts_contacts_bulk_update_post", input)`)
293
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
294
+ - API-key scope: `contacts:write`
295
+
296
+ Apply a DIFFERENT change to each of many contacts.
297
+
298
+ The whole target set is authorised before the first write, so a batch
299
+ containing one contact the key cannot write is refused outright rather
300
+ than half-applied.
301
+
302
+ After that preflight, individual failures are REPORTED, not fatal: read
303
+ `updated`, `failed` and the per-contact `errors` rather than the HTTP
304
+ status.
305
+
306
+ **Input**
307
+
308
+ | Field | Type | Required | Description |
309
+ |---|---|---|---|
310
+ | `body` | `Array<Record<string, unknown>>` | yes | Request body; fields below. |
311
+
312
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
313
+
314
+ Other envelope fields: `pagination` (PaginationMeta).
315
+
316
+ **Example**
317
+
318
+ ```ts
319
+ const result = await g8.api.contacts.bulkUpdateContacts({ body: [{}] });
320
+ ```
321
+
322
+ ---
323
+
324
+ <a id="op-cancelrecordworkflowexecution"></a>
325
+
326
+ ### `g8.api.contacts.cancelRecordWorkflowExecution(input)`
327
+
328
+ **Cancel Record Workflow Execution**
329
+
330
+ - HTTP: `POST /api/v1/contacts/workflow-executions/{execution_id}/cancel`
331
+ - operationId: `cancel_record_workflow_execution_contacts_workflow_executions__execution_id__cancel_post` (also callable as `g8.api.call("cancel_record_workflow_execution_contacts_workflow_executions__execution_id__cancel_post", input)`)
332
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
333
+ - API-key scope: `contacts:delete`
334
+
335
+ Cancel a row workflow. Steps already run are not undone.
336
+
337
+ **Input**
338
+
339
+ | Field | Type | Required | Description |
340
+ |---|---|---|---|
341
+ | `path.execution_id` | `string` | yes | Workflow execution id. |
342
+
343
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
344
+
345
+ Other envelope fields: `pagination` (PaginationMeta).
346
+
347
+ **Example**
348
+
349
+ ```ts
350
+ // destructive: deletes or archives data; confirm with a human before calling.
351
+ const result = await g8.api.contacts.cancelRecordWorkflowExecution({ path: { execution_id: "id" } });
352
+ ```
353
+
354
+ ---
355
+
356
+ <a id="op-createcontactcolumn"></a>
357
+
358
+ ### `g8.api.contacts.createContactColumn(input)`
359
+
360
+ **Create Contact Column**
361
+
362
+ - HTTP: `POST /api/v1/contacts/columns/create`
363
+ - operationId: `create_contact_column_contacts_columns_create_post` (also callable as `g8.api.call("create_contact_column_contacts_columns_create_post", input)`)
364
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
365
+ - API-key scope: `contacts:write`
366
+ - ★ Hand-written: [`g8.contacts.createColumn()`](../sdk-clients.md#g8-contacts-createcolumn)
367
+
368
+ Create a custom contact column. Global if list_id is null, list-scoped otherwise.
369
+
370
+ Optionally pass an `enrichment` block to provision a companion waterfall
371
+ pipeline in the same request — STRONGLY RECOMMENDED so the UI 'Enrich'
372
+ button works out-of-the-box. Without it the column is created but isn't
373
+ enrichable until a pipeline is provisioned via
374
+ POST /enrichment/waterfall/configs.
375
+
376
+ **Input**
377
+
378
+ | Field | Type | Required | Description |
379
+ |---|---|---|---|
380
+ | `body` | `CreateContactColumnRequest` | yes | Request body; fields below. |
381
+
382
+ Body fields (`CreateContactColumnRequest`):
383
+
384
+ | Field | Type | Required | Description |
385
+ |---|---|---|---|
386
+ | `body.created_by` | `string (email)` | yes | Email of the user creating the column (for audit). |
387
+ | `body.title` | `string` | yes | Column title shown in the UI (e.g. 'Lead Score') |
388
+ | `body.data_type` | `ColumnType` | no | Column data type. Currently only 'text' is supported. default `"text"` |
389
+ | `body.enrichment` | `CreateFieldEnrichmentInput \| null` | no | STRONGLY RECOMMENDED. Optional waterfall enrichment block. When supplied, a companion `enrichment_configs` row is created alongside the column so the UI 'Enrich' button works immediately. Without it the column exists but isn't enrichable until a pipeline is configured via POST /enrichment/waterfall/configs. |
390
+ | `body.list_id` | `integer \| null` | no | If set, the column is list-scoped (only visible on that list). Required when `enrichment` is supplied — waterfall pipelines are list-scoped. |
391
+
392
+ **Returns** `ApiResponse_CreateContactColumnResponse_`: the envelope `{ data: CreateContactColumnResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
393
+
394
+ Other envelope fields: `pagination` (PaginationMeta).
395
+
396
+ `CreateContactColumnResponse` fields:
397
+
398
+ | Field | Type | Required | Description |
399
+ |---|---|---|---|
400
+ | `title` | `string` | yes | |
401
+ | `data_type` | `ColumnType` | no | default `"text"` |
402
+ | `enrichment` | `CreateFieldEnrichmentResponse \| null` | no | Populated when the request included an `enrichment` block. Use `enrichment.column_id` for subsequent POST /enrichment/waterfall/enrich calls. |
403
+ | `id` | `integer \| null` | no | |
404
+ | `is_global` | `boolean` | no | Computed: True when object_id is null/empty (global column). default `false` |
405
+ | `name` | `string \| null` | no | |
406
+ | `object_id` | `string \| null` | no | |
407
+
408
+ **Example**
409
+
410
+ ```ts
411
+ const result = await g8.api.contacts.createContactColumn({ body: { created_by: "jane@acme.com", title: "Example" } });
412
+ ```
413
+
414
+ ---
415
+
416
+ <a id="op-createcontacttag"></a>
417
+
418
+ ### `g8.api.contacts.createContactTag(input)`
419
+
420
+ **Create Contact Tag**
421
+
422
+ - HTTP: `POST /api/v1/contacts/tags`
423
+ - operationId: `create_contact_tag_contacts_tags_post` (also callable as `g8.api.call("create_contact_tag_contacts_tags_post", input)`)
424
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
425
+ - API-key scope: `contacts:write`
426
+
427
+ Create a tag definition.
428
+
429
+ **Input**
430
+
431
+ | Field | Type | Required | Description |
432
+ |---|---|---|---|
433
+ | `body` | `ContactTagCreateRequest` | yes | Request body; fields below. |
434
+
435
+ Body fields (`ContactTagCreateRequest`):
436
+
437
+ | Field | Type | Required | Description |
438
+ |---|---|---|---|
439
+ | `body.name` | `string` | yes | min length 1, max length 50 |
440
+ | `body.color` | `string \| null` | no | Six-digit hex colour, e.g. `#4F46E5`. pattern `^#[0-9A-Fa-f]{6}$` |
441
+ | `body.description` | `string \| null` | no | max length 200 |
442
+
443
+ **Returns** `ApiResponse_ContactTag_`: the envelope `{ data: ContactTag, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
444
+
445
+ Other envelope fields: `pagination` (PaginationMeta).
446
+
447
+ `ContactTag` fields:
448
+
449
+ | Field | Type | Required | Description |
450
+ |---|---|---|---|
451
+ | `archived` | `boolean \| null` | no | |
452
+ | `color` | `string \| null` | no | |
453
+ | `contact_count` | `integer \| null` | no | Contacts currently carrying the tag. |
454
+ | `description` | `string \| null` | no | |
455
+ | `id` | `string \| null` | no | |
456
+ | `name` | `string \| null` | no | |
457
+
458
+ **Example**
459
+
460
+ ```ts
461
+ const result = await g8.api.contacts.createContactTag({ body: { name: "Example" } });
462
+ ```
463
+
464
+ ---
465
+
466
+ <a id="op-createcontacts"></a>
467
+
468
+ ### `g8.api.contacts.createContacts(input)`
469
+
470
+ **Create Contacts**
471
+
472
+ - HTTP: `POST /api/v1/contacts`
473
+ - operationId: `create_contacts_contacts_post` (also callable as `g8.api.call("create_contacts_contacts_post", input)`)
474
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
475
+ - API-key scope: `contacts:write`
476
+ - ★ Hand-written: [`g8.contacts.create()`](../sdk-clients.md#g8-contacts-create)
477
+
478
+ Create a contact, optionally adding it to a list.
479
+
480
+ The contact is created independent of any list. When ``list_id`` is
481
+ provided, the contact is added to that list AFTER it is created; when
482
+ omitted, the contact is created standalone. A company is resolved and
483
+ attached from ``company_domain`` when supplied.
484
+
485
+ Duplicate handling: when the submitted ``work_email`` / ``linkedin_url``
486
+ (or the deterministic identity hash) already matches an existing contact,
487
+ the handler does NOT overwrite it — it writes nothing and skips the
488
+ ``list_id`` linkage. This endpoint mirrors the in-app create and responds
489
+ ``409 Conflict`` with the matched ``contact_id`` and a ``field_diff`` under
490
+ ``detail`` (rather than a misleading ``201`` success). The 409 is NOT
491
+ cached under the ``Idempotency-Key``, so a later create of the same
492
+ identity is re-evaluated fresh. The 409 ``detail`` also carries ``hint``,
493
+ ``upsert`` and ``update``, which name the idempotent create-or-update route
494
+ ``PUT /contacts/assert`` and the ``PATCH /contacts/{id}`` for the matched
495
+ contact. To create-or-update in one call, use ``PUT /contacts/assert``.
496
+
497
+ Supports optional Stripe-style idempotency via the ``Idempotency-Key``
498
+ header — a safe retry of the same key replays the first SUCCESSFUL response
499
+ (flagged ``Idempotent-Replay: true``) rather than creating duplicate
500
+ contacts.
501
+
502
+ **Input**
503
+
504
+ | Field | Type | Required | Description |
505
+ |---|---|---|---|
506
+ | `body` | `ContactCreateRequest` | yes | Request body; fields below. |
507
+ | `headers.Idempotency-Key` | `string \| null` | no | Optional. Retrying a create with the same key returns the first response instead of creating a duplicate (cached 24h). Omit for the existing non-idempotent behavior. |
508
+
509
+ Body fields (`ContactCreateRequest`):
510
+
511
+ | Field | Type | Required | Description |
512
+ |---|---|---|---|
513
+ | `body.city` | `string \| null` | no | City |
514
+ | `body.company_domain` | `string \| null` | no | Company domain for matching |
515
+ | `body.company_id` | `integer \| null` | no | Existing company id (mashup_companies.id) to attach |
516
+ | `body.country` | `string \| null` | no | Country |
517
+ | `body.create_missing_fields` | `boolean` | no | When true, custom_fields keys that match no existing column are created as NEW custom columns (list-scoped when list_id is set) and then written. default `false` |
518
+ | `body.custom_fields` | `Record<string, string \| null> \| null` | no | Custom column values keyed by the column's display title (e.g. 'Followup 1'), its slug (e.g. 'udo_followup_1_ab12cd34'), or a case/space variant of the title. Keys matching no existing column are reported in the response's `custom_fields.ignored` unless `create_missing_fields` is true. |
519
+ | `body.direct_phone` | `string \| null` | no | Direct phone number |
520
+ | `body.first_name` | `string \| null` | no | Contact first name |
521
+ | `body.job_department` | `string \| null` | no | Department |
522
+ | `body.job_title` | `string \| null` | no | Job title |
523
+ | `body.last_name` | `string \| null` | no | Contact last name |
524
+ | `body.linkedin_url` | `string \| null` | no | LinkedIn profile URL |
525
+ | `body.list_id` | `integer \| null` | no | Optional target list ID. When provided, the contact is added to this list after it is created; omit to create the contact without a list. |
526
+ | `body.mobile_phone` | `string \| null` | no | Mobile phone number |
527
+ | `body.personal_emails` | `string \| null` | no | Personal email addresses |
528
+ | `body.seniority_level` | `string \| null` | no | Seniority level |
529
+ | `body.state` | `string \| null` | no | State/Province |
530
+ | `body.work_email` | `string \| null` | no | Work email address |
531
+
532
+ **Returns** `ApiResponse_ContactCreateResponse_`: the envelope `{ data: ContactCreateResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
533
+
534
+ Other envelope fields: `pagination` (PaginationMeta).
535
+
536
+ `ContactCreateResponse` fields:
537
+
538
+ | Field | Type | Required | Description |
539
+ |---|---|---|---|
540
+ | `count` | `integer` | yes | |
541
+ | `status` | `string` | yes | |
542
+ | `company_attached` | `boolean` | no | default `false` |
543
+ | `contact_id` | `integer \| null` | no | |
544
+ | `custom_fields` | `CustomFieldWriteReport` | no | |
545
+ | `merged` | `boolean` | no | default `false` |
546
+ | `validation_errors` | `Array<string>` | no | |
547
+
548
+ **Example**
549
+
550
+ ```ts
551
+ const result = await g8.api.contacts.createContacts({ body: {} });
552
+ ```
553
+
554
+ ---
555
+
556
+ <a id="op-deciderecordworkflowexecution"></a>
557
+
558
+ ### `g8.api.contacts.decideRecordWorkflowExecution(input)`
559
+
560
+ **Decide Record Workflow Execution**
561
+
562
+ - HTTP: `POST /api/v1/contacts/workflow-executions/{execution_id}/approve`
563
+ - operationId: `decide_record_workflow_execution_contacts_workflow_executions__execution_id__approve_post` (also callable as `g8.api.call("decide_record_workflow_execution_contacts_workflow_executions__execution_id__approve_post", input)`)
564
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
565
+ - API-key scope: `contacts:write`
566
+
567
+ Approve or reject a row workflow paused at an approval step.
568
+
569
+ **Input**
570
+
571
+ | Field | Type | Required | Description |
572
+ |---|---|---|---|
573
+ | `path.execution_id` | `string` | yes | Workflow execution id. |
574
+ | `body` | `ApproveExecutionRequest` | yes | Request body; fields below. |
575
+
576
+ Body fields (`ApproveExecutionRequest`):
577
+
578
+ | Field | Type | Required | Description |
579
+ |---|---|---|---|
580
+ | `body.decision` | `"approve" \| "reject"` | yes | Approve or reject the paused step. |
581
+ | `body.reason` | `string \| null` | no | Recorded with a rejection. |
582
+
583
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
584
+
585
+ Other envelope fields: `pagination` (PaginationMeta).
586
+
587
+ **Example**
588
+
589
+ ```ts
590
+ const result = await g8.api.contacts.decideRecordWorkflowExecution({ path: { execution_id: "id" }, body: { decision: "approve" } });
591
+ ```
592
+
593
+ ---
594
+
595
+ <a id="op-deletecontact"></a>
596
+
597
+ ### `g8.api.contacts.deleteContact(input)`
598
+
599
+ **Delete Contact**
600
+
601
+ - HTTP: `DELETE /api/v1/contacts/{contact_id}`
602
+ - operationId: `delete_contact_contacts__contact_id__delete` (also callable as `g8.api.call("delete_contact_contacts__contact_id__delete", input)`)
603
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
604
+ - API-key scope: `contacts:delete`
605
+ - ★ Hand-written: [`g8.contacts.delete()`](../sdk-clients.md#g8-contacts-delete)
606
+
607
+ Soft-delete a contact.
608
+
609
+ **Input**
610
+
611
+ | Field | Type | Required | Description |
612
+ |---|---|---|---|
613
+ | `path.contact_id` | `integer` | yes | Contact ID |
614
+
615
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
616
+
617
+ Other envelope fields: `pagination` (PaginationMeta).
618
+
619
+ **Example**
620
+
621
+ ```ts
622
+ // destructive: deletes or archives data; confirm with a human before calling.
623
+ const result = await g8.api.contacts.deleteContact({ path: { contact_id: 123 } });
624
+ ```
625
+
626
+ ---
627
+
628
+ <a id="op-deletecontactcolumn"></a>
629
+
630
+ ### `g8.api.contacts.deleteContactColumn(input)`
631
+
632
+ **Delete Contact Column**
633
+
634
+ - HTTP: `DELETE /api/v1/contacts/columns/{column_id}`
635
+ - operationId: `delete_contact_column_contacts_columns__column_id__delete` (also callable as `g8.api.call("delete_contact_column_contacts_columns__column_id__delete", input)`)
636
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
637
+ - API-key scope: `contacts:delete`
638
+
639
+ Soft-delete a custom contact column (sets deleted_at; data is not physically removed).
640
+
641
+ **Input**
642
+
643
+ | Field | Type | Required | Description |
644
+ |---|---|---|---|
645
+ | `path.column_id` | `integer` | yes | ID of the column to delete |
646
+
647
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
648
+
649
+ Other envelope fields: `pagination` (PaginationMeta).
650
+
651
+ **Example**
652
+
653
+ ```ts
654
+ // destructive: deletes or archives data; confirm with a human before calling.
655
+ const result = await g8.api.contacts.deleteContactColumn({ path: { column_id: 123 } });
656
+ ```
657
+
658
+ ---
659
+
660
+ <a id="op-deletecontactdocument"></a>
661
+
662
+ ### `g8.api.contacts.deleteContactDocument(input)`
663
+
664
+ **Delete Contact Document**
665
+
666
+ - HTTP: `DELETE /api/v1/contacts/{contact_id}/documents/{document_id}`
667
+ - operationId: `delete_contact_document_contacts__contact_id__documents__document_id__delete` (also callable as `g8.api.call("delete_contact_document_contacts__contact_id__documents__document_id__delete", input)`)
668
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
669
+ - API-key scope: `contacts:delete`
670
+
671
+ Delete one generated document PERMANENTLY.
672
+
673
+ **Input**
674
+
675
+ | Field | Type | Required | Description |
676
+ |---|---|---|---|
677
+ | `path.contact_id` | `integer` | yes | Contact id. |
678
+ | `path.document_id` | `string` | yes | Document id. |
679
+
680
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
681
+
682
+ Other envelope fields: `pagination` (PaginationMeta).
683
+
684
+ **Example**
685
+
686
+ ```ts
687
+ // destructive: deletes or archives data; confirm with a human before calling.
688
+ const result = await g8.api.contacts.deleteContactDocument({ path: { contact_id: 123, document_id: "id" } });
689
+ ```
690
+
691
+ ---
692
+
693
+ <a id="op-deletecontacttag"></a>
694
+
695
+ ### `g8.api.contacts.deleteContactTag(input)`
696
+
697
+ **Delete Contact Tag**
698
+
699
+ - HTTP: `DELETE /api/v1/contacts/tags/{tag_id}`
700
+ - operationId: `delete_contact_tag_contacts_tags__tag_id__delete` (also callable as `g8.api.call("delete_contact_tag_contacts_tags__tag_id__delete", input)`)
701
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
702
+ - API-key scope: `contacts:delete`
703
+
704
+ Delete a tag, optionally reassigning its contacts first.
705
+
706
+ **Input**
707
+
708
+ | Field | Type | Required | Description |
709
+ |---|---|---|---|
710
+ | `path.tag_id` | `string` | yes | Tag id. |
711
+ | `query.reassign_to` | `string \| null` | no | Move every assignment to this tag before deleting. Omit to drop the assignments with the tag. |
712
+
713
+ **Returns** `ApiResponse_ContactTagWriteResult_`: the envelope `{ data: ContactTagWriteResult, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
714
+
715
+ Other envelope fields: `pagination` (PaginationMeta).
716
+
717
+ **Example**
718
+
719
+ ```ts
720
+ // destructive: deletes or archives data; confirm with a human before calling.
721
+ const result = await g8.api.contacts.deleteContactTag({ path: { tag_id: "id" } });
722
+ ```
723
+
724
+ ---
725
+
726
+ <a id="op-fetchcontacts"></a>
727
+
728
+ ### `g8.api.contacts.fetchContacts(input)`
729
+
730
+ **Fetch Contacts**
731
+
732
+ - HTTP: `POST /api/v1/contacts/fetch`
733
+ - operationId: `fetch_contacts_contacts_fetch_post` (also callable as `g8.api.call("fetch_contacts_contacts_fetch_post", input)`)
734
+ - Tier: `read`: reads data; safe to call and to retry
735
+ - API-key scope: `contacts:read`
736
+
737
+ Page through contacts, projecting only the columns you name.
738
+
739
+ A POST because the filter is a body, not because it writes: this reads and
740
+ mutates nothing, and is tiered as a read so a read-only key can call it.
741
+
742
+ Prefer this over `GET /contacts` when you want a narrow column set -
743
+ naming the columns lets the planner drop joins the full row forces.
744
+
745
+ **Input**
746
+
747
+ | Field | Type | Required | Description |
748
+ |---|---|---|---|
749
+ | `body` | `FetchContactsRequest` | yes | Request body; fields below. |
750
+
751
+ Body fields (`FetchContactsRequest`):
752
+
753
+ | Field | Type | Required | Description |
754
+ |---|---|---|---|
755
+ | `body.filter` | `string \| null` | no | Serialized per-column filter JSON. Omit for no filter. |
756
+ | `body.limit` | `integer` | no | Records per page. default `50`, min 1, max 1000 |
757
+ | `body.mapping_columns` | `Array<string> \| null` | no | Columns to return. Omit for every column. |
758
+ | `body.page` | `integer` | no | Page number (1-indexed). default `1`, min 1 |
759
+
760
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
761
+
762
+ Other envelope fields: `pagination` (PaginationMeta).
763
+
764
+ `CrmCollectionPayload` fields:
765
+
766
+ | Field | Type | Required | Description |
767
+ |---|---|---|---|
768
+ | `items` | `Array<unknown>` | no | |
769
+
770
+ **Example**
771
+
772
+ ```ts
773
+ const result = await g8.api.contacts.fetchContacts({ body: {} });
774
+ ```
775
+
776
+ ---
777
+
778
+ <a id="op-generateallcontactdocuments"></a>
779
+
780
+ ### `g8.api.contacts.generateAllContactDocuments(input)`
781
+
782
+ **Generate All Contact Documents**
783
+
784
+ - HTTP: `POST /api/v1/contacts/{contact_id}/documents/generate-all`
785
+ - operationId: `generate_all_contact_documents_contacts__contact_id__documents_generate_all_post` (also callable as `g8.api.call("generate_all_contact_documents_contacts__contact_id__documents_generate_all_post", input)`)
786
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
787
+ - API-key scope: `enrichment:run`
788
+
789
+ Generate the full document set for this contact. SPENDS CREDITS.
790
+
791
+ Enqueues the work and returns immediately; poll
792
+ `/contacts/{contact_id}/documents/generation-status` for progress. Each
793
+ document is a model call, so calling this repeatedly on the same contact
794
+ spends repeatedly.
795
+
796
+ **Input**
797
+
798
+ | Field | Type | Required | Description |
799
+ |---|---|---|---|
800
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
801
+
802
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
803
+
804
+ Other envelope fields: `pagination` (PaginationMeta).
805
+
806
+ **Example**
807
+
808
+ ```ts
809
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
810
+ const result = await g8.api.contacts.generateAllContactDocuments({ path: { contact_id: 123 } });
811
+ ```
812
+
813
+ ---
814
+
815
+ <a id="op-generatecontactdocument"></a>
816
+
817
+ ### `g8.api.contacts.generateContactDocument(input)`
818
+
819
+ **Generate Contact Document**
820
+
821
+ - HTTP: `POST /api/v1/contacts/{contact_id}/documents/types/{doc_type}/generate`
822
+ - operationId: `generate_contact_document_contacts__contact_id__documents_types__doc_type__generate_post` (also callable as `g8.api.call("generate_contact_document_contacts__contact_id__documents_types__doc_type__generate_post", input)`)
823
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
824
+ - API-key scope: `enrichment:run`
825
+
826
+ Generate one document of this type. SPENDS CREDITS. Unknown types are a 400.
827
+
828
+ **Input**
829
+
830
+ | Field | Type | Required | Description |
831
+ |---|---|---|---|
832
+ | `path.contact_id` | `integer` | yes | Contact id. |
833
+ | `path.doc_type` | `string` | yes | Document type. |
834
+
835
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
836
+
837
+ Other envelope fields: `pagination` (PaginationMeta).
838
+
839
+ **Example**
840
+
841
+ ```ts
842
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
843
+ const result = await g8.api.contacts.generateContactDocument({ path: { contact_id: 123, doc_type: "example" } });
844
+ ```
845
+
846
+ ---
847
+
848
+ <a id="op-getactivityfeed"></a>
849
+
850
+ ### `g8.api.contacts.getActivityFeed(input)`
851
+
852
+ **Get Activity Feed**
853
+
854
+ - HTTP: `GET /api/v1/activity-feed`
855
+ - operationId: `get_activity_feed_activity_feed_get` (also callable as `g8.api.call("get_activity_feed_activity_feed_get", input)`)
856
+ - Tier: `read`: reads data; safe to call and to retry
857
+ - API-key scope: `contacts:read`
858
+
859
+ One timeline over everything that happened to a record.
860
+
861
+ Replaces four separate per-type reads. `entity_type` decides which record
862
+ scope authorises the call, and all four are resolved from the CALLING
863
+ KEY'S OWN credential scopes - so a key without `deals:read` resolves the
864
+ deal scope to nothing and cannot read a deal's feed through this path,
865
+ even though the key gate on the route is `contacts:read`.
866
+
867
+ **Input**
868
+
869
+ | Field | Type | Required | Description |
870
+ |---|---|---|---|
871
+ | `query.entity_type` | `string` | yes | contact \| company \| deal \| team_member |
872
+ | `query.entity_id` | `string` | yes | Id of that record. |
873
+ | `query.types` | `string \| null` | no | Comma-separated subset of task,note,email,call,meeting,sms,chat,stage_change,quote,record_change,deal. Omit for all. |
874
+ | `query.source` | `string` | no | manual \| crm \| system \| dialer \| automation \| api \| all default `"all"` |
875
+ | `query.since` | `string \| null` | no | ISO 8601 cursor; returns events at or after it. |
876
+ | `query.limit` | `integer` | no | default `50` |
877
+
878
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
879
+
880
+ Other envelope fields: `pagination` (PaginationMeta).
881
+
882
+ `CrmCollectionPayload` fields:
883
+
884
+ | Field | Type | Required | Description |
885
+ |---|---|---|---|
886
+ | `items` | `Array<unknown>` | no | |
887
+
888
+ **Example**
889
+
890
+ ```ts
891
+ const result = await g8.api.contacts.getActivityFeed({ query: { entity_type: "example", entity_id: "id" } });
892
+ ```
893
+
894
+ ---
895
+
896
+ <a id="op-getcontact"></a>
897
+
898
+ ### `g8.api.contacts.getContact(input)`
899
+
900
+ **Get Contact**
901
+
902
+ - HTTP: `GET /api/v1/contacts/{contact_id}`
903
+ - operationId: `get_contact_contacts__contact_id__get` (also callable as `g8.api.call("get_contact_contacts__contact_id__get", input)`)
904
+ - Tier: `read`: reads data; safe to call and to retry
905
+ - API-key scope: `contacts:read`
906
+ - ★ Hand-written: [`g8.contacts.get()`](../sdk-clients.md#g8-contacts-get)
907
+
908
+ Get detailed information about a single contact.
909
+
910
+ **Input**
911
+
912
+ | Field | Type | Required | Description |
913
+ |---|---|---|---|
914
+ | `path.contact_id` | `integer` | yes | Contact ID |
915
+ | `query.include_custom_fields` | `boolean` | no | When true, the response includes a `custom_fields` object of custom column values keyed by column slug. Default false omits it. default `false` |
916
+
917
+ **Returns** `ApiResponse_ContactResponse_`: the envelope `{ data: ContactResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
918
+
919
+ Other envelope fields: `pagination` (PaginationMeta).
920
+
921
+ `ContactResponse` fields:
922
+
923
+ | Field | Type | Required | Description |
924
+ |---|---|---|---|
925
+ | `id` | `integer` | yes | |
926
+ | `about` | `string \| null` | no | |
927
+ | `city` | `string \| null` | no | |
928
+ | `company` | `ContactCompanySummary \| null` | no | |
929
+ | `confidence_score` | `number \| null` | no | |
930
+ | `country` | `string \| null` | no | |
931
+ | `created_at` | `string \| null` | no | |
932
+ | `custom_fields` | `Record<string, string \| null> \| null` | no | |
933
+ | `direct_phone` | `string \| null` | no | |
934
+ | `facebook_url` | `string \| null` | no | |
935
+ | `first_name` | `string \| null` | no | |
936
+ | `full_name` | `string \| null` | no | |
937
+ | `job_department` | `string \| null` | no | |
938
+ | `job_title` | `string \| null` | no | |
939
+ | `last_name` | `string \| null` | no | |
940
+ | `linkedin_url` | `string \| null` | no | |
941
+ | `meta_data` | `Record<string, unknown> \| null` | no | |
942
+ | `mobile_phone` | `string \| null` | no | |
943
+ | `personal_emails` | `unknown \| null` | no | |
944
+ | `seniority_level` | `string \| null` | no | |
945
+ | `state` | `string \| null` | no | |
946
+ | `twitter_url` | `string \| null` | no | |
947
+ | `updated_at` | `string \| null` | no | |
948
+ | `work_email` | `string \| null` | no | |
949
+
950
+ **Example**
951
+
952
+ ```ts
953
+ const result = await g8.api.contacts.getContact({ path: { contact_id: 123 } });
954
+ ```
955
+
956
+ ---
957
+
958
+ <a id="op-getcontactanalysis"></a>
959
+
960
+ ### `g8.api.contacts.getContactAnalysis(input)`
961
+
962
+ **Get Contact Analysis**
963
+
964
+ - HTTP: `GET /api/v1/contacts/{contact_id}/analysis`
965
+ - operationId: `get_contact_analysis_contacts__contact_id__analysis_get` (also callable as `g8.api.call("get_contact_analysis_contacts__contact_id__analysis_get", input)`)
966
+ - Tier: `read`: reads data; safe to call and to retry
967
+ - API-key scope: `contacts:read`
968
+
969
+ Engagement trend over 7/30/60 days and the strategy it suggests.
970
+
971
+ Rule-based over recorded events, cached briefly. No model call, no spend.
972
+
973
+ **Input**
974
+
975
+ | Field | Type | Required | Description |
976
+ |---|---|---|---|
977
+ | `path.contact_id` | `integer` | yes | Contact id. |
978
+
979
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
980
+
981
+ Other envelope fields: `pagination` (PaginationMeta).
982
+
983
+ **Example**
984
+
985
+ ```ts
986
+ const result = await g8.api.contacts.getContactAnalysis({ path: { contact_id: 123 } });
987
+ ```
988
+
989
+ ---
990
+
991
+ <a id="op-getcontactdashboard"></a>
992
+
993
+ ### `g8.api.contacts.getContactDashboard(input)`
994
+
995
+ **Get Contact Dashboard**
996
+
997
+ - HTTP: `GET /api/v1/contacts/{contact_id}/dashboard`
998
+ - operationId: `get_contact_dashboard_contacts__contact_id__dashboard_get` (also callable as `g8.api.call("get_contact_dashboard_contacts__contact_id__dashboard_get", input)`)
999
+ - Tier: `read`: reads data; safe to call and to retry
1000
+ - API-key scope: `contacts:read`
1001
+
1002
+ Everything the contact detail view shows, in one call.
1003
+
1004
+ Open-shaped: this is a composed view whose panels grow with the product.
1005
+
1006
+ **Input**
1007
+
1008
+ | Field | Type | Required | Description |
1009
+ |---|---|---|---|
1010
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
1011
+
1012
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1013
+
1014
+ Other envelope fields: `pagination` (PaginationMeta).
1015
+
1016
+ **Example**
1017
+
1018
+ ```ts
1019
+ const result = await g8.api.contacts.getContactDashboard({ path: { contact_id: 123 } });
1020
+ ```
1021
+
1022
+ ---
1023
+
1024
+ <a id="op-getcontactdashboardstats"></a>
1025
+
1026
+ ### `g8.api.contacts.getContactDashboardStats(input?)`
1027
+
1028
+ **Get Contact Dashboard Stats**
1029
+
1030
+ - HTTP: `GET /api/v1/contacts/dashboard-stats`
1031
+ - operationId: `get_contact_dashboard_stats_contacts_dashboard_stats_get` (also callable as `g8.api.call("get_contact_dashboard_stats_contacts_dashboard_stats_get", input)`)
1032
+ - Tier: `read`: reads data; safe to call and to retry
1033
+ - API-key scope: `contacts:read`
1034
+
1035
+ Counts and distributions across the contacts this key can see.
1036
+
1037
+ Scoped, not org-wide: a key narrowed away from contacts gets its own
1038
+ narrower totals rather than the organisation's.
1039
+
1040
+ **Input**: none.
1041
+
1042
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1043
+
1044
+ Other envelope fields: `pagination` (PaginationMeta).
1045
+
1046
+ **Example**
1047
+
1048
+ ```ts
1049
+ const result = await g8.api.contacts.getContactDashboardStats();
1050
+ ```
1051
+
1052
+ ---
1053
+
1054
+ <a id="op-getcontactdetail"></a>
1055
+
1056
+ ### `g8.api.contacts.getContactDetail(input)`
1057
+
1058
+ **Get Contact Detail**
1059
+
1060
+ - HTTP: `GET /api/v1/contacts/{contact_id}/detail`
1061
+ - operationId: `get_contact_detail_contacts__contact_id__detail_get` (also callable as `g8.api.call("get_contact_detail_contacts__contact_id__detail_get", input)`)
1062
+ - Tier: `read`: reads data; safe to call and to retry
1063
+ - API-key scope: `contacts:read`
1064
+
1065
+ The composed contact record the app's detail page renders.
1066
+
1067
+ 404 when the contact does not exist OR is outside the key's scope - the
1068
+ two are deliberately indistinguishable.
1069
+
1070
+ **Input**
1071
+
1072
+ | Field | Type | Required | Description |
1073
+ |---|---|---|---|
1074
+ | `path.contact_id` | `integer` | yes | Contact id. |
1075
+
1076
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1077
+
1078
+ Other envelope fields: `pagination` (PaginationMeta).
1079
+
1080
+ **Example**
1081
+
1082
+ ```ts
1083
+ const result = await g8.api.contacts.getContactDetail({ path: { contact_id: 123 } });
1084
+ ```
1085
+
1086
+ ---
1087
+
1088
+ <a id="op-getcontactdocument"></a>
1089
+
1090
+ ### `g8.api.contacts.getContactDocument(input)`
1091
+
1092
+ **Get Contact Document**
1093
+
1094
+ - HTTP: `GET /api/v1/contacts/{contact_id}/documents/types/{doc_type}`
1095
+ - operationId: `get_contact_document_contacts__contact_id__documents_types__doc_type__get` (also callable as `g8.api.call("get_contact_document_contacts__contact_id__documents_types__doc_type__get", input)`)
1096
+ - Tier: `read`: reads data; safe to call and to retry
1097
+ - API-key scope: `contacts:read`
1098
+
1099
+ The current document of one type for this contact.
1100
+
1101
+ **Input**
1102
+
1103
+ | Field | Type | Required | Description |
1104
+ |---|---|---|---|
1105
+ | `path.contact_id` | `integer` | yes | Contact id. |
1106
+ | `path.doc_type` | `string` | yes | Document type, e.g. `contact_brief`. |
1107
+
1108
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1109
+
1110
+ Other envelope fields: `pagination` (PaginationMeta).
1111
+
1112
+ **Example**
1113
+
1114
+ ```ts
1115
+ const result = await g8.api.contacts.getContactDocument({ path: { contact_id: 123, doc_type: "example" } });
1116
+ ```
1117
+
1118
+ ---
1119
+
1120
+ <a id="op-getcontactengagementsummary"></a>
1121
+
1122
+ ### `g8.api.contacts.getContactEngagementSummary(input)`
1123
+
1124
+ **Get Contact Engagement Summary**
1125
+
1126
+ - HTTP: `GET /api/v1/contacts/{contact_id}/engagement-summary`
1127
+ - operationId: `get_contact_engagement_summary_contacts__contact_id__engagement_summary_get` (also callable as `g8.api.call("get_contact_engagement_summary_contacts__contact_id__engagement_summary_get", input)`)
1128
+ - Tier: `read`: reads data; safe to call and to retry
1129
+ - API-key scope: `contacts:read`
1130
+
1131
+ How much this contact has engaged: emails, calls, meetings, visits.
1132
+
1133
+ Gated on `id_kind="pk"` because the handler counts against
1134
+ `mashup_contacts.id`. A gate resolving any other namespace would authorise
1135
+ a different row than it serves.
1136
+
1137
+ **Input**
1138
+
1139
+ | Field | Type | Required | Description |
1140
+ |---|---|---|---|
1141
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
1142
+
1143
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1144
+
1145
+ Other envelope fields: `pagination` (PaginationMeta).
1146
+
1147
+ **Example**
1148
+
1149
+ ```ts
1150
+ const result = await g8.api.contacts.getContactEngagementSummary({ path: { contact_id: 123 } });
1151
+ ```
1152
+
1153
+ ---
1154
+
1155
+ <a id="op-getcontactformfields"></a>
1156
+
1157
+ ### `g8.api.contacts.getContactFormFields(input?)`
1158
+
1159
+ **Get Contact Form Fields**
1160
+
1161
+ - HTTP: `GET /api/v1/contacts/form-fields`
1162
+ - operationId: `get_contact_form_fields_contacts_form_fields_get` (also callable as `g8.api.call("get_contact_form_fields_contacts_form_fields_get", input)`)
1163
+ - Tier: `read`: reads data; safe to call and to retry
1164
+ - API-key scope: `contacts:read`
1165
+
1166
+ Fields grouped the way the contact form presents them.
1167
+
1168
+ Same underlying columns as the schema reads above, arranged into labelled
1169
+ groups with a `required` flag - what to render, rather than what exists.
1170
+
1171
+ **Input**
1172
+
1173
+ | Field | Type | Required | Description |
1174
+ |---|---|---|---|
1175
+ | `query.list_id` | `integer \| null` | no | Include this list's custom fields. |
1176
+
1177
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1178
+
1179
+ Other envelope fields: `pagination` (PaginationMeta).
1180
+
1181
+ **Example**
1182
+
1183
+ ```ts
1184
+ const result = await g8.api.contacts.getContactFormFields();
1185
+ ```
1186
+
1187
+ ---
1188
+
1189
+ <a id="op-getcontactgenerationstatus"></a>
1190
+
1191
+ ### `g8.api.contacts.getContactGenerationStatus(input)`
1192
+
1193
+ **Get Contact Generation Status**
1194
+
1195
+ - HTTP: `GET /api/v1/contacts/{contact_id}/documents/generation-status`
1196
+ - operationId: `get_contact_generation_status_contacts__contact_id__documents_generation_status_get` (also callable as `g8.api.call("get_contact_generation_status_contacts__contact_id__documents_generation_status_get", input)`)
1197
+ - Tier: `read`: reads data; safe to call and to retry
1198
+ - API-key scope: `contacts:read`
1199
+
1200
+ Progress of this contact's document generation. Reads only.
1201
+
1202
+ Named for the app route it proxies, which means the path contains
1203
+ `generate` - the tier heuristic reads that as an active GET and would
1204
+ publish a status poll as a credit spend. It is corrected by an explicit
1205
+ entry in `build_scope_policy.py::READ_ONLY_ACTIVE_GET_ROUTES` rather than
1206
+ by spelling the path around the matcher.
1207
+
1208
+ **Input**
1209
+
1210
+ | Field | Type | Required | Description |
1211
+ |---|---|---|---|
1212
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
1213
+
1214
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1215
+
1216
+ Other envelope fields: `pagination` (PaginationMeta).
1217
+
1218
+ **Example**
1219
+
1220
+ ```ts
1221
+ const result = await g8.api.contacts.getContactGenerationStatus({ path: { contact_id: 123 } });
1222
+ ```
1223
+
1224
+ ---
1225
+
1226
+ <a id="op-getcontactlists"></a>
1227
+
1228
+ ### `g8.api.contacts.getContactLists(input)`
1229
+
1230
+ **Get Contact Lists**
1231
+
1232
+ - HTTP: `GET /api/v1/contacts/{contact_id}/lists`
1233
+ - operationId: `get_contact_lists_contacts__contact_id__lists_get` (also callable as `g8.api.call("get_contact_lists_contacts__contact_id__lists_get", input)`)
1234
+ - Tier: `read`: reads data; safe to call and to retry
1235
+ - API-key scope: `contacts:read`
1236
+
1237
+ The lists this contact belongs to that the key can see.
1238
+
1239
+ **Input**
1240
+
1241
+ | Field | Type | Required | Description |
1242
+ |---|---|---|---|
1243
+ | `path.contact_id` | `integer` | yes | Contact primary key (`mashup_contacts.id`). |
1244
+
1245
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1246
+
1247
+ Other envelope fields: `pagination` (PaginationMeta).
1248
+
1249
+ `CrmCollectionPayload` fields:
1250
+
1251
+ | Field | Type | Required | Description |
1252
+ |---|---|---|---|
1253
+ | `items` | `Array<unknown>` | no | |
1254
+
1255
+ **Example**
1256
+
1257
+ ```ts
1258
+ const result = await g8.api.contacts.getContactLists({ path: { contact_id: 123 } });
1259
+ ```
1260
+
1261
+ ---
1262
+
1263
+ <a id="op-getcontactmeetings"></a>
1264
+
1265
+ ### `g8.api.contacts.getContactMeetings(input)`
1266
+
1267
+ **Get Contact Meetings**
1268
+
1269
+ - HTTP: `GET /api/v1/contacts/{contact_id}/meetings`
1270
+ - operationId: `get_contact_meetings_contacts__contact_id__meetings_get` (also callable as `g8.api.call("get_contact_meetings_contacts__contact_id__meetings_get", input)`)
1271
+ - Tier: `read`: reads data; safe to call and to retry
1272
+ - API-key scope: `contacts:read`
1273
+
1274
+ Meetings booked with this contact, past and upcoming.
1275
+
1276
+ **Input**
1277
+
1278
+ | Field | Type | Required | Description |
1279
+ |---|---|---|---|
1280
+ | `path.contact_id` | `integer` | yes | Contact id. |
1281
+
1282
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1283
+
1284
+ Other envelope fields: `pagination` (PaginationMeta).
1285
+
1286
+ `CrmCollectionPayload` fields:
1287
+
1288
+ | Field | Type | Required | Description |
1289
+ |---|---|---|---|
1290
+ | `items` | `Array<unknown>` | no | |
1291
+
1292
+ **Example**
1293
+
1294
+ ```ts
1295
+ const result = await g8.api.contacts.getContactMeetings({ path: { contact_id: 123 } });
1296
+ ```
1297
+
1298
+ ---
1299
+
1300
+ <a id="op-getcontactnextbeststep"></a>
1301
+
1302
+ ### `g8.api.contacts.getContactNextBestStep(input)`
1303
+
1304
+ **Get Contact Next Best Step**
1305
+
1306
+ - HTTP: `GET /api/v1/contacts/{contact_id}/next-best-step`
1307
+ - operationId: `get_contact_next_best_step_contacts__contact_id__next_best_step_get` (also callable as `g8.api.call("get_contact_next_best_step_contacts__contact_id__next_best_step_get", input)`)
1308
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
1309
+ - API-key scope: `enrichment:run`
1310
+
1311
+ What to do next with this contact, and why. SPENDS CREDITS.
1312
+
1313
+ A GET that costs money: the recommendation is generated by a model on a
1314
+ cache miss, and the cache key includes the contact's engagement state, so
1315
+ activity on the record invalidates it. Tiered `billable` for that reason
1316
+ rather than as an ordinary read - polling it per contact is real spend.
1317
+
1318
+ **Input**
1319
+
1320
+ | Field | Type | Required | Description |
1321
+ |---|---|---|---|
1322
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
1323
+
1324
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1325
+
1326
+ Other envelope fields: `pagination` (PaginationMeta).
1327
+
1328
+ **Example**
1329
+
1330
+ ```ts
1331
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
1332
+ const result = await g8.api.contacts.getContactNextBestStep({ path: { contact_id: 123 } });
1333
+ ```
1334
+
1335
+ ---
1336
+
1337
+ <a id="op-getcontactprofilepictures"></a>
1338
+
1339
+ ### `g8.api.contacts.getContactProfilePictures(input)`
1340
+
1341
+ **Get Contact Profile Pictures**
1342
+
1343
+ - HTTP: `POST /api/v1/contacts/profile-pictures`
1344
+ - operationId: `get_contact_profile_pictures_contacts_profile_pictures_post` (also callable as `g8.api.call("get_contact_profile_pictures_contacts_profile_pictures_post", input)`)
1345
+ - Tier: `read`: reads data; safe to call and to retry
1346
+ - API-key scope: `contacts:read`
1347
+
1348
+ Resolve profile photos for a batch of LinkedIn URLs.
1349
+
1350
+ A missing key in the result means "no allow-listed photo for that URL",
1351
+ not "the lookup failed" - roughly half of contacts have one. Soft-fails to
1352
+ an empty map rather than erroring, so it is safe on a render path.
1353
+
1354
+ **Input**
1355
+
1356
+ | Field | Type | Required | Description |
1357
+ |---|---|---|---|
1358
+ | `body` | `ProfilePicturesRequest` | yes | Request body; fields below. |
1359
+
1360
+ Body fields (`ProfilePicturesRequest`):
1361
+
1362
+ | Field | Type | Required | Description |
1363
+ |---|---|---|---|
1364
+ | `body.linkedin_urls` | `Array<string>` | no | LinkedIn profile URLs (deduplicated, max 200). max items 200 |
1365
+
1366
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1367
+
1368
+ Other envelope fields: `pagination` (PaginationMeta).
1369
+
1370
+ **Example**
1371
+
1372
+ ```ts
1373
+ const result = await g8.api.contacts.getContactProfilePictures({ body: {} });
1374
+ ```
1375
+
1376
+ ---
1377
+
1378
+ <a id="op-getcontactrowdetail"></a>
1379
+
1380
+ ### `g8.api.contacts.getContactRowDetail(input)`
1381
+
1382
+ **Get Contact Row Detail**
1383
+
1384
+ - HTTP: `GET /api/v1/contacts/row-detail/{record_id}`
1385
+ - operationId: `get_contact_row_detail_contacts_row_detail__record_id__get` (also callable as `g8.api.call("get_contact_row_detail_contacts_row_detail__record_id__get", input)`)
1386
+ - Tier: `read`: reads data; safe to call and to retry
1387
+ - API-key scope: `contacts:read`
1388
+
1389
+ Which workflows have run against this record, and what they produced.
1390
+
1391
+ Carries the execution timeline, each run's outputs, and the actions
1392
+ currently available on the row. The workflow-permission gate is the app's
1393
+ own, including its soak behaviour - while the enforcement flag is off a
1394
+ caller without `workflows:read` is logged and allowed, because that
1395
+ permission is not yet held by every role.
1396
+
1397
+ Under `/contacts/` because the record scope it enforces is the CONTACT
1398
+ one, but `record_id` is whatever the list holds: a companies list reads
1399
+ company rows through this path.
1400
+
1401
+ **Input**
1402
+
1403
+ | Field | Type | Required | Description |
1404
+ |---|---|---|---|
1405
+ | `path.record_id` | `integer` | yes | Record primary key. |
1406
+ | `query.list_id` | `integer` | yes | Required: the list the record is read through. |
1407
+
1408
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1409
+
1410
+ Other envelope fields: `pagination` (PaginationMeta).
1411
+
1412
+ **Example**
1413
+
1414
+ ```ts
1415
+ const result = await g8.api.contacts.getContactRowDetail({ path: { record_id: 123 }, query: { list_id: 123 } });
1416
+ ```
1417
+
1418
+ ---
1419
+
1420
+ <a id="op-getcontactsequences"></a>
1421
+
1422
+ ### `g8.api.contacts.getContactSequences(input)`
1423
+
1424
+ **Get Contact Sequences**
1425
+
1426
+ - HTTP: `GET /api/v1/contacts/{contact_id}/sequences`
1427
+ - operationId: `get_contact_sequences_contacts__contact_id__sequences_get` (also callable as `g8.api.call("get_contact_sequences_contacts__contact_id__sequences_get", input)`)
1428
+ - Tier: `read`: reads data; safe to call and to retry
1429
+ - API-key scope: `contacts:read`
1430
+
1431
+ Every sequence this contact is or was enrolled in, with its step and state.
1432
+
1433
+ **Input**
1434
+
1435
+ | Field | Type | Required | Description |
1436
+ |---|---|---|---|
1437
+ | `path.contact_id` | `integer` | yes | Contact id. |
1438
+
1439
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1440
+
1441
+ Other envelope fields: `pagination` (PaginationMeta).
1442
+
1443
+ `CrmCollectionPayload` fields:
1444
+
1445
+ | Field | Type | Required | Description |
1446
+ |---|---|---|---|
1447
+ | `items` | `Array<unknown>` | no | |
1448
+
1449
+ **Example**
1450
+
1451
+ ```ts
1452
+ const result = await g8.api.contacts.getContactSequences({ path: { contact_id: 123 } });
1453
+ ```
1454
+
1455
+ ---
1456
+
1457
+ <a id="op-getcontactsignals"></a>
1458
+
1459
+ ### `g8.api.contacts.getContactSignals(input)`
1460
+
1461
+ **Get Contact Signals**
1462
+
1463
+ - HTTP: `GET /api/v1/contacts/{contact_id}/signals`
1464
+ - operationId: `get_contact_signals_contacts__contact_id__signals_get` (also callable as `g8.api.call("get_contact_signals_contacts__contact_id__signals_get", input)`)
1465
+ - Tier: `read`: reads data; safe to call and to retry
1466
+ - API-key scope: `contacts:read`
1467
+
1468
+ Buying signals recorded against this contact.
1469
+
1470
+ **Input**
1471
+
1472
+ | Field | Type | Required | Description |
1473
+ |---|---|---|---|
1474
+ | `path.contact_id` | `integer` | yes | Contact id. |
1475
+
1476
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1477
+
1478
+ Other envelope fields: `pagination` (PaginationMeta).
1479
+
1480
+ **Example**
1481
+
1482
+ ```ts
1483
+ const result = await g8.api.contacts.getContactSignals({ path: { contact_id: 123 } });
1484
+ ```
1485
+
1486
+ ---
1487
+
1488
+ <a id="op-getcontactsitesvisited"></a>
1489
+
1490
+ ### `g8.api.contacts.getContactSitesVisited(input)`
1491
+
1492
+ **Get Contact Sites Visited**
1493
+
1494
+ - HTTP: `GET /api/v1/contacts/{contact_id}/sites-visited`
1495
+ - operationId: `get_contact_sites_visited_contacts__contact_id__sites_visited_get` (also callable as `g8.api.call("get_contact_sites_visited_contacts__contact_id__sites_visited_get", input)`)
1496
+ - Tier: `read`: reads data; safe to call and to retry
1497
+ - API-key scope: `contacts:read`
1498
+
1499
+ Pages this contact visited on your site.
1500
+
1501
+ **Input**
1502
+
1503
+ | Field | Type | Required | Description |
1504
+ |---|---|---|---|
1505
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
1506
+ | `query.days` | `integer` | no | Lookback window. Bounded here rather than left open: the query is an unindexed analytics scan and an unbounded window is a cheap way to exhaust it. default `90` |
1507
+
1508
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1509
+
1510
+ Other envelope fields: `pagination` (PaginationMeta).
1511
+
1512
+ **Example**
1513
+
1514
+ ```ts
1515
+ const result = await g8.api.contacts.getContactSitesVisited({ path: { contact_id: 123 } });
1516
+ ```
1517
+
1518
+ ---
1519
+
1520
+ <a id="op-getcontacttagids"></a>
1521
+
1522
+ ### `g8.api.contacts.getContactTagIds(input)`
1523
+
1524
+ **Get Contact Tag Ids**
1525
+
1526
+ - HTTP: `GET /api/v1/contacts/{contact_id}/tags`
1527
+ - operationId: `get_contact_tag_ids_contacts__contact_id__tags_get` (also callable as `g8.api.call("get_contact_tag_ids_contacts__contact_id__tags_get", input)`)
1528
+ - Tier: `read`: reads data; safe to call and to retry
1529
+ - API-key scope: `contacts:read`
1530
+
1531
+ The ids of the tags on this contact. Resolve names with `GET /contacts/tags`.
1532
+
1533
+ **Input**
1534
+
1535
+ | Field | Type | Required | Description |
1536
+ |---|---|---|---|
1537
+ | `path.contact_id` | `integer` | yes | Contact id. |
1538
+
1539
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1540
+
1541
+ Other envelope fields: `pagination` (PaginationMeta).
1542
+
1543
+ **Example**
1544
+
1545
+ ```ts
1546
+ const result = await g8.api.contacts.getContactTagIds({ path: { contact_id: 123 } });
1547
+ ```
1548
+
1549
+ ---
1550
+
1551
+ <a id="op-getduplicatesettings"></a>
1552
+
1553
+ ### `g8.api.contacts.getDuplicateSettings(input?)`
1554
+
1555
+ **Get Duplicate Settings**
1556
+
1557
+ - HTTP: `GET /api/v1/duplicates/settings`
1558
+ - operationId: `get_duplicate_settings_duplicates_settings_get` (also callable as `g8.api.call("get_duplicate_settings_duplicates_settings_get", input)`)
1559
+ - Tier: `read`: reads data; safe to call and to retry
1560
+ - API-key scope: `contacts:read`
1561
+
1562
+ The org's merge rules: field winners, auto-merge, detection-rule overrides.
1563
+
1564
+ Admin-only in the app (manage scope on every governed object); the same
1565
+ check runs here, inside the handler.
1566
+
1567
+ **Input**: none.
1568
+
1569
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1570
+
1571
+ Other envelope fields: `pagination` (PaginationMeta).
1572
+
1573
+ **Example**
1574
+
1575
+ ```ts
1576
+ const result = await g8.api.contacts.getDuplicateSettings();
1577
+ ```
1578
+
1579
+ ---
1580
+
1581
+ <a id="op-getrecordcolumnvalues"></a>
1582
+
1583
+ ### `g8.api.contacts.getRecordColumnValues(input)`
1584
+
1585
+ **Get Record Column Values**
1586
+
1587
+ - HTTP: `POST /api/v1/contacts/column-values`
1588
+ - operationId: `get_record_column_values_contacts_column_values_post` (also callable as `g8.api.call("get_record_column_values_contacts_column_values_post", input)`)
1589
+ - Tier: `read`: reads data; safe to call and to retry
1590
+ - API-key scope: `contacts:read`
1591
+
1592
+ Every column value for one row, resolved through a list.
1593
+
1594
+ The list is required, not optional: it decides whether `record_id` names a
1595
+ contact or a company and which list-scoped custom columns apply. Reading
1596
+ the same id through two different lists can legitimately return different
1597
+ columns.
1598
+
1599
+ **Input**
1600
+
1601
+ | Field | Type | Required | Description |
1602
+ |---|---|---|---|
1603
+ | `body` | `RecordColumnValuesRequest` | yes | Request body; fields below. |
1604
+
1605
+ Body fields (`RecordColumnValuesRequest`):
1606
+
1607
+ | Field | Type | Required | Description |
1608
+ |---|---|---|---|
1609
+ | `body.list_id` | `integer` | yes | List the record is read through. |
1610
+ | `body.record_id` | `integer` | yes | Record primary key. |
1611
+
1612
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1613
+
1614
+ Other envelope fields: `pagination` (PaginationMeta).
1615
+
1616
+ **Example**
1617
+
1618
+ ```ts
1619
+ const result = await g8.api.contacts.getRecordColumnValues({ body: { list_id: 123, record_id: 123 } });
1620
+ ```
1621
+
1622
+ ---
1623
+
1624
+ <a id="op-listbasecolumns"></a>
1625
+
1626
+ ### `g8.api.contacts.listBaseColumns(input)`
1627
+
1628
+ **List Base Columns**
1629
+
1630
+ - HTTP: `GET /api/v1/contacts/base-columns`
1631
+ - operationId: `list_base_columns_contacts_base_columns_get` (also callable as `g8.api.call("list_base_columns_contacts_base_columns_get", input)`)
1632
+ - Tier: `read`: reads data; safe to call and to retry
1633
+ - API-key scope: `contacts:read`
1634
+
1635
+ The real DATABASE columns behind a list.
1636
+
1637
+ Excludes the composite and enrichment columns the grid displays, so what
1638
+ comes back is what can actually be written to and filtered on.
1639
+
1640
+ **Input**
1641
+
1642
+ | Field | Type | Required | Description |
1643
+ |---|---|---|---|
1644
+ | `query.list_id` | `integer` | yes | Required: the list decides which base columns exist. |
1645
+
1646
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1647
+
1648
+ Other envelope fields: `pagination` (PaginationMeta).
1649
+
1650
+ `CrmCollectionPayload` fields:
1651
+
1652
+ | Field | Type | Required | Description |
1653
+ |---|---|---|---|
1654
+ | `items` | `Array<unknown>` | no | |
1655
+
1656
+ **Example**
1657
+
1658
+ ```ts
1659
+ const result = await g8.api.contacts.listBaseColumns({ query: { list_id: 123 } });
1660
+ ```
1661
+
1662
+ ---
1663
+
1664
+ <a id="op-listcolumnnames"></a>
1665
+
1666
+ ### `g8.api.contacts.listColumnNames(input?)`
1667
+
1668
+ **List Column Names**
1669
+
1670
+ - HTTP: `GET /api/v1/contacts/column-names`
1671
+ - operationId: `list_column_names_contacts_column_names_get` (also callable as `g8.api.call("list_column_names_contacts_column_names_get", input)`)
1672
+ - Tier: `read`: reads data; safe to call and to retry
1673
+ - API-key scope: `contacts:read`
1674
+
1675
+ Column names only, as a flat list of strings.
1676
+
1677
+ **Input**
1678
+
1679
+ | Field | Type | Required | Description |
1680
+ |---|---|---|---|
1681
+ | `query.list_id` | `integer \| null` | no | Include this list's own columns. |
1682
+
1683
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1684
+
1685
+ Other envelope fields: `pagination` (PaginationMeta).
1686
+
1687
+ `CrmCollectionPayload` fields:
1688
+
1689
+ | Field | Type | Required | Description |
1690
+ |---|---|---|---|
1691
+ | `items` | `Array<unknown>` | no | |
1692
+
1693
+ **Example**
1694
+
1695
+ ```ts
1696
+ const result = await g8.api.contacts.listColumnNames();
1697
+ ```
1698
+
1699
+ ---
1700
+
1701
+ <a id="op-listcontactcolumndefinitions"></a>
1702
+
1703
+ ### `g8.api.contacts.listContactColumnDefinitions(input?)`
1704
+
1705
+ **List Contact Column Definitions**
1706
+
1707
+ - HTTP: `GET /api/v1/contacts/column-definitions`
1708
+ - operationId: `list_contact_column_definitions_contacts_column_definitions_get` (also callable as `g8.api.call("list_contact_column_definitions_contacts_column_definitions_get", input)`)
1709
+ - Tier: `read`: reads data; safe to call and to retry
1710
+ - API-key scope: `contacts:read`
1711
+
1712
+ Every column the grid can show, with its type and display name.
1713
+
1714
+ The richest of the schema reads here: it carries base columns, custom
1715
+ columns and enrichment columns together. `GET /contacts/columns` returns
1716
+ the custom columns alone.
1717
+
1718
+ **Input**
1719
+
1720
+ | Field | Type | Required | Description |
1721
+ |---|---|---|---|
1722
+ | `query.list_id` | `integer \| null` | no | Include the columns specific to this list. The list also decides whether contact or company columns are returned - a companies list returns company columns from this contacts path. |
1723
+
1724
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1725
+
1726
+ Other envelope fields: `pagination` (PaginationMeta).
1727
+
1728
+ `CrmCollectionPayload` fields:
1729
+
1730
+ | Field | Type | Required | Description |
1731
+ |---|---|---|---|
1732
+ | `items` | `Array<unknown>` | no | |
1733
+
1734
+ **Example**
1735
+
1736
+ ```ts
1737
+ const result = await g8.api.contacts.listContactColumnDefinitions();
1738
+ ```
1739
+
1740
+ ---
1741
+
1742
+ <a id="op-listcontactcolumns"></a>
1743
+
1744
+ ### `g8.api.contacts.listContactColumns(input?)`
1745
+
1746
+ **List Contact Columns**
1747
+
1748
+ - HTTP: `GET /api/v1/contacts/columns`
1749
+ - operationId: `list_contact_columns_contacts_columns_get` (also callable as `g8.api.call("list_contact_columns_contacts_columns_get", input)`)
1750
+ - Tier: `read`: reads data; safe to call and to retry
1751
+ - API-key scope: `contacts:read`
1752
+ - ★ Hand-written: [`g8.contacts.listColumns()`](../sdk-clients.md#g8-contacts-listcolumns)
1753
+
1754
+ List custom contact columns (table columns + global dynamic columns; +list-scoped if list_id given).
1755
+
1756
+ **Input**
1757
+
1758
+ | Field | Type | Required | Description |
1759
+ |---|---|---|---|
1760
+ | `query.list_id` | `integer \| null` | no | Optional list ID. When provided, list-specific dynamic columns are included alongside global ones. |
1761
+
1762
+ **Returns** `ApiResponse_list_Column__`: the envelope `{ data: Array<Column>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1763
+
1764
+ Other envelope fields: `pagination` (PaginationMeta).
1765
+
1766
+ `Column` fields:
1767
+
1768
+ | Field | Type | Required | Description |
1769
+ |---|---|---|---|
1770
+ | `is_global` | `boolean` | yes | Automatically computed: True if object_id is None/empty, False otherwise. |
1771
+ | `title` | `string` | yes | |
1772
+ | `data_type` | `ColumnType` | no | default `"text"` |
1773
+ | `id` | `integer \| null` | no | |
1774
+ | `name` | `string \| null` | no | |
1775
+ | `object_id` | `string \| null` | no | |
1776
+ | `source` | `ColumnSource` | no | default `"contact"` |
1777
+
1778
+ **Example**
1779
+
1780
+ ```ts
1781
+ const result = await g8.api.contacts.listContactColumns();
1782
+ ```
1783
+
1784
+ ---
1785
+
1786
+ <a id="op-listcontactdocuments"></a>
1787
+
1788
+ ### `g8.api.contacts.listContactDocuments(input)`
1789
+
1790
+ **List Contact Documents**
1791
+
1792
+ - HTTP: `GET /api/v1/contacts/{contact_id}/documents`
1793
+ - operationId: `list_contact_documents_contacts__contact_id__documents_get` (also callable as `g8.api.call("list_contact_documents_contacts__contact_id__documents_get", input)`)
1794
+ - Tier: `read`: reads data; safe to call and to retry
1795
+ - API-key scope: `contacts:read`
1796
+
1797
+ The documents graph8 has generated about this contact.
1798
+
1799
+ **Input**
1800
+
1801
+ | Field | Type | Required | Description |
1802
+ |---|---|---|---|
1803
+ | `path.contact_id` | `integer` | yes | Contact id. |
1804
+ | `query.folder` | `string \| null` | no | Only documents in this folder. |
1805
+
1806
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1807
+
1808
+ Other envelope fields: `pagination` (PaginationMeta).
1809
+
1810
+ `CrmCollectionPayload` fields:
1811
+
1812
+ | Field | Type | Required | Description |
1813
+ |---|---|---|---|
1814
+ | `items` | `Array<unknown>` | no | |
1815
+
1816
+ **Example**
1817
+
1818
+ ```ts
1819
+ const result = await g8.api.contacts.listContactDocuments({ path: { contact_id: 123 } });
1820
+ ```
1821
+
1822
+ ---
1823
+
1824
+ <a id="op-listcontacttags"></a>
1825
+
1826
+ ### `g8.api.contacts.listContactTags(input?)`
1827
+
1828
+ **List Contact Tags**
1829
+
1830
+ - HTTP: `GET /api/v1/contacts/tags`
1831
+ - operationId: `list_contact_tags_contacts_tags_get` (also callable as `g8.api.call("list_contact_tags_contacts_tags_get", input)`)
1832
+ - Tier: `read`: reads data; safe to call and to retry
1833
+ - API-key scope: `contacts:read`
1834
+
1835
+ Org tag definitions with per-tag contact counts.
1836
+
1837
+ **Input**
1838
+
1839
+ | Field | Type | Required | Description |
1840
+ |---|---|---|---|
1841
+ | `query.include_archived` | `boolean` | no | Include archived tags. default `false` |
1842
+
1843
+ **Returns** `ApiResponse_ContactTagListResponse_`: the envelope `{ data: ContactTagListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1844
+
1845
+ Other envelope fields: `pagination` (PaginationMeta).
1846
+
1847
+ `ContactTagListResponse` fields:
1848
+
1849
+ | Field | Type | Required | Description |
1850
+ |---|---|---|---|
1851
+ | `tags` | `Array<ContactTag>` | no | |
1852
+ | `total` | `integer` | no | default `0` |
1853
+
1854
+ **Example**
1855
+
1856
+ ```ts
1857
+ const result = await g8.api.contacts.listContactTags();
1858
+ ```
1859
+
1860
+ ---
1861
+
1862
+ <a id="op-listcontacts"></a>
1863
+
1864
+ ### `g8.api.contacts.listContacts(input?)`
1865
+
1866
+ **List Contacts**
1867
+
1868
+ - HTTP: `GET /api/v1/contacts`
1869
+ - operationId: `list_contacts_contacts_get` (also callable as `g8.api.call("list_contacts_contacts_get", input)`)
1870
+ - Tier: `read`: reads data; safe to call and to retry
1871
+ - API-key scope: `contacts:read`
1872
+ - ★ Hand-written: [`g8.contacts.list()`](../sdk-clients.md#g8-contacts-list), [`g8.contacts.listDetailed()`](../sdk-clients.md#g8-contacts-listdetailed)
1873
+
1874
+ List contacts with optional filtering and pagination.
1875
+
1876
+ **Input**
1877
+
1878
+ | Field | Type | Required | Description |
1879
+ |---|---|---|---|
1880
+ | `query.page` | `integer` | no | Page number (1-indexed) default `1` |
1881
+ | `query.limit` | `integer` | no | Items per page (max 200) default `50` |
1882
+ | `query.email` | `string \| null` | no | Filter by work email (exact match) |
1883
+ | `query.list_id` | `integer \| null` | no | Filter by list ID |
1884
+ | `query.name` | `string \| null` | no | Filter by first or last name (partial match) |
1885
+ | `query.job_title` | `string \| null` | no | Filter by job title (partial match) |
1886
+ | `query.seniority_level` | `string \| null` | no | Filter by seniority level (exact match) |
1887
+ | `query.company_name` | `string \| null` | no | Filter by company name (partial match) |
1888
+ | `query.company_id` | `integer \| null` | no | Filter by company ID |
1889
+ | `query.country` | `string \| null` | no | Filter by country (exact match) |
1890
+ | `query.state` | `string \| null` | no | Filter by state (exact match) |
1891
+ | `query.city` | `string \| null` | no | Filter by city (partial match) |
1892
+ | `query.job_department` | `string \| null` | no | Filter by job department (partial match) |
1893
+ | `query.industry` | `string \| null` | no | Filter by company industry (partial match) |
1894
+ | `query.include_custom_fields` | `boolean` | no | When true, each contact includes a `custom_fields` object of custom column values keyed by column slug. Default false keeps the legacy response shape and adds no extra query. default `false` |
1895
+
1896
+ **Returns** `ApiResponse_list_ContactListItem__`: the envelope `{ data: Array<ContactListItem>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1897
+
1898
+ Other envelope fields: `pagination` (PaginationMeta).
1899
+
1900
+ `ContactListItem` fields:
1901
+
1902
+ | Field | Type | Required | Description |
1903
+ |---|---|---|---|
1904
+ | `city` | `string \| null` | no | |
1905
+ | `company_id` | `integer \| null` | no | |
1906
+ | `country` | `string \| null` | no | |
1907
+ | `custom_fields` | `Record<string, string \| null> \| null` | no | |
1908
+ | `direct_phone` | `string \| null` | no | |
1909
+ | `first_name` | `string \| null` | no | |
1910
+ | `id` | `integer \| null` | no | |
1911
+ | `job_department` | `string \| null` | no | |
1912
+ | `job_title` | `string \| null` | no | |
1913
+ | `last_name` | `string \| null` | no | |
1914
+ | `linkedin_url` | `string \| null` | no | |
1915
+ | `mobile_phone` | `string \| null` | no | |
1916
+ | `owner_id` | `string \| null` | no | |
1917
+ | `owner_name` | `string \| null` | no | |
1918
+ | `seniority_level` | `string \| null` | no | |
1919
+ | `state` | `string \| null` | no | |
1920
+ | `work_email` | `string \| null` | no | |
1921
+
1922
+ **Example**
1923
+
1924
+ ```ts
1925
+ const result = await g8.api.contacts.listContacts();
1926
+ ```
1927
+
1928
+ ---
1929
+
1930
+ <a id="op-listcustomcolumndefinitions"></a>
1931
+
1932
+ ### `g8.api.contacts.listCustomColumnDefinitions(input?)`
1933
+
1934
+ **List Custom Column Definitions**
1935
+
1936
+ - HTTP: `GET /api/v1/contacts/custom-column-definitions`
1937
+ - operationId: `list_custom_column_definitions_contacts_custom_column_definitions_get` (also callable as `g8.api.call("list_custom_column_definitions_contacts_custom_column_definitions_get", input)`)
1938
+ - Tier: `read`: reads data; safe to call and to retry
1939
+ - API-key scope: `contacts:read`
1940
+
1941
+ The org's custom columns as `{column_id, name}` pairs.
1942
+
1943
+ The flat form: enough to build a field picker, and the source of the ids
1944
+ other calls accept.
1945
+
1946
+ **Input**
1947
+
1948
+ | Field | Type | Required | Description |
1949
+ |---|---|---|---|
1950
+ | `query.entity_type` | `string` | no | `contact` or `company`. Anything else is refused. default `"contact"` |
1951
+
1952
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1953
+
1954
+ Other envelope fields: `pagination` (PaginationMeta).
1955
+
1956
+ `CrmCollectionPayload` fields:
1957
+
1958
+ | Field | Type | Required | Description |
1959
+ |---|---|---|---|
1960
+ | `items` | `Array<unknown>` | no | |
1961
+
1962
+ **Example**
1963
+
1964
+ ```ts
1965
+ const result = await g8.api.contacts.listCustomColumnDefinitions();
1966
+ ```
1967
+
1968
+ ---
1969
+
1970
+ <a id="op-listduplicatedetectionruns"></a>
1971
+
1972
+ ### `g8.api.contacts.listDuplicateDetectionRuns(input?)`
1973
+
1974
+ **List Duplicate Detection Runs**
1975
+
1976
+ - HTTP: `GET /api/v1/duplicates/detection/runs`
1977
+ - operationId: `list_duplicate_detection_runs_duplicates_detection_runs_get` (also callable as `g8.api.call("list_duplicate_detection_runs_duplicates_detection_runs_get", input)`)
1978
+ - Tier: `read`: reads data; safe to call and to retry
1979
+ - API-key scope: `contacts:read`
1980
+
1981
+ Recent duplicate-detection runs - when the last check ran and what it found.
1982
+
1983
+ **Input**
1984
+
1985
+ | Field | Type | Required | Description |
1986
+ |---|---|---|---|
1987
+ | `query.entity_type` | `"contact" \| "company" \| "deal" \| null` | no | Only runs for this record type. |
1988
+ | `query.limit` | `integer` | no | How many runs, newest first. default `10` |
1989
+
1990
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1991
+
1992
+ Other envelope fields: `pagination` (PaginationMeta).
1993
+
1994
+ `CrmCollectionPayload` fields:
1995
+
1996
+ | Field | Type | Required | Description |
1997
+ |---|---|---|---|
1998
+ | `items` | `Array<unknown>` | no | |
1999
+
2000
+ **Example**
2001
+
2002
+ ```ts
2003
+ const result = await g8.api.contacts.listDuplicateDetectionRuns();
2004
+ ```
2005
+
2006
+ ---
2007
+
2008
+ <a id="op-listrecordworkflowexecutions"></a>
2009
+
2010
+ ### `g8.api.contacts.listRecordWorkflowExecutions(input)`
2011
+
2012
+ **List Record Workflow Executions**
2013
+
2014
+ - HTTP: `GET /api/v1/contacts/workflow-executions`
2015
+ - operationId: `list_record_workflow_executions_contacts_workflow_executions_get` (also callable as `g8.api.call("list_record_workflow_executions_contacts_workflow_executions_get", input)`)
2016
+ - Tier: `read`: reads data; safe to call and to retry
2017
+ - API-key scope: `contacts:read`
2018
+
2019
+ Workflow runs for one row of a list, newest first.
2020
+
2021
+ **Input**
2022
+
2023
+ | Field | Type | Required | Description |
2024
+ |---|---|---|---|
2025
+ | `query.list_id` | `integer` | yes | The list the row belongs to. |
2026
+ | `query.record_id` | `integer` | yes | The row (contact) id. |
2027
+ | `query.workflow_id` | `string \| null` | no | Only runs of this workflow. |
2028
+ | `query.status` | `string \| null` | no | Only this status. |
2029
+ | `query.include_events` | `boolean` | no | Include each run's step events. default `false` |
2030
+
2031
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2032
+
2033
+ Other envelope fields: `pagination` (PaginationMeta).
2034
+
2035
+ `CrmCollectionPayload` fields:
2036
+
2037
+ | Field | Type | Required | Description |
2038
+ |---|---|---|---|
2039
+ | `items` | `Array<unknown>` | no | |
2040
+
2041
+ **Example**
2042
+
2043
+ ```ts
2044
+ const result = await g8.api.contacts.listRecordWorkflowExecutions({ query: { list_id: 123, record_id: 123 } });
2045
+ ```
2046
+
2047
+ ---
2048
+
2049
+ <a id="op-listsearchablefields"></a>
2050
+
2051
+ ### `g8.api.contacts.listSearchableFields(input?)`
2052
+
2053
+ **List Searchable Fields**
2054
+
2055
+ - HTTP: `GET /api/v1/contacts/searchable-fields`
2056
+ - operationId: `list_searchable_fields_contacts_searchable_fields_get` (also callable as `g8.api.call("list_searchable_fields_contacts_searchable_fields_get", input)`)
2057
+ - Tier: `read`: reads data; safe to call and to retry
2058
+ - API-key scope: `contacts:read`
2059
+
2060
+ Which fields can be searched, and what each one COSTS.
2061
+
2062
+ Every entry carries a `tier` derived from the org's real indexes -
2063
+ `fast`, `text_search` or `full_scan` - plus the operators that column's
2064
+ live type supports. Index coverage is per-org, so this is the only honest
2065
+ way to know a custom-column search is a full table scan before running it.
2066
+
2067
+ **Input**
2068
+
2069
+ | Field | Type | Required | Description |
2070
+ |---|---|---|---|
2071
+ | `query.entity_type` | `string` | no | `contact` or `company`. Anything else is refused. default `"contact"` |
2072
+
2073
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2074
+
2075
+ Other envelope fields: `pagination` (PaginationMeta).
2076
+
2077
+ `CrmCollectionPayload` fields:
2078
+
2079
+ | Field | Type | Required | Description |
2080
+ |---|---|---|---|
2081
+ | `items` | `Array<unknown>` | no | |
2082
+
2083
+ **Example**
2084
+
2085
+ ```ts
2086
+ const result = await g8.api.contacts.listSearchableFields();
2087
+ ```
2088
+
2089
+ ---
2090
+
2091
+ <a id="op-mergecontact"></a>
2092
+
2093
+ ### `g8.api.contacts.mergeContact(input)`
2094
+
2095
+ **Merge Contact**
2096
+
2097
+ - HTTP: `POST /api/v1/contacts/{contact_id}/merge`
2098
+ - operationId: `merge_contact_contacts__contact_id__merge_post` (also callable as `g8.api.call("merge_contact_contacts__contact_id__merge_post", input)`)
2099
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
2100
+ - API-key scope: `contacts:delete`
2101
+
2102
+ Merge `secondary_id` INTO this contact. THE SECONDARY STOPS EXISTING.
2103
+
2104
+ Both contacts must be writable by the key; the handler checks both.
2105
+ Undo is one merge at a time via `POST /duplicates/undo-merge/{id}`.
2106
+
2107
+ **Input**
2108
+
2109
+ | Field | Type | Required | Description |
2110
+ |---|---|---|---|
2111
+ | `path.contact_id` | `integer` | yes | The contact that SURVIVES the merge. |
2112
+ | `body` | `MergeRecordRequest` | yes | Request body; fields below. |
2113
+
2114
+ Body fields (`MergeRecordRequest`):
2115
+
2116
+ | Field | Type | Required | Description |
2117
+ |---|---|---|---|
2118
+ | `body.secondary_id` | `integer` | yes | The record merged AWAY. |
2119
+ | `body.bulk_criterion` | `string \| null` | no | The bulk criterion, when `trigger` is `bulk_criterion`. |
2120
+ | `body.field_overrides` | `Array<MergeFieldOverride>` | no | Decide individual fields instead of the app's rules. |
2121
+ | `body.suggestion_id` | `string \| null` | no | The duplicate suggestion this merge acts on, if any. |
2122
+ | `body.trigger` | `"manual" \| "bulk_criterion"` | no | What prompted the merge. Recorded on the audit row. default `"manual"` |
2123
+
2124
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2125
+
2126
+ Other envelope fields: `pagination` (PaginationMeta).
2127
+
2128
+ **Example**
2129
+
2130
+ ```ts
2131
+ // destructive: deletes or archives data; confirm with a human before calling.
2132
+ const result = await g8.api.contacts.mergeContact({ path: { contact_id: 123 }, body: { secondary_id: 123 } });
2133
+ ```
2134
+
2135
+ ---
2136
+
2137
+ <a id="op-mergecontacttags"></a>
2138
+
2139
+ ### `g8.api.contacts.mergeContactTags(input)`
2140
+
2141
+ **Merge Contact Tags**
2142
+
2143
+ - HTTP: `POST /api/v1/contacts/tags/merge`
2144
+ - operationId: `merge_contact_tags_contacts_tags_merge_post` (also callable as `g8.api.call("merge_contact_tags_contacts_tags_merge_post", input)`)
2145
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2146
+ - API-key scope: `contacts:write`
2147
+
2148
+ Fold one or more tags into a target. The sources are removed.
2149
+
2150
+ No shadowing risk against `/{tag_id}`: that path has no POST, so the
2151
+ literal `merge` segment cannot be read as a tag id whatever the order.
2152
+
2153
+ **Input**
2154
+
2155
+ | Field | Type | Required | Description |
2156
+ |---|---|---|---|
2157
+ | `body` | `ContactTagMergeRequest` | yes | Request body; fields below. |
2158
+
2159
+ Body fields (`ContactTagMergeRequest`):
2160
+
2161
+ | Field | Type | Required | Description |
2162
+ |---|---|---|---|
2163
+ | `body.source_tag_ids` | `Array<string>` | yes | Tags to fold in. Removed on success. min items 1 |
2164
+ | `body.target_tag_id` | `string` | yes | Tag that survives and absorbs the assignments. |
2165
+
2166
+ **Returns** `ApiResponse_ContactTagWriteResult_`: the envelope `{ data: ContactTagWriteResult, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2167
+
2168
+ Other envelope fields: `pagination` (PaginationMeta).
2169
+
2170
+ **Example**
2171
+
2172
+ ```ts
2173
+ const result = await g8.api.contacts.mergeContactTags({ body: { source_tag_ids: ["id"], target_tag_id: "id" } });
2174
+ ```
2175
+
2176
+ ---
2177
+
2178
+ <a id="op-mergefilteredcontacts"></a>
2179
+
2180
+ ### `g8.api.contacts.mergeFilteredContacts(input)`
2181
+
2182
+ **Merge Filtered Contacts**
2183
+
2184
+ - HTTP: `POST /api/v1/contacts/merge-filtered`
2185
+ - operationId: `merge_filtered_contacts_contacts_merge_filtered_post` (also callable as `g8.api.call("merge_filtered_contacts_contacts_merge_filtered_post", input)`)
2186
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2187
+ - API-key scope: `contacts:write`
2188
+
2189
+ Add every contact matching a filter into `target_list_id`.
2190
+
2191
+ Despite the name this does NOT merge duplicate contacts together - it
2192
+ merges a SELECTION INTO A LIST. `/duplicates` is the surface that merges
2193
+ records.
2194
+
2195
+ A 409 means some contacts need a decision before they can be added; re-send
2196
+ with `conflict_resolution`. Blocked contacts are never added regardless.
2197
+
2198
+ **Input**
2199
+
2200
+ | Field | Type | Required | Description |
2201
+ |---|---|---|---|
2202
+ | `body` | `MergeFilteredRequest` | yes | Request body; fields below. |
2203
+ | `query.filterModel` | `string \| null` | no | Optional per-column filter JSON, applied alongside `filter`. |
2204
+ | `query.sortModel` | `string \| null` | no | Optional sort JSON. |
2205
+
2206
+ Body fields (`MergeFilteredRequest`):
2207
+
2208
+ | Field | Type | Required | Description |
2209
+ |---|---|---|---|
2210
+ | `body.target_list_id` | `integer` | yes | List the matching records are added to. |
2211
+ | `body.conflict_resolution` | `"add_all" \| "skip_all" \| "custom" \| null` | no | Required when retrying after a 409. `add_all` takes every warned record, `skip_all` takes none of them, `custom` takes the ids in `include_warned_ids`. Blocked records are excluded either way. |
2212
+ | `body.dynamic_column_mapping` | `Record<string, string>` | no | Source-column to target-column mapping for custom columns. |
2213
+ | `body.filter` | `Array<FilterCondition>` | no | Conditions selecting the source records. |
2214
+ | `body.include_warned_ids` | `Array<string> \| null` | no | With `conflict_resolution=custom`, the warned ids to include. |
2215
+ | `body.segmentFilter` | `SegmentFilterGroup \| null` | no | Advanced AND/OR filter tree. |
2216
+
2217
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2218
+
2219
+ Other envelope fields: `pagination` (PaginationMeta).
2220
+
2221
+ **Example**
2222
+
2223
+ ```ts
2224
+ const result = await g8.api.contacts.mergeFilteredContacts({ body: { target_list_id: 123 } });
2225
+ ```
2226
+
2227
+ ---
2228
+
2229
+ <a id="op-pauserecordworkflowexecution"></a>
2230
+
2231
+ ### `g8.api.contacts.pauseRecordWorkflowExecution(input)`
2232
+
2233
+ **Pause Record Workflow Execution**
2234
+
2235
+ - HTTP: `POST /api/v1/contacts/workflow-executions/{execution_id}/pause`
2236
+ - operationId: `pause_record_workflow_execution_contacts_workflow_executions__execution_id__pause_post` (also callable as `g8.api.call("pause_record_workflow_execution_contacts_workflow_executions__execution_id__pause_post", input)`)
2237
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2238
+ - API-key scope: `contacts:write`
2239
+
2240
+ Pause a running row workflow at its next step boundary.
2241
+
2242
+ **Input**
2243
+
2244
+ | Field | Type | Required | Description |
2245
+ |---|---|---|---|
2246
+ | `path.execution_id` | `string` | yes | Workflow execution id. |
2247
+
2248
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2249
+
2250
+ Other envelope fields: `pagination` (PaginationMeta).
2251
+
2252
+ **Example**
2253
+
2254
+ ```ts
2255
+ const result = await g8.api.contacts.pauseRecordWorkflowExecution({ path: { execution_id: "id" } });
2256
+ ```
2257
+
2258
+ ---
2259
+
2260
+ <a id="op-previewcontactmerge"></a>
2261
+
2262
+ ### `g8.api.contacts.previewContactMerge(input)`
2263
+
2264
+ **Preview Contact Merge**
2265
+
2266
+ - HTTP: `GET /api/v1/contacts/{contact_id}/merge/preview`
2267
+ - operationId: `preview_contact_merge_contacts__contact_id__merge_preview_get` (also callable as `g8.api.call("preview_contact_merge_contacts__contact_id__merge_preview_get", input)`)
2268
+ - Tier: `read`: reads data; safe to call and to retry
2269
+ - API-key scope: `contacts:read`
2270
+
2271
+ Side-by-side comparison and blocker check. Writes nothing.
2272
+
2273
+ **Input**
2274
+
2275
+ | Field | Type | Required | Description |
2276
+ |---|---|---|---|
2277
+ | `path.contact_id` | `integer` | yes | The contact that SURVIVES the merge. |
2278
+ | `query.secondary` | `integer` | yes | The contact that would be merged AWAY. |
2279
+
2280
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2281
+
2282
+ Other envelope fields: `pagination` (PaginationMeta).
2283
+
2284
+ **Example**
2285
+
2286
+ ```ts
2287
+ const result = await g8.api.contacts.previewContactMerge({ path: { contact_id: 123 }, query: { secondary: 1 } });
2288
+ ```
2289
+
2290
+ ---
2291
+
2292
+ <a id="op-previewdetectionrule"></a>
2293
+
2294
+ ### `g8.api.contacts.previewDetectionRule(input)`
2295
+
2296
+ **Preview Detection Rule**
2297
+
2298
+ - HTTP: `POST /api/v1/duplicates/settings/preview-detection-rule`
2299
+ - operationId: `preview_detection_rule_duplicates_settings_preview_detection_rule_post` (also callable as `g8.api.call("preview_detection_rule_duplicates_settings_preview_detection_rule_post", input)`)
2300
+ - Tier: `read`: reads data; safe to call and to retry
2301
+ - API-key scope: `contacts:read`
2302
+
2303
+ Dry-run a duplicate-detection rule. Writes nothing.
2304
+
2305
+ Returns the pair count the rule would match plus a small sample, which is
2306
+ the only way to size a rule before auto-merge acts on it. A POST because
2307
+ the rule is a body; tiered a read so a read-only key can check a rule
2308
+ before someone saves it.
2309
+
2310
+ **Input**
2311
+
2312
+ | Field | Type | Required | Description |
2313
+ |---|---|---|---|
2314
+ | `body` | `PreviewDetectionRuleRequest` | yes | Request body; fields below. |
2315
+
2316
+ Body fields (`PreviewDetectionRuleRequest`):
2317
+
2318
+ | Field | Type | Required | Description |
2319
+ |---|---|---|---|
2320
+ | `body.entity_type` | `"contact" \| "company" \| "deal"` | yes | Object the rule matches on. |
2321
+ | `body.field` | `string` | yes | Column the rule compares. |
2322
+ | `body.match_mode` | `"exact" \| "normalized" \| "fuzzy_levenshtein" \| "domain_match" \| "phone_e164" \| "linkedin_handle"` | yes | How two values are considered equal. |
2323
+ | `body.rule_name` | `string` | yes | Name for the rule being previewed. |
2324
+ | `body.template` | `string` | yes | Platform rule template the rule is built from. |
2325
+ | `body.confidence_bucket` | `"high" \| "medium" \| "low" \| null` | no | Override the default confidence bucket. |
2326
+ | `body.score` | `integer \| null` | no | Override the platform default score for this rule. |
2327
+
2328
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2329
+
2330
+ Other envelope fields: `pagination` (PaginationMeta).
2331
+
2332
+ **Example**
2333
+
2334
+ ```ts
2335
+ const result = await g8.api.contacts.previewDetectionRule({
2336
+ body: {
2337
+ entity_type: "contact",
2338
+ field: "example",
2339
+ match_mode: "exact",
2340
+ rule_name: "Example",
2341
+ template: "example",
2342
+ },
2343
+ });
2344
+ ```
2345
+
2346
+ ---
2347
+
2348
+ <a id="op-regeneratecontactdocument"></a>
2349
+
2350
+ ### `g8.api.contacts.regenerateContactDocument(input)`
2351
+
2352
+ **Regenerate Contact Document**
2353
+
2354
+ - HTTP: `POST /api/v1/contacts/{contact_id}/documents/types/{doc_type}/regenerate`
2355
+ - operationId: `regenerate_contact_document_contacts__contact_id__documents_types__doc_type__regenerate_post` (also callable as `g8.api.call("regenerate_contact_document_contacts__contact_id__documents_types__doc_type__regenerate_post", input)`)
2356
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
2357
+ - API-key scope: `enrichment:run`
2358
+
2359
+ Throw away this document and generate it again. SPENDS CREDITS.
2360
+
2361
+ **Input**
2362
+
2363
+ | Field | Type | Required | Description |
2364
+ |---|---|---|---|
2365
+ | `path.contact_id` | `integer` | yes | Contact id. |
2366
+ | `path.doc_type` | `string` | yes | Document type. |
2367
+
2368
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2369
+
2370
+ Other envelope fields: `pagination` (PaginationMeta).
2371
+
2372
+ **Example**
2373
+
2374
+ ```ts
2375
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
2376
+ const result = await g8.api.contacts.regenerateContactDocument({ path: { contact_id: 123, doc_type: "example" } });
2377
+ ```
2378
+
2379
+ ---
2380
+
2381
+ <a id="op-resumerecordworkflowexecution"></a>
2382
+
2383
+ ### `g8.api.contacts.resumeRecordWorkflowExecution(input)`
2384
+
2385
+ **Resume Record Workflow Execution**
2386
+
2387
+ - HTTP: `POST /api/v1/contacts/workflow-executions/{execution_id}/resume`
2388
+ - operationId: `resume_record_workflow_execution_contacts_workflow_executions__execution_id__resume_post` (also callable as `g8.api.call("resume_record_workflow_execution_contacts_workflow_executions__execution_id__resume_post", input)`)
2389
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2390
+ - API-key scope: `contacts:write`
2391
+
2392
+ Resume a paused row workflow.
2393
+
2394
+ **Input**
2395
+
2396
+ | Field | Type | Required | Description |
2397
+ |---|---|---|---|
2398
+ | `path.execution_id` | `string` | yes | Workflow execution id. |
2399
+
2400
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2401
+
2402
+ Other envelope fields: `pagination` (PaginationMeta).
2403
+
2404
+ **Example**
2405
+
2406
+ ```ts
2407
+ const result = await g8.api.contacts.resumeRecordWorkflowExecution({ path: { execution_id: "id" } });
2408
+ ```
2409
+
2410
+ ---
2411
+
2412
+ <a id="op-runduplicatedetection"></a>
2413
+
2414
+ ### `g8.api.contacts.runDuplicateDetection(input)`
2415
+
2416
+ **Run Duplicate Detection**
2417
+
2418
+ - HTTP: `POST /api/v1/duplicates/detection/run`
2419
+ - operationId: `run_duplicate_detection_duplicates_detection_run_post` (also callable as `g8.api.call("run_duplicate_detection_duplicates_detection_run_post", input)`)
2420
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2421
+ - API-key scope: `contacts:write`
2422
+
2423
+ Scan the org for duplicates of one record type now. Admin-only.
2424
+
2425
+ Rate-limited by the app to once per 15 minutes per record type (429 with
2426
+ the wait). Finds suggestions only - nothing is merged.
2427
+
2428
+ **Input**
2429
+
2430
+ | Field | Type | Required | Description |
2431
+ |---|---|---|---|
2432
+ | `body` | `RunDetectionRequest` | yes | Request body; fields below. |
2433
+
2434
+ Body fields (`RunDetectionRequest`):
2435
+
2436
+ | Field | Type | Required | Description |
2437
+ |---|---|---|---|
2438
+ | `body.entity_type` | `"contact" \| "company" \| "deal"` | yes | What to scan. |
2439
+
2440
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2441
+
2442
+ Other envelope fields: `pagination` (PaginationMeta).
2443
+
2444
+ **Example**
2445
+
2446
+ ```ts
2447
+ const result = await g8.api.contacts.runDuplicateDetection({ body: { entity_type: "contact" } });
2448
+ ```
2449
+
2450
+ ---
2451
+
2452
+ <a id="op-runrecordworkflow"></a>
2453
+
2454
+ ### `g8.api.contacts.runRecordWorkflow(input)`
2455
+
2456
+ **Run Record Workflow**
2457
+
2458
+ - HTTP: `POST /api/v1/contacts/workflow-executions/run`
2459
+ - operationId: `run_record_workflow_contacts_workflow_executions_run_post` (also callable as `g8.api.call("run_record_workflow_contacts_workflow_executions_run_post", input)`)
2460
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
2461
+ - API-key scope: `enrichment:run`
2462
+
2463
+ Run a list workflow over rows. SPENDS CREDITS when its steps enrich or call a model.
2464
+
2465
+ `run_mode=all` runs over every row in the list, so the spend is bounded
2466
+ by the list, not the request.
2467
+
2468
+ **Input**
2469
+
2470
+ | Field | Type | Required | Description |
2471
+ |---|---|---|---|
2472
+ | `body` | `RunRecordWorkflowRequest` | yes | Request body; fields below. |
2473
+
2474
+ Body fields (`RunRecordWorkflowRequest`):
2475
+
2476
+ | Field | Type | Required | Description |
2477
+ |---|---|---|---|
2478
+ | `body.list_id` | `integer` | yes | List (workbench) the workflow belongs to. |
2479
+ | `body.record_ids` | `Array<integer>` | yes | Rows to run it on, for `selected`. |
2480
+ | `body.workflow_id` | `string` | yes | Workflow to run. |
2481
+ | `body.run_mode` | `"selected" \| "filtered" \| "all"` | no | Which rows to run on. default `"selected"` |
2482
+
2483
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2484
+
2485
+ Other envelope fields: `pagination` (PaginationMeta).
2486
+
2487
+ **Example**
2488
+
2489
+ ```ts
2490
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
2491
+ const result = await g8.api.contacts.runRecordWorkflow({ body: { list_id: 123, record_ids: [123], workflow_id: "id" } });
2492
+ ```
2493
+
2494
+ ---
2495
+
2496
+ <a id="op-saveskillresulttocontact"></a>
2497
+
2498
+ ### `g8.api.contacts.saveSkillResultToContact(input)`
2499
+
2500
+ **Save Skill Result To Contact**
2501
+
2502
+ - HTTP: `POST /api/v1/contacts/{contact_id}/documents/from-skill`
2503
+ - operationId: `save_skill_result_to_contact_contacts__contact_id__documents_from_skill_post` (also callable as `g8.api.call("save_skill_result_to_contact_contacts__contact_id__documents_from_skill_post", input)`)
2504
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2505
+ - API-key scope: `contacts:write`
2506
+
2507
+ Store a skill run's output on this contact as a document.
2508
+
2509
+ **Input**
2510
+
2511
+ | Field | Type | Required | Description |
2512
+ |---|---|---|---|
2513
+ | `path.contact_id` | `integer` | yes | Contact primary key. |
2514
+ | `body` | `SaveSkillResultRequest` | yes | Request body; fields below. |
2515
+
2516
+ Body fields (`SaveSkillResultRequest`):
2517
+
2518
+ | Field | Type | Required | Description |
2519
+ |---|---|---|---|
2520
+ | `body.action_name` | `string` | yes | Action within that execution. |
2521
+ | `body.content` | `string` | yes | Document body to store. |
2522
+ | `body.execution_id` | `string` | yes | The skill execution that produced the content. |
2523
+
2524
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2525
+
2526
+ Other envelope fields: `pagination` (PaginationMeta).
2527
+
2528
+ **Example**
2529
+
2530
+ ```ts
2531
+ const result = await g8.api.contacts.saveSkillResultToContact({
2532
+ path: { contact_id: 123 },
2533
+ body: { action_name: "Example", content: "example", execution_id: "id" },
2534
+ });
2535
+ ```
2536
+
2537
+ ---
2538
+
2539
+ <a id="op-triggerautomerge"></a>
2540
+
2541
+ ### `g8.api.contacts.triggerAutoMerge(input)`
2542
+
2543
+ **Trigger Auto Merge**
2544
+
2545
+ - HTTP: `POST /api/v1/duplicates/auto-merge`
2546
+ - operationId: `trigger_auto_merge_duplicates_auto_merge_post` (also callable as `g8.api.call("trigger_auto_merge_duplicates_auto_merge_post", input)`)
2547
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
2548
+ - API-key scope: `contacts:delete`
2549
+
2550
+ Run auto-merge once. RECORDS ARE DESTROYED.
2551
+
2552
+ Each merge removes one record and moves its data onto the survivor. The
2553
+ only way back is `POST /duplicates/undo-merge/{merge_history_id}`, one
2554
+ merge at a time. Send `dry_run=true` first.
2555
+
2556
+ A 200 does NOT by itself mean anything merged: if the org has auto-merge
2557
+ disabled or is in shadow mode the response says so instead of failing,
2558
+ which is the app's behaviour and is preserved here. Read the body.
2559
+
2560
+ **Input**
2561
+
2562
+ | Field | Type | Required | Description |
2563
+ |---|---|---|---|
2564
+ | `body` | `AutoMergeRequest` | yes | Request body; fields below. |
2565
+
2566
+ Body fields (`AutoMergeRequest`):
2567
+
2568
+ | Field | Type | Required | Description |
2569
+ |---|---|---|---|
2570
+ | `body.entity_type` | `"contact" \| "company"` | yes | Object to merge. |
2571
+ | `body.dry_run` | `boolean` | no | Report what would merge without merging it. default `false` |
2572
+
2573
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2574
+
2575
+ Other envelope fields: `pagination` (PaginationMeta).
2576
+
2577
+ **Example**
2578
+
2579
+ ```ts
2580
+ // destructive: deletes or archives data; confirm with a human before calling.
2581
+ const result = await g8.api.contacts.triggerAutoMerge({ body: { entity_type: "contact" } });
2582
+ ```
2583
+
2584
+ ---
2585
+
2586
+ <a id="op-unassigncontacttags"></a>
2587
+
2588
+ ### `g8.api.contacts.unassignContactTags(input)`
2589
+
2590
+ **Unassign Contact Tags**
2591
+
2592
+ - HTTP: `POST /api/v1/contacts/tags/unassign`
2593
+ - operationId: `unassign_contact_tags_contacts_tags_unassign_post` (also callable as `g8.api.call("unassign_contact_tags_contacts_tags_unassign_post", input)`)
2594
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2595
+ - API-key scope: `contacts:write`
2596
+
2597
+ Remove tags from contacts. The tag definitions survive.
2598
+
2599
+ **Input**
2600
+
2601
+ | Field | Type | Required | Description |
2602
+ |---|---|---|---|
2603
+ | `body` | `ContactTagAssignRequest` | yes | Request body; fields below. |
2604
+
2605
+ Body fields (`ContactTagAssignRequest`):
2606
+
2607
+ | Field | Type | Required | Description |
2608
+ |---|---|---|---|
2609
+ | `body.tag_ids` | `Array<string>` | yes | min items 1 |
2610
+ | `body.contact_ids` | `Array<integer>` | no | Contacts to tag. |
2611
+
2612
+ **Returns** `ApiResponse_ContactTagWriteResult_`: the envelope `{ data: ContactTagWriteResult, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2613
+
2614
+ Other envelope fields: `pagination` (PaginationMeta).
2615
+
2616
+ **Example**
2617
+
2618
+ ```ts
2619
+ const result = await g8.api.contacts.unassignContactTags({ body: { tag_ids: ["id"] } });
2620
+ ```
2621
+
2622
+ ---
2623
+
2624
+ <a id="op-unlockcontactinfo"></a>
2625
+
2626
+ ### `g8.api.contacts.unlockContactInfo(input)`
2627
+
2628
+ **Unlock Contact Info**
2629
+
2630
+ - HTTP: `POST /api/v1/contacts/unlock-info`
2631
+ - operationId: `unlock_contact_info_contacts_unlock_info_post` (also callable as `g8.api.call("unlock_contact_info_contacts_unlock_info_post", input)`)
2632
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
2633
+ - API-key scope: `enrichment:run`
2634
+
2635
+ Reveal withheld contact details. CHARGES CREDITS.
2636
+
2637
+ Returns `credits_charged`. Contacts already unlocked are not charged
2638
+ again, so re-sending the same ids is safe - but `all_matching` resolves an
2639
+ unbounded selection, and every newly-unlocked contact in it is billed.
2640
+
2641
+ **Input**
2642
+
2643
+ | Field | Type | Required | Description |
2644
+ |---|---|---|---|
2645
+ | `body` | `UnlockContactInfoRequest` | yes | Request body; fields below. |
2646
+ | `query.filterModel` | `string \| null` | no | Per-column filter JSON, resolved against `list_id`. |
2647
+
2648
+ Body fields (`UnlockContactInfoRequest`):
2649
+
2650
+ | Field | Type | Required | Description |
2651
+ |---|---|---|---|
2652
+ | `body.allMatching` | `boolean` | no | Resolve the complete matching set server-side. default `false` |
2653
+ | `body.contact_ids` | `Array<integer> \| null` | no | Contacts to unlock (max 1000). max items 1000 |
2654
+ | `body.filterModel` | `Record<string, unknown>` | no | Per-column filters. |
2655
+ | `body.list_id` | `integer \| null` | no | Unlock the contacts in this list. |
2656
+ | `body.segmentFilter` | `SegmentFilterGroup \| null` | no | Advanced AND/OR filter tree. |
2657
+
2658
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2659
+
2660
+ Other envelope fields: `pagination` (PaginationMeta).
2661
+
2662
+ **Example**
2663
+
2664
+ ```ts
2665
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
2666
+ const result = await g8.api.contacts.unlockContactInfo({ body: {} });
2667
+ ```
2668
+
2669
+ ---
2670
+
2671
+ <a id="op-updatecontact"></a>
2672
+
2673
+ ### `g8.api.contacts.updateContact(input)`
2674
+
2675
+ **Update Contact**
2676
+
2677
+ - HTTP: `PATCH /api/v1/contacts/{contact_id}`
2678
+ - operationId: `update_contact_contacts__contact_id__patch` (also callable as `g8.api.call("update_contact_contacts__contact_id__patch", input)`)
2679
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2680
+ - API-key scope: `contacts:write`
2681
+ - ★ Hand-written: [`g8.contacts.update()`](../sdk-clients.md#g8-contacts-update)
2682
+
2683
+ Update a contact's fields (partial update).
2684
+
2685
+ Company link (both optional; a contact may have no company): ``company_id``
2686
+ attaches an EXISTING company (mashup_companies.id) directly; ``company_domain``
2687
+ resolves-or-creates a company from its domain. ``company_id`` wins if both
2688
+ are given. Every other field is a plain column update. Provide any subset;
2689
+ at least one field (plain or company) is required.
2690
+
2691
+ **Input**
2692
+
2693
+ | Field | Type | Required | Description |
2694
+ |---|---|---|---|
2695
+ | `path.contact_id` | `integer` | yes | Contact ID |
2696
+ | `body` | `ContactUpdateRequest` | yes | Request body; fields below. |
2697
+
2698
+ Body fields (`ContactUpdateRequest`):
2699
+
2700
+ | Field | Type | Required | Description |
2701
+ |---|---|---|---|
2702
+ | `body.city` | `string \| null` | no | |
2703
+ | `body.company_domain` | `string \| null` | no | |
2704
+ | `body.company_id` | `integer \| null` | no | |
2705
+ | `body.country` | `string \| null` | no | |
2706
+ | `body.direct_phone` | `string \| null` | no | |
2707
+ | `body.first_name` | `string \| null` | no | |
2708
+ | `body.job_department` | `string \| null` | no | |
2709
+ | `body.job_title` | `string \| null` | no | |
2710
+ | `body.last_name` | `string \| null` | no | |
2711
+ | `body.linkedin_url` | `string \| null` | no | |
2712
+ | `body.mobile_phone` | `string \| null` | no | |
2713
+ | `body.seniority_level` | `string \| null` | no | |
2714
+ | `body.state` | `string \| null` | no | |
2715
+ | `body.work_email` | `string \| null` | no | |
2716
+
2717
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2718
+
2719
+ Other envelope fields: `pagination` (PaginationMeta).
2720
+
2721
+ **Example**
2722
+
2723
+ ```ts
2724
+ const result = await g8.api.contacts.updateContact({ path: { contact_id: 123 }, body: {} });
2725
+ ```
2726
+
2727
+ ---
2728
+
2729
+ <a id="op-updatecontactdocument"></a>
2730
+
2731
+ ### `g8.api.contacts.updateContactDocument(input)`
2732
+
2733
+ **Update Contact Document**
2734
+
2735
+ - HTTP: `PUT /api/v1/contacts/{contact_id}/documents/{document_id}`
2736
+ - operationId: `update_contact_document_contacts__contact_id__documents__document_id__put` (also callable as `g8.api.call("update_contact_document_contacts__contact_id__documents__document_id__put", input)`)
2737
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2738
+ - API-key scope: `contacts:write`
2739
+
2740
+ Edit a generated document's content or structured data by hand.
2741
+
2742
+ **Input**
2743
+
2744
+ | Field | Type | Required | Description |
2745
+ |---|---|---|---|
2746
+ | `path.contact_id` | `integer` | yes | Contact id. |
2747
+ | `path.document_id` | `string` | yes | Document id. |
2748
+ | `body` | `ContactDocumentUpdateRequest` | yes | Request body; fields below. |
2749
+
2750
+ Body fields (`ContactDocumentUpdateRequest`):
2751
+
2752
+ | Field | Type | Required | Description |
2753
+ |---|---|---|---|
2754
+ | `body.content` | `string \| null` | no | Replacement document body. |
2755
+ | `body.structured_data` | `Record<string, unknown> \| null` | no | Replacement structured payload. |
2756
+
2757
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2758
+
2759
+ Other envelope fields: `pagination` (PaginationMeta).
2760
+
2761
+ **Example**
2762
+
2763
+ ```ts
2764
+ const result = await g8.api.contacts.updateContactDocument({ path: { contact_id: 123, document_id: "id" }, body: {} });
2765
+ ```
2766
+
2767
+ ---
2768
+
2769
+ <a id="op-updatecontacttag"></a>
2770
+
2771
+ ### `g8.api.contacts.updateContactTag(input)`
2772
+
2773
+ **Update Contact Tag**
2774
+
2775
+ - HTTP: `PATCH /api/v1/contacts/tags/{tag_id}`
2776
+ - operationId: `update_contact_tag_contacts_tags__tag_id__patch` (also callable as `g8.api.call("update_contact_tag_contacts_tags__tag_id__patch", input)`)
2777
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2778
+ - API-key scope: `contacts:write`
2779
+
2780
+ Rename, recolour, redescribe or archive a tag. Omitted fields stay.
2781
+
2782
+ **Input**
2783
+
2784
+ | Field | Type | Required | Description |
2785
+ |---|---|---|---|
2786
+ | `path.tag_id` | `string` | yes | Tag id. |
2787
+ | `body` | `ContactTagUpdateRequest` | yes | Request body; fields below. |
2788
+
2789
+ Body fields (`ContactTagUpdateRequest`):
2790
+
2791
+ | Field | Type | Required | Description |
2792
+ |---|---|---|---|
2793
+ | `body.archived` | `boolean \| null` | no | Archive without deleting. |
2794
+ | `body.color` | `string \| null` | no | pattern `^#[0-9A-Fa-f]{6}$` |
2795
+ | `body.description` | `string \| null` | no | max length 200 |
2796
+ | `body.name` | `string \| null` | no | min length 1, max length 50 |
2797
+
2798
+ **Returns** `ApiResponse_ContactTag_`: the envelope `{ data: ContactTag, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2799
+
2800
+ Other envelope fields: `pagination` (PaginationMeta).
2801
+
2802
+ `ContactTag` fields:
2803
+
2804
+ | Field | Type | Required | Description |
2805
+ |---|---|---|---|
2806
+ | `archived` | `boolean \| null` | no | |
2807
+ | `color` | `string \| null` | no | |
2808
+ | `contact_count` | `integer \| null` | no | Contacts currently carrying the tag. |
2809
+ | `description` | `string \| null` | no | |
2810
+ | `id` | `string \| null` | no | |
2811
+ | `name` | `string \| null` | no | |
2812
+
2813
+ **Example**
2814
+
2815
+ ```ts
2816
+ const result = await g8.api.contacts.updateContactTag({ path: { tag_id: "id" }, body: {} });
2817
+ ```
2818
+
2819
+ ---
2820
+
2821
+ <a id="op-updateduplicatesettings"></a>
2822
+
2823
+ ### `g8.api.contacts.updateDuplicateSettings(input)`
2824
+
2825
+ **Update Duplicate Settings**
2826
+
2827
+ - HTTP: `PUT /api/v1/duplicates/settings`
2828
+ - operationId: `update_duplicate_settings_duplicates_settings_put` (also callable as `g8.api.call("update_duplicate_settings_duplicates_settings_put", input)`)
2829
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2830
+ - API-key scope: `contacts:write`
2831
+
2832
+ REPLACE the org's merge settings wholesale. Partial updates are not supported.
2833
+
2834
+ Read with `GET /duplicates/settings`, change what you need, and send the
2835
+ whole tree back - a missing section falls back to the platform default.
2836
+
2837
+ **Input**
2838
+
2839
+ | Field | Type | Required | Description |
2840
+ |---|---|---|---|
2841
+ | `body` | `Record<string, unknown>` | yes | Request body; fields below. |
2842
+
2843
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2844
+
2845
+ Other envelope fields: `pagination` (PaginationMeta).
2846
+
2847
+ **Example**
2848
+
2849
+ ```ts
2850
+ const result = await g8.api.contacts.updateDuplicateSettings({ body: {} });
2851
+ ```
2852
+
2853
+ ---
2854
+
2855
+ <a id="op-verifycontactemails"></a>
2856
+
2857
+ ### `g8.api.contacts.verifyContactEmails(input)`
2858
+
2859
+ **Verify Contact Emails**
2860
+
2861
+ - HTTP: `POST /api/v1/contacts/verify-email`
2862
+ - operationId: `verify_contact_emails_contacts_verify_email_post` (also callable as `g8.api.call("verify_contact_emails_contacts_verify_email_post", input)`)
2863
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
2864
+ - API-key scope: `enrichment:run`
2865
+
2866
+ Re-check deliverability for a batch of contacts. SPENDS CREDITS.
2867
+
2868
+ Synchronous: one call to the verification service, and the result is
2869
+ written back onto each contact. Capped at 1000 contacts - use
2870
+ `/contacts/verify-email/async` for a whole list.
2871
+
2872
+ Different from `POST /enrichment/verify-email`, which checks one arbitrary
2873
+ address and stores nothing.
2874
+
2875
+ **Input**
2876
+
2877
+ | Field | Type | Required | Description |
2878
+ |---|---|---|---|
2879
+ | `body` | `VerifyContactEmailRequest` | yes | Request body; fields below. |
2880
+ | `query.list_id` | `integer \| null` | no | Restrict a filtered selection to this list. |
2881
+ | `query.filterModel` | `string \| null` | no | Per-column filter JSON. With `list_id`, verifies every matching contact instead of the ids in the body. |
2882
+
2883
+ Body fields (`VerifyContactEmailRequest`):
2884
+
2885
+ | Field | Type | Required | Description |
2886
+ |---|---|---|---|
2887
+ | `body.contact_pks` | `Array<integer>` | no | Contact primary keys (max 1000). Empty verifies nothing. max items 1000 |
2888
+
2889
+ **Returns** `ApiResponse_CrmCollectionPayload_`: the envelope `{ data: CrmCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2890
+
2891
+ Other envelope fields: `pagination` (PaginationMeta).
2892
+
2893
+ `CrmCollectionPayload` fields:
2894
+
2895
+ | Field | Type | Required | Description |
2896
+ |---|---|---|---|
2897
+ | `items` | `Array<unknown>` | no | |
2898
+
2899
+ **Example**
2900
+
2901
+ ```ts
2902
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
2903
+ const result = await g8.api.contacts.verifyContactEmails({ body: {} });
2904
+ ```
2905
+
2906
+ ---
2907
+
2908
+ <a id="op-verifycontactemailsasync"></a>
2909
+
2910
+ ### `g8.api.contacts.verifyContactEmailsAsync(input)`
2911
+
2912
+ **Verify Contact Emails Async**
2913
+
2914
+ - HTTP: `POST /api/v1/contacts/verify-email/async`
2915
+ - operationId: `verify_contact_emails_async_contacts_verify_email_async_post` (also callable as `g8.api.call("verify_contact_emails_async_contacts_verify_email_async_post", input)`)
2916
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
2917
+ - API-key scope: `enrichment:run`
2918
+
2919
+ Queue verification for a whole list or filtered selection. SPENDS CREDITS.
2920
+
2921
+ Returns the number of contacts and addresses ACCEPTED, not verified - the
2922
+ results land on the contacts as the job runs. `all_matching` resolves the
2923
+ selection server-side, so the cost is not bounded by anything in the
2924
+ request; send the filter you actually mean.
2925
+
2926
+ **Input**
2927
+
2928
+ | Field | Type | Required | Description |
2929
+ |---|---|---|---|
2930
+ | `body` | `VerifyContactEmailAsyncRequest` | yes | Request body; fields below. |
2931
+
2932
+ Body fields (`VerifyContactEmailAsyncRequest`):
2933
+
2934
+ | Field | Type | Required | Description |
2935
+ |---|---|---|---|
2936
+ | `body.allMatching` | `boolean` | no | Resolve the complete matching set server-side, not just a page. default `false` |
2937
+ | `body.filterModel` | `Record<string, unknown>` | no | Per-column filters, keyed by column name. |
2938
+ | `body.list_id` | `integer \| null` | no | Restrict the selection to this list. |
2939
+ | `body.segmentFilter` | `SegmentFilterGroup \| null` | no | Advanced cross-column AND/OR filter tree. |
2940
+
2941
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2942
+
2943
+ Other envelope fields: `pagination` (PaginationMeta).
2944
+
2945
+ **Example**
2946
+
2947
+ ```ts
2948
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
2949
+ const result = await g8.api.contacts.verifyContactEmailsAsync({ body: {} });
2950
+ ```
2951
+
2952
+ ---
2953
+
2954
+ <a id="op-withdrawcontactsfromsequences"></a>
2955
+
2956
+ ### `g8.api.contacts.withdrawContactsFromSequences(input)`
2957
+
2958
+ **Withdraw Contacts From Sequences**
2959
+
2960
+ - HTTP: `POST /api/v1/contacts/withdraw-from-sequences`
2961
+ - operationId: `withdraw_contacts_from_sequences_contacts_withdraw_from_sequences_post` (also callable as `g8.api.call("withdraw_contacts_from_sequences_contacts_withdraw_from_sequences_post", input)`)
2962
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2963
+ - API-key scope: `contacts:write`
2964
+
2965
+ Take contacts OUT of a sequence. They stop receiving its steps.
2966
+
2967
+ `remove_all=true` withdraws them from EVERY sequence they are enrolled in
2968
+ and ignores `sequence_id` - the wider blast radius of the two, and never
2969
+ the default.
2970
+
2971
+ `response` is REQUIRED by the app handler rather than decoration: it sets
2972
+ a status on it for the partial-withdrawal case, so omitting it is an
2973
+ AttributeError on every call.
2974
+
2975
+ **Input**
2976
+
2977
+ | Field | Type | Required | Description |
2978
+ |---|---|---|---|
2979
+ | `body` | `WithdrawFromSequencesRequest` | yes | Request body; fields below. |
2980
+
2981
+ Body fields (`WithdrawFromSequencesRequest`):
2982
+
2983
+ | Field | Type | Required | Description |
2984
+ |---|---|---|---|
2985
+ | `body.contact_ids` | `Array<integer>` | no | Contact primary keys to withdraw (max 5000). max items 5000 |
2986
+ | `body.remove_all` | `boolean` | no | Withdraw from EVERY enrolled sequence. Ignores `sequence_id`. default `false` |
2987
+ | `body.sequence_id` | `string \| null` | no | Sequence to withdraw from. Required unless `remove_all` is true. |
2988
+ | `body.source` | `string \| null` | no | Origin label recorded on the resulting event. default `"workflow"`, max length 64 |
2989
+ | `body.target_state` | `string \| null` | no | Terminal state to record: removed \| completed \| not_interested. default `"removed"` |
2990
+
2991
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2992
+
2993
+ Other envelope fields: `pagination` (PaginationMeta).
2994
+
2995
+ **Example**
2996
+
2997
+ ```ts
2998
+ const result = await g8.api.contacts.withdrawContactsFromSequences({ body: {} });
2999
+ ```
3000
+
3001
+ ---
3002
+
3003
+ ## Referenced types
3004
+
3005
+ Named types that appear in the tables above. Full TypeScript definitions: `G8Contract.<Name>` (`import type { G8Contract } from "@graph8/sdk"`).
3006
+
3007
+ <a id="type-columnsource"></a>
3008
+
3009
+ ### `ColumnSource`
3010
+
3011
+ Which entity a field in the contact field list belongs to. The ``GET /contacts/columns`` response deliberately combines fields from three provenances into one list (issue #21184): the person record, their employer's company record, and user-created custom columns. Consumers (form-mapping UI, AI-agent field listing, CSV import) need to tell them apart — a company field like ``COMPANY_REVENUE`` describes the employer, not the contact. - ``contact``: a field on the person record (``MashupContact.*``) — the default. - ``company``: a field on the contact's employer (``MashupCompany.*``), surfaced…
3012
+
3013
+ Type: `"contact" | "company" | "custom"`.
3014
+
3015
+ <a id="type-columntype"></a>
3016
+
3017
+ ### `ColumnType`
3018
+
3019
+ User-selectable dynamic-column data types. Every member must have a physical type in the repos' pg_type_map (contacts/companies CDP repos + enrichment DynamicColumnRepository: int→INTEGER, numeric→NUMERIC, text→TEXT, boolean→BOOLEAN) and belong to the user-owned family in lists/usecases/dynamic_column_write_contract.py — both already list these four. Write paths coerce values per type via shared.infrustructure.db.cdp.dynamic_column_values.coerce_dynamic_value.
3020
+
3021
+ Type: `"text" | "int" | "numeric" | "boolean"`.
3022
+
3023
+ <a id="type-contactbulkgetitem"></a>
3024
+
3025
+ ### `ContactBulkGetItem`
3026
+
3027
+ One contact: the full record, or `found: false`.
3028
+
3029
+ | Field | Type | Required | Description |
3030
+ |---|---|---|---|
3031
+ | `contact_id` | `integer` | yes | |
3032
+ | `found` | `boolean` | yes | False when the contact does not exist or is outside this key's scope (indistinguishable on purpose, like the per-contact 404). |
3033
+ | `contact` | `ContactResponse \| null` | no | The same record `GET /contacts/{contact_id}` returns. Null when not found. |
3034
+
3035
+ <a id="type-contactcompanysummary"></a>
3036
+
3037
+ ### `ContactCompanySummary`
3038
+
3039
+ | Field | Type | Required | Description |
3040
+ |---|---|---|---|
3041
+ | `city` | `string \| null` | no | |
3042
+ | `country` | `string \| null` | no | |
3043
+ | `domain` | `string \| null` | no | |
3044
+ | `employee_count` | `string \| null` | no | |
3045
+ | `id` | `integer \| null` | no | |
3046
+ | `industry` | `string \| null` | no | |
3047
+ | `linkedin_url` | `string \| null` | no | |
3048
+ | `logo_url` | `string \| null` | no | |
3049
+ | `name` | `string \| null` | no | |
3050
+ | `state` | `string \| null` | no | |
3051
+ | `website` | `string \| null` | no | |
3052
+
3053
+ <a id="type-contactrelateditem"></a>
3054
+
3055
+ ### `ContactRelatedItem`
3056
+
3057
+ One contact's related records. A field is present only when requested.
3058
+
3059
+ | Field | Type | Required | Description |
3060
+ |---|---|---|---|
3061
+ | `contact_id` | `integer` | yes | |
3062
+ | `found` | `boolean` | yes | False when the contact does not exist or is outside this key's scope (indistinguishable on purpose, like the per-contact 404). |
3063
+ | `lists` | `Array<Record<string, unknown>> \| null` | no | |
3064
+ | `sequences` | `Array<Record<string, unknown>> \| null` | no | |
3065
+
3066
+ <a id="type-createfieldenrichmentinput"></a>
3067
+
3068
+ ### `CreateFieldEnrichmentInput`
3069
+
3070
+ Optional enrichment-pipeline block attached at column-create time. When supplied, `POST /fields` creates a companion `enrichment_configs` row in the same request so the new column is immediately runnable via `POST /enrichment/waterfall/enrich`. Without this block the column exists but has no enrichment plan — calling /waterfall/enrich on it returns 422 (`waterfall_config_missing`). Currently only `type='waterfall'` is supported; AI / formula enrichment will follow once the rest of the agent surface lands.
3071
+
3072
+ | Field | Type | Required | Description |
3073
+ |---|---|---|---|
3074
+ | `email_verification` | `EmailVerificationInput \| null` | no | Optional post-enrichment email verification config. |
3075
+ | `field_to_enrich` | `string \| null` | no | Target field identifier. Defaults to the new column's slug. |
3076
+ | `name` | `string \| null` | no | Pipeline name. Defaults to `<column title> Enrichment` if omitted. |
3077
+ | `providers` | `Array<string> \| null` | no | Ordered list of provider names. Without `target_field`, server maps each to its default email-finder action (legacy). With `target_field`, filters the column template to these providers (correct per-field action preserved). Mutually exclusive with `steps`. |
3078
+ | `skip_existing_values` | `boolean` | no | If true, skip rows where the target field is already populated. default `true` |
3079
+ | `steps` | `Array<WaterfallStepInput> \| null` | no | Full caller-supplied step list. Persisted verbatim. Mutually exclusive with `providers`. |
3080
+ | `target_field` | `string \| null` | no | Kind of data this column holds — CONTACT_DIRECT_PHONE, CONTACT_MOBILE_PHONE, CONTACT_WORK_EMAIL, CONTACT_LINKEDIN_URL, COMPANY_PHONE, ... or a friendly synonym ('phone', 'mobile', 'email', 'linkedin'). When set, the pipeline is built from the server's per-column TEMPLATE so each provider runs its CORRECT action for that data kind (e.g. leadmagic `mobile_finder` for a phone, NOT `email_finder`) —… |
3081
+ | `type` | `string` | no | Pipeline kind. Only 'waterfall' is supported today. default `"waterfall"` |
3082
+
3083
+ <a id="type-createfieldenrichmentresponse"></a>
3084
+
3085
+ ### `CreateFieldEnrichmentResponse`
3086
+
3087
+ Echo of the companion enrichment config created by `enrichment` block.
3088
+
3089
+ | Field | Type | Required | Description |
3090
+ |---|---|---|---|
3091
+ | `column_id` | `string` | yes | column_id slug to pass to /enrichment/waterfall/enrich |
3092
+ | `config_id` | `string` | yes | |
3093
+ | `name` | `string` | yes | |
3094
+ | `type` | `string` | yes | |
3095
+ | `email_verification` | `Record<string, unknown> \| null` | no | |
3096
+ | `providers` | `Array<string>` | no | |
3097
+
3098
+ <a id="type-customfieldwritereport"></a>
3099
+
3100
+ ### `CustomFieldWriteReport`
3101
+
3102
+ How a write path handled the request's custom (dynamic) column keys. Shared by every Developer API write surface that accepts custom columns (``POST /contacts``, ``PUT /contacts/assert[/batch]``, ``PUT /companies/assert[/batch]``). Every field defaults to empty, so a client that ignores this object sees no behavioural change. It exists because these keys were previously dropped with NO caller-visible signal — the only trace was a server-side ``logger.warning`` in ``append_to_audience``.
3103
+
3104
+ | Field | Type | Required | Description |
3105
+ |---|---|---|---|
3106
+ | `created` | `Array<string>` | no | Caller keys for which a NEW custom column was created by this request. |
3107
+ | `ignored` | `Array<string>` | no | Caller keys that matched no custom column and were NOT written. Create the column first (POST /fields) or pass create_missing_fields=true. |
3108
+ | `written` | `Array<string>` | no | Caller keys that resolved to a custom column and were written. |
3109
+
3110
+ <a id="type-filtercondition"></a>
3111
+
3112
+ ### `FilterCondition`
3113
+
3114
+ One structured filter condition. Mirrors `shared.interfaces.fastapi.dtos.DtoCondition`.
3115
+
3116
+ | Field | Type | Required | Description |
3117
+ |---|---|---|---|
3118
+ | `field` | `string` | yes | Field name to apply the condition to. |
3119
+ | `operator` | `string` | no | Operator, e.g. `=`, `in`, `like`. default `"="` |
3120
+ | `value` | `unknown` | no | Value to compare against. |
3121
+ | `value_to` | `unknown \| null` | no | Secondary value, for range operators. |
3122
+
3123
+ <a id="type-mergefieldoverride"></a>
3124
+
3125
+ ### `MergeFieldOverride`
3126
+
3127
+ Which side of a merge wins one field.
3128
+
3129
+ | Field | Type | Required | Description |
3130
+ |---|---|---|---|
3131
+ | `field` | `string` | yes | Field name, e.g. `CONTACT_JOB_TITLE`. |
3132
+ | `winner` | `"primary" \| "secondary"` | yes | Which record's value to keep. |
3133
+
3134
+ <a id="type-segmentfiltergroup"></a>
3135
+
3136
+ ### `SegmentFilterGroup`
3137
+
3138
+ An AND/OR group of leaves and nested groups, at most three groups deep. Mirrors `SegmentFilterGroup` in `contacts.domain.value_objects.ag_grid_models`. `op` is closed because the app REFUSES an unrecognised connector rather than defaulting to AND - defaulting would silently return a different result set, and on a destructive route that is a different set of records acted on. FIXED DEPTH, NOT RECURSIVE. The app's model is self-referencing; the published one deliberately is not, because a schema that reaches itself through `$ref` sends the docs renderer into unbounded recursion. Three group lev…
3139
+
3140
+ | Field | Type | Required | Description |
3141
+ |---|---|---|---|
3142
+ | `op` | `"AND" \| "OR" \| "and" \| "or"` | yes | Connector for this group. Case-insensitive. |
3143
+ | `children` | `Array<SegmentFilterSubgroup \| SegmentFilterLeaf>` | no | Nested groups and/or leaf conditions. |