@graph8/sdk 0.251.0 → 0.260.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 +104 -7
  4. package/dist/index.d.ts +104 -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 +102 -7
  10. package/dist/react.d.ts +102 -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 +1696 -0
  140. package/docs/api/deals.md +2432 -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,2432 @@
1
+ <!-- Generated by sdk/js/scripts/generate-agent-docs.ts from developer-contract/openapi.json. Regenerated on every build. -->
2
+
3
+ # `g8.api.deals`: Deals
4
+
5
+ 48 operations (21 read, 17 write, 7 destructive, 3 billable).
6
+
7
+ 8 of these also have a hand-written method (`g8.deals`), 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: [deals.d.ts](deals.d.ts).
20
+
21
+ ## Operations
22
+
23
+ | Call | HTTP | Tier | Scope | Summary |
24
+ |---|---|---|---|---|
25
+ | [`addDealContact`](#op-adddealcontact) | `POST /api/v1/deals/{deal_id}/contacts` | write | `deals:write` | Add Deal Contact |
26
+ | [`archiveDealCloseReason`](#op-archivedealclosereason) | `DELETE /api/v1/deals/close-reasons/{reason_id}` | destructive | `deals:delete` | Archive Deal Close Reason |
27
+ | [`bulkUpdateDeals`](#op-bulkupdatedeals) | `POST /api/v1/deals/bulk` | write | `deals:write` | Bulk Update Deals |
28
+ | [`createAccountDeal`](#op-createaccountdeal) | `POST /api/v1/accounts/{account_id}/deals` | write | `deals:write` | Create Account Deal |
29
+ | [`createDeal`](#op-createdeal) ★ | `POST /api/v1/deals` | write | `deals:write` | Create Deal |
30
+ | [`createDealCloseReason`](#op-createdealclosereason) | `POST /api/v1/deals/close-reasons` | write | `deals:write` | Create Deal Close Reason |
31
+ | [`createDealColumn`](#op-createdealcolumn) | `POST /api/v1/deals/columns/create` | write | `deals:write` | Create Deal Column |
32
+ | [`deleteDeal`](#op-deletedeal) ★ | `DELETE /api/v1/deals/{deal_id}` | destructive | `deals:delete` | Delete Deal |
33
+ | [`deleteDealColumn`](#op-deletedealcolumn) | `DELETE /api/v1/deals/columns/{column_id}` | destructive | `deals:delete` | Delete Deal Column |
34
+ | [`deleteDealDocument`](#op-deletedealdocument) | `DELETE /api/v1/deals/{deal_id}/documents/{document_id}` | destructive | `deals:delete` | Delete Deal Document |
35
+ | [`deleteDealNote`](#op-deletedealnote) | `DELETE /api/v1/deals/{deal_id}/notes/{note_id}` | destructive | `deals:delete` | Delete Deal Note |
36
+ | [`generateAllDealDocuments`](#op-generatealldealdocuments) | `POST /api/v1/deals/{deal_id}/documents/generate-all` | billable | `deals:run` | Generate All Deal Documents |
37
+ | [`generateDealDocument`](#op-generatedealdocument) | `POST /api/v1/deals/{deal_id}/documents/types/{doc_type}/generate` | billable | `deals:run` | Generate Deal Document |
38
+ | [`getCompanyDeals`](#op-getcompanydeals) ★ | `GET /api/v1/companies/{company_id}/deals` | read | `deals:read` | Get Company Deals |
39
+ | [`getContactDeals`](#op-getcontactdeals) ★ | `GET /api/v1/contacts/{contact_id}/deals` | read | `deals:read` | Get Contact Deals |
40
+ | [`getDeal`](#op-getdeal) ★ | `GET /api/v1/deals/{deal_id}` | read | `deals:read` | Get Deal |
41
+ | [`getDealAnalytics`](#op-getdealanalytics) | `GET /api/v1/deals/analytics` | read | `deals:read` | Get Deal Analytics |
42
+ | [`getDealCrossfire`](#op-getdealcrossfire) | `GET /api/v1/deals/{deal_id}/crossfire` | read | `deals:read` | Get Deal Crossfire |
43
+ | [`getDealDetail`](#op-getdealdetail) | `GET /api/v1/deals/{deal_id}/detail` | read | `deals:read` | Get Deal Detail |
44
+ | [`getDealDocument`](#op-getdealdocument) | `GET /api/v1/deals/{deal_id}/documents/types/{doc_type}` | read | `deals:read` | Get Deal Document |
45
+ | [`getDealDocumentGenerationStatus`](#op-getdealdocumentgenerationstatus) | `GET /api/v1/deals/{deal_id}/documents/generation-status` | read | `deals:read` | Get Deal Document Generation Status |
46
+ | [`getDealSignals`](#op-getdealsignals) | `GET /api/v1/deals/{deal_id}/signals` | read | `deals:read` | Get Deal Signals |
47
+ | [`getDealStageVelocity`](#op-getdealstagevelocity) | `GET /api/v1/deals/stage-velocity` | read | `deals:read` | Get Deal Stage Velocity |
48
+ | [`listAccountDeals`](#op-listaccountdeals) | `GET /api/v1/accounts/{account_id}/deals` | read | `deals:read` | List Account Deals |
49
+ | [`listDealCloseReasons`](#op-listdealclosereasons) | `GET /api/v1/deals/close-reasons` | read | `deals:read` | List Deal Close Reasons |
50
+ | [`listDealColumns`](#op-listdealcolumns) | `GET /api/v1/deals/columns` | read | `deals:read` | List Deal Columns |
51
+ | [`listDealContacts`](#op-listdealcontacts) | `GET /api/v1/deals/{deal_id}/contacts` | read | `deals:read` | List Deal Contacts |
52
+ | [`listDealCustomFieldDiConfig`](#op-listdealcustomfielddiconfig) | `GET /api/v1/deals/custom-fields/di-config` | read | `deals:read` | List Deal Custom Field Di Config |
53
+ | [`listDealDocuments`](#op-listdealdocuments) | `GET /api/v1/deals/{deal_id}/documents` | read | `deals:read` | List Deal Documents |
54
+ | [`listDealHistory`](#op-listdealhistory) | `GET /api/v1/deals/{deal_id}/history` | read | `deals:read` | List Deal History |
55
+ | [`listDealLineItems`](#op-listdeallineitems) | `GET /api/v1/deals/{deal_id}/line-items` | read | `deals:read` | List Deal Line Items |
56
+ | [`listDeals`](#op-listdeals) ★ | `GET /api/v1/deals` | read | `deals:read` | List Deals |
57
+ | [`listPipelines`](#op-listpipelines) ★ | `GET /api/v1/deals/pipelines` | read | `deals:read` | List Pipelines |
58
+ | [`mergeDeal`](#op-mergedeal) | `POST /api/v1/deals/{deal_id}/merge` | destructive | `deals:delete` | Merge Deal |
59
+ | [`moveDealToPipeline`](#op-movedealtopipeline) | `PUT /api/v1/deals/{deal_id}/pipeline` | write | `deals:write` | Move Deal To Pipeline |
60
+ | [`previewDealMerge`](#op-previewdealmerge) | `GET /api/v1/deals/{deal_id}/merge/preview` | read | `deals:read` | Preview Deal Merge |
61
+ | [`regenerateDealDocument`](#op-regeneratedealdocument) | `POST /api/v1/deals/{deal_id}/documents/types/{doc_type}/regenerate` | billable | `deals:run` | Regenerate Deal Document |
62
+ | [`removeDealContact`](#op-removedealcontact) | `DELETE /api/v1/deals/{deal_id}/contacts/{person_id}` | destructive | `deals:delete` | Remove Deal Contact |
63
+ | [`replaceDealLineItems`](#op-replacedeallineitems) | `PUT /api/v1/deals/{deal_id}/line-items` | write | `deals:write` | Replace Deal Line Items |
64
+ | [`setDealColumnValues`](#op-setdealcolumnvalues) | `PUT /api/v1/deals/{deal_id}/columns/values` | write | `deals:write` | Set Deal Column Values |
65
+ | [`setDealCompany`](#op-setdealcompany) | `PUT /api/v1/deals/{deal_id}/company` | write | `deals:write` | Set Deal Company |
66
+ | [`setDealContactRole`](#op-setdealcontactrole) | `PUT /api/v1/deals/{deal_id}/contacts/{contact_id}` | write | `deals:write` | Set Deal Contact Role |
67
+ | [`setPrimaryDealContact`](#op-setprimarydealcontact) | `PUT /api/v1/deals/{deal_id}/contacts/{person_id}/primary` | write | `deals:write` | Set Primary Deal Contact |
68
+ | [`setRivalAttach`](#op-setrivalattach) | `POST /api/v1/deals/{deal_id}/rival-attach` | write | `deals:write` | Set Rival Attach |
69
+ | [`updateDeal`](#op-updatedeal) ★ | `PATCH /api/v1/deals/{deal_id}` | write | `deals:write` | Update Deal |
70
+ | [`updateDealDocument`](#op-updatedealdocument) | `PUT /api/v1/deals/{deal_id}/documents/{document_id}` | write | `deals:write` | Update Deal Document |
71
+ | [`updateDealNote`](#op-updatedealnote) | `PUT /api/v1/deals/{deal_id}/notes/{note_id}` | write | `deals:write` | Update Deal Note |
72
+ | [`upsertDealCustomFieldDiConfig`](#op-upsertdealcustomfielddiconfig) | `POST /api/v1/deals/custom-fields/di-config` | write | `deals:write` | Upsert Deal Custom Field Di Config |
73
+
74
+ ---
75
+
76
+ <a id="op-adddealcontact"></a>
77
+
78
+ ### `g8.api.deals.addDealContact(input)`
79
+
80
+ **Add Deal Contact**
81
+
82
+ - HTTP: `POST /api/v1/deals/{deal_id}/contacts`
83
+ - operationId: `add_deal_contact_deals__deal_id__contacts_post` (also callable as `g8.api.call("add_deal_contact_deals__deal_id__contacts_post", input)`)
84
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
85
+ - API-key scope: `deals:write`
86
+
87
+ Link a contact to this deal.
88
+
89
+ **Input**
90
+
91
+ | Field | Type | Required | Description |
92
+ |---|---|---|---|
93
+ | `path.deal_id` | `string` | yes | Deal id. |
94
+ | `body` | `DealContactCreateRequest` | yes | Request body; fields below. |
95
+
96
+ Body fields (`DealContactCreateRequest`):
97
+
98
+ | Field | Type | Required | Description |
99
+ |---|---|---|---|
100
+ | `body.person_id` | `string` | yes | Contact to link to the deal. |
101
+ | `body.role` | `string \| null` | no | Role on this deal: champion, decision_maker, influencer, blocker, coach or end_user. The app does not constrain the value, so it is left open here rather than declaring an enum this surface would then have to keep in lock-step. |
102
+
103
+ **Returns** `ApiResponse_DealContact_`: the envelope `{ data: DealContact, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
104
+
105
+ Other envelope fields: `pagination` (PaginationMeta).
106
+
107
+ `DealContact` fields:
108
+
109
+ | Field | Type | Required | Description |
110
+ |---|---|---|---|
111
+ | `buying_role` | `string \| null` | no | General buying role from the contact record. |
112
+ | `created_at` | `string (date-time) \| null` | no | |
113
+ | `email` | `string \| null` | no | |
114
+ | `id` | `string \| null` | no | Link id, not the person id. |
115
+ | `is_primary` | `boolean \| null` | no | |
116
+ | `name` | `string \| null` | no | |
117
+ | `person_id` | `string \| null` | no | |
118
+ | `role` | `string \| null` | no | Role on THIS deal. |
119
+ | `title` | `string \| null` | no | |
120
+
121
+ **Example**
122
+
123
+ ```ts
124
+ const result = await g8.api.deals.addDealContact({ path: { deal_id: "id" }, body: { person_id: "id" } });
125
+ ```
126
+
127
+ ---
128
+
129
+ <a id="op-archivedealclosereason"></a>
130
+
131
+ ### `g8.api.deals.archiveDealCloseReason(input)`
132
+
133
+ **Archive Deal Close Reason**
134
+
135
+ - HTTP: `DELETE /api/v1/deals/close-reasons/{reason_id}`
136
+ - operationId: `archive_deal_close_reason_deals_close_reasons__reason_id__delete` (also callable as `g8.api.call("archive_deal_close_reason_deals_close_reasons__reason_id__delete", input)`)
137
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
138
+ - API-key scope: `deals:delete`
139
+
140
+ Archive a close reason.
141
+
142
+ ENTRY GATE: `_REASON_MUTATE_PERMISSIONS`, the SAME route dependency the app
143
+ declares. Beyond the gate the decision is CREATOR OR MANAGER, not
144
+ manager-only - the app's own note: manager-only removal "would make every
145
+ rep's typo permanent and org-wide, in a list" a rep is expected to extend
146
+ inline. `can_manage` (forwarded to the app handler) enforces that in-body
147
+ creator-or-manager check, and tells a caller in advance which rows they may
148
+ remove.
149
+
150
+ **Input**
151
+
152
+ | Field | Type | Required | Description |
153
+ |---|---|---|---|
154
+ | `path.reason_id` | `string` | yes | Close reason id. |
155
+
156
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
157
+
158
+ Other envelope fields: `pagination` (PaginationMeta).
159
+
160
+ **Example**
161
+
162
+ ```ts
163
+ // destructive: deletes or archives data; confirm with a human before calling.
164
+ const result = await g8.api.deals.archiveDealCloseReason({ path: { reason_id: "id" } });
165
+ ```
166
+
167
+ ---
168
+
169
+ <a id="op-bulkupdatedeals"></a>
170
+
171
+ ### `g8.api.deals.bulkUpdateDeals(input)`
172
+
173
+ **Bulk Update Deals**
174
+
175
+ - HTTP: `POST /api/v1/deals/bulk`
176
+ - operationId: `bulk_update_deals_deals_bulk_post` (also callable as `g8.api.call("bulk_update_deals_deals_bulk_post", input)`)
177
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
178
+ - API-key scope: `deals:write`
179
+
180
+ Apply ONE change to up to 100 deals.
181
+
182
+ PUT semantics on every field of `change`: null leaves a value alone, an
183
+ EMPTY STRING clears it. Omitting a field and sending `""` are therefore
184
+ different instructions and the second one is destructive.
185
+
186
+ Read the per-deal result rather than the HTTP status: a deal the caller
187
+ cannot write is reported, not fatal.
188
+
189
+ **Input**
190
+
191
+ | Field | Type | Required | Description |
192
+ |---|---|---|---|
193
+ | `body` | `BulkDealUpdateRequest` | yes | Request body; fields below. |
194
+
195
+ Body fields (`BulkDealUpdateRequest`):
196
+
197
+ | Field | Type | Required | Description |
198
+ |---|---|---|---|
199
+ | `body.change` | `BulkDealChange` | yes | |
200
+ | `body.deal_ids` | `Array<string>` | yes | min items 1, max items 100 |
201
+
202
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
203
+
204
+ Other envelope fields: `pagination` (PaginationMeta).
205
+
206
+ **Example**
207
+
208
+ ```ts
209
+ const result = await g8.api.deals.bulkUpdateDeals({ body: { change: {}, deal_ids: ["id"] } });
210
+ ```
211
+
212
+ ---
213
+
214
+ <a id="op-createaccountdeal"></a>
215
+
216
+ ### `g8.api.deals.createAccountDeal(input)`
217
+
218
+ **Create Account Deal**
219
+
220
+ - HTTP: `POST /api/v1/accounts/{account_id}/deals`
221
+ - operationId: `create_account_deal_accounts__account_id__deals_post` (also callable as `g8.api.call("create_account_deal_accounts__account_id__deals_post", input)`)
222
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
223
+ - API-key scope: `deals:write`
224
+
225
+ Create a deal already attached to an account.
226
+
227
+ `POST /deals` creates one standalone; this attaches it in the same call,
228
+ closing the window where a deal exists with no account.
229
+
230
+ No per-record gate, matching the app: there is no existing deal to check
231
+ against, and the account is validated by the handler.
232
+
233
+ **Input**
234
+
235
+ | Field | Type | Required | Description |
236
+ |---|---|---|---|
237
+ | `path.account_id` | `string` | yes | Account the deal belongs to. |
238
+ | `body` | `AccountDealCreateRequest` | yes | Request body; fields below. |
239
+
240
+ Body fields (`AccountDealCreateRequest`):
241
+
242
+ | Field | Type | Required | Description |
243
+ |---|---|---|---|
244
+ | `body.name` | `string` | yes | |
245
+ | `body.amount` | `number \| null` | no | |
246
+ | `body.close_date` | `string (date-time) \| null` | no | |
247
+ | `body.contact_ids` | `Array<string>` | no | max items 100 |
248
+ | `body.currency` | `string` | no | default `"USD"` |
249
+ | `body.description` | `string \| null` | no | |
250
+ | `body.owner_id` | `string \| null` | no | Who owns the deal. Omit to take the app's default - an API key is an ORGANISATION credential, so there is no 'me' to fall back to. |
251
+ | `body.pipeline_id` | `string \| null` | no | |
252
+ | `body.products` | `Array<string>` | no | |
253
+ | `body.stage` | `string` | no | Stage NAME, not id. default `"discovery"` |
254
+ | `body.stage_id` | `string \| null` | no | Stage id. Takes precedence over `stage`. |
255
+
256
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
257
+
258
+ Other envelope fields: `pagination` (PaginationMeta).
259
+
260
+ **Example**
261
+
262
+ ```ts
263
+ const result = await g8.api.deals.createAccountDeal({ path: { account_id: "id" }, body: { name: "Example" } });
264
+ ```
265
+
266
+ ---
267
+
268
+ <a id="op-createdeal"></a>
269
+
270
+ ### `g8.api.deals.createDeal(input)`
271
+
272
+ **Create Deal**
273
+
274
+ - HTTP: `POST /api/v1/deals`
275
+ - operationId: `create_deal_deals_post` (also callable as `g8.api.call("create_deal_deals_post", input)`)
276
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
277
+ - API-key scope: `deals:write`
278
+ - ★ Hand-written: [`g8.deals.create()`](../sdk-clients.md#g8-deals-create)
279
+
280
+ Create a new deal. Defaults to the org's default pipeline and first stage if not specified.
281
+
282
+ ``background_tasks`` carries the ``deal.created`` event only (#16242). Like
283
+ the PATCH endpoint's stage fan-out it is injected, not a body field, so it
284
+ does not appear in the OpenAPI schema and the request contract is unchanged.
285
+ Queuing it there rather than publishing inline keeps the Redis round trip
286
+ off the caller's latency budget and makes "strictly after the commit"
287
+ structural: the task is queued only once the session context has exited,
288
+ and FastAPI attaches background tasks to the SUCCESS response, so a raise
289
+ anywhere above publishes nothing.
290
+
291
+ **Input**
292
+
293
+ | Field | Type | Required | Description |
294
+ |---|---|---|---|
295
+ | `body` | `DealCreateRequest` | yes | Request body; fields below. |
296
+
297
+ Body fields (`DealCreateRequest`):
298
+
299
+ | Field | Type | Required | Description |
300
+ |---|---|---|---|
301
+ | `body.contact_ids` | `Array<integer>` | yes | mashup_contact_ids to associate with the deal (>=1 required; all must share one company) min items 1 |
302
+ | `body.name` | `string` | yes | Deal name |
303
+ | `body.owner_id` | `string` | yes | Deal owner (user id or email). Required. |
304
+ | `body.allow_duplicate` | `boolean` | no | Set true to create a deal even if one already exists for the company default `false` |
305
+ | `body.amount` | `number \| null` | no | Deal monetary value |
306
+ | `body.close_date` | `string \| null` | no | Expected close date (ISO 8601) |
307
+ | `body.company_id` | `integer \| null` | no | Deprecated: the company is derived from the contacts. If sent, it must match; otherwise omit it. |
308
+ | `body.currency` | `string \| null` | no | Currency code (default: USD) default `"USD"` |
309
+ | `body.description` | `string \| null` | no | Deal description |
310
+ | `body.pipeline_id` | `string \| null` | no | Pipeline ID (defaults to org default) |
311
+ | `body.stage_id` | `string \| null` | no | Stage ID (from /deals/pipelines) |
312
+
313
+ **Returns** `ApiResponse_DealResponse_`: the envelope `{ data: DealResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
314
+
315
+ Other envelope fields: `pagination` (PaginationMeta).
316
+
317
+ `DealResponse` fields:
318
+
319
+ | Field | Type | Required | Description |
320
+ |---|---|---|---|
321
+ | `amount` | `number \| null` | no | |
322
+ | `close_date` | `string \| null` | no | |
323
+ | `closed_lost_reason` | `string \| null` | no | |
324
+ | `company_id` | `unknown \| null` | no | |
325
+ | `contact_count` | `integer` | no | default `0` |
326
+ | `contacts` | `Array<ContactBrief> \| null` | no | |
327
+ | `created_at` | `string \| null` | no | |
328
+ | `currency` | `string \| null` | no | |
329
+ | `description` | `string \| null` | no | |
330
+ | `id` | `string \| null` | no | |
331
+ | `last_activity_at` | `string \| null` | no | |
332
+ | `name` | `string \| null` | no | |
333
+ | `owner_email` | `string \| null` | no | |
334
+ | `owner_id` | `string \| null` | no | |
335
+ | `owner_name` | `string \| null` | no | |
336
+ | `pipeline_id` | `string \| null` | no | |
337
+ | `primary_contact` | `ContactBrief \| null` | no | |
338
+ | `revision` | `integer \| null` | no | CRM revision after a conditional update |
339
+ | `stage_id` | `string \| null` | no | |
340
+ | `stage_name` | `string \| null` | no | |
341
+ | `updated_at` | `string \| null` | no | |
342
+
343
+ **Example**
344
+
345
+ ```ts
346
+ const result = await g8.api.deals.createDeal({ body: { contact_ids: [123], name: "Example", owner_id: "id" } });
347
+ ```
348
+
349
+ ---
350
+
351
+ <a id="op-createdealclosereason"></a>
352
+
353
+ ### `g8.api.deals.createDealCloseReason(input)`
354
+
355
+ **Create Deal Close Reason**
356
+
357
+ - HTTP: `POST /api/v1/deals/close-reasons`
358
+ - operationId: `create_deal_close_reason_deals_close_reasons_post` (also callable as `g8.api.call("create_deal_close_reason_deals_close_reasons_post", input)`)
359
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
360
+ - API-key scope: `deals:write`
361
+
362
+ Add a close reason.
363
+
364
+ ENTRY GATE: `_REASON_MUTATE_PERMISSIONS`, the SAME route dependency the app
365
+ declares - wider than the manager tier (a rep may extend the list inline
366
+ while closing their own deal) but NOT open to org members with no deal
367
+ access. `can_manage` is still resolved for the handler; `may_seed` is now
368
+ enforced by the route gate rather than discarded.
369
+
370
+ **Input**
371
+
372
+ | Field | Type | Required | Description |
373
+ |---|---|---|---|
374
+ | `body` | `CloseReasonCreateRequest` | yes | Request body; fields below. |
375
+
376
+ Body fields (`CloseReasonCreateRequest`):
377
+
378
+ | Field | Type | Required | Description |
379
+ |---|---|---|---|
380
+ | `body.kind` | `string` | yes | Which list this reason belongs to, e.g. won or lost. |
381
+ | `body.label` | `string` | yes | min length 1, max length 255 |
382
+
383
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
384
+
385
+ Other envelope fields: `pagination` (PaginationMeta).
386
+
387
+ **Example**
388
+
389
+ ```ts
390
+ const result = await g8.api.deals.createDealCloseReason({ body: { kind: "example", label: "example" } });
391
+ ```
392
+
393
+ ---
394
+
395
+ <a id="op-createdealcolumn"></a>
396
+
397
+ ### `g8.api.deals.createDealColumn(input)`
398
+
399
+ **Create Deal Column**
400
+
401
+ - HTTP: `POST /api/v1/deals/columns/create`
402
+ - operationId: `create_deal_column_deals_columns_create_post` (also callable as `g8.api.call("create_deal_column_deals_columns_create_post", input)`)
403
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
404
+ - API-key scope: `deals:write`
405
+
406
+ Add a custom column.
407
+
408
+ `list_id` null creates a GLOBAL column, visible on every deals grid in the
409
+ org. That is the wider blast radius of the two, so it is what you get by
410
+ omission only because it is the app's own default.
411
+
412
+ The path is `/columns/create` rather than a POST to `/columns`, matching
413
+ the app exactly - a different spelling here would be a second way to say
414
+ the same thing.
415
+
416
+ **Input**
417
+
418
+ | Field | Type | Required | Description |
419
+ |---|---|---|---|
420
+ | `body` | `CreateDealColumnRequest` | yes | Request body; fields below. |
421
+
422
+ Body fields (`CreateDealColumnRequest`):
423
+
424
+ | Field | Type | Required | Description |
425
+ |---|---|---|---|
426
+ | `body.title` | `string` | yes | Display name. min length 1, max length 100 |
427
+ | `body.data_type` | `"text" \| "int" \| "numeric" \| "number" \| "boolean" \| "date"` | no | Closed to what the app accepts. It validates this inside the handler, so a free string would raise there and escape as a 500 instead of a 422 naming the valid types. default `"text"` |
428
+ | `body.list_id` | `integer \| null` | no | Scope the column to one list. Null creates a GLOBAL column. |
429
+
430
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
431
+
432
+ Other envelope fields: `pagination` (PaginationMeta).
433
+
434
+ **Example**
435
+
436
+ ```ts
437
+ const result = await g8.api.deals.createDealColumn({ body: { title: "Example" } });
438
+ ```
439
+
440
+ ---
441
+
442
+ <a id="op-deletedeal"></a>
443
+
444
+ ### `g8.api.deals.deleteDeal(input)`
445
+
446
+ **Delete Deal**
447
+
448
+ - HTTP: `DELETE /api/v1/deals/{deal_id}`
449
+ - operationId: `delete_deal_deals__deal_id__delete` (also callable as `g8.api.call("delete_deal_deals__deal_id__delete", input)`)
450
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
451
+ - API-key scope: `deals:delete`
452
+ - ★ Hand-written: [`g8.deals.delete()`](../sdk-clients.md#g8-deals-delete)
453
+
454
+ Delete a deal.
455
+
456
+ THE TOMBSTONE RULE (#16242): ``deal.deleted`` has to be self-contained,
457
+ because by the time a consumer reads it the row is gone and ``deal_id``
458
+ resolves to nothing. The payload therefore comes from ``RETURNING`` on the
459
+ DELETE itself — one round trip, and no window in which a concurrent write
460
+ could change what a preceding SELECT had read. ``background_tasks`` is
461
+ injected (not a body field, so the OpenAPI schema is unchanged) for the
462
+ same reason as on PATCH.
463
+
464
+ **Input**
465
+
466
+ | Field | Type | Required | Description |
467
+ |---|---|---|---|
468
+ | `path.deal_id` | `string` | yes | Deal ID (UUID) |
469
+
470
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
471
+
472
+ Other envelope fields: `pagination` (PaginationMeta).
473
+
474
+ **Example**
475
+
476
+ ```ts
477
+ // destructive: deletes or archives data; confirm with a human before calling.
478
+ const result = await g8.api.deals.deleteDeal({ path: { deal_id: "id" } });
479
+ ```
480
+
481
+ ---
482
+
483
+ <a id="op-deletedealcolumn"></a>
484
+
485
+ ### `g8.api.deals.deleteDealColumn(input)`
486
+
487
+ **Delete Deal Column**
488
+
489
+ - HTTP: `DELETE /api/v1/deals/columns/{column_id}`
490
+ - operationId: `delete_deal_column_deals_columns__column_id__delete` (also callable as `g8.api.call("delete_deal_column_deals_columns__column_id__delete", input)`)
491
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
492
+ - API-key scope: `deals:delete`
493
+
494
+ Remove a custom column, and the values every deal held in it.
495
+
496
+ **Input**
497
+
498
+ | Field | Type | Required | Description |
499
+ |---|---|---|---|
500
+ | `path.column_id` | `integer` | yes | Column id. |
501
+
502
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
503
+
504
+ Other envelope fields: `pagination` (PaginationMeta).
505
+
506
+ **Example**
507
+
508
+ ```ts
509
+ // destructive: deletes or archives data; confirm with a human before calling.
510
+ const result = await g8.api.deals.deleteDealColumn({ path: { column_id: 123 } });
511
+ ```
512
+
513
+ ---
514
+
515
+ <a id="op-deletedealdocument"></a>
516
+
517
+ ### `g8.api.deals.deleteDealDocument(input)`
518
+
519
+ **Delete Deal Document**
520
+
521
+ - HTTP: `DELETE /api/v1/deals/{deal_id}/documents/{document_id}`
522
+ - operationId: `delete_deal_document_deals__deal_id__documents__document_id__delete` (also callable as `g8.api.call("delete_deal_document_deals__deal_id__documents__document_id__delete", input)`)
523
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
524
+ - API-key scope: `deals:delete`
525
+
526
+ Remove a generated document.
527
+
528
+ Not destructive in the way a deleted record is: the document can be
529
+ generated again from the same sources - at the cost of the credits that
530
+ takes.
531
+
532
+ **Input**
533
+
534
+ | Field | Type | Required | Description |
535
+ |---|---|---|---|
536
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
537
+ | `path.document_id` | `string` | yes | Document id, from the list read. |
538
+
539
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
540
+
541
+ Other envelope fields: `pagination` (PaginationMeta).
542
+
543
+ **Example**
544
+
545
+ ```ts
546
+ // destructive: deletes or archives data; confirm with a human before calling.
547
+ const result = await g8.api.deals.deleteDealDocument({ path: { deal_id: "id", document_id: "id" } });
548
+ ```
549
+
550
+ ---
551
+
552
+ <a id="op-deletedealnote"></a>
553
+
554
+ ### `g8.api.deals.deleteDealNote(input)`
555
+
556
+ **Delete Deal Note**
557
+
558
+ - HTTP: `DELETE /api/v1/deals/{deal_id}/notes/{note_id}`
559
+ - operationId: `delete_deal_note_deals__deal_id__notes__note_id__delete` (also callable as `g8.api.call("delete_deal_note_deals__deal_id__notes__note_id__delete", input)`)
560
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
561
+ - API-key scope: `deals:delete`
562
+
563
+ Delete a note. The deal and its other notes are untouched.
564
+
565
+ **Input**
566
+
567
+ | Field | Type | Required | Description |
568
+ |---|---|---|---|
569
+ | `path.deal_id` | `string` | yes | Deal id. |
570
+ | `path.note_id` | `string` | yes | Note id. |
571
+
572
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
573
+
574
+ Other envelope fields: `pagination` (PaginationMeta).
575
+
576
+ **Example**
577
+
578
+ ```ts
579
+ // destructive: deletes or archives data; confirm with a human before calling.
580
+ const result = await g8.api.deals.deleteDealNote({ path: { deal_id: "id", note_id: "id" } });
581
+ ```
582
+
583
+ ---
584
+
585
+ <a id="op-generatealldealdocuments"></a>
586
+
587
+ ### `g8.api.deals.generateAllDealDocuments(input)`
588
+
589
+ **Generate All Deal Documents**
590
+
591
+ - HTTP: `POST /api/v1/deals/{deal_id}/documents/generate-all`
592
+ - operationId: `generate_all_deal_documents_deals__deal_id__documents_generate_all_post` (also callable as `g8.api.call("generate_all_deal_documents_deals__deal_id__documents_generate_all_post", input)`)
593
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
594
+ - API-key scope: `deals:run`
595
+
596
+ Generate all six documents for this deal. SPENDS CREDITS.
597
+
598
+ ASYNCHRONOUS: the work is queued and this returns straight away. Poll
599
+ `/documents/generation-status`.
600
+
601
+ The app REFUSES this when the deal's company has no completed synthesis
602
+ documents of its own - the deal documents are written from them, so
603
+ without them there is nothing to write from. Generate the company
604
+ documents first.
605
+
606
+ **Input**
607
+
608
+ | Field | Type | Required | Description |
609
+ |---|---|---|---|
610
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
611
+
612
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
613
+
614
+ Other envelope fields: `pagination` (PaginationMeta).
615
+
616
+ **Example**
617
+
618
+ ```ts
619
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
620
+ const result = await g8.api.deals.generateAllDealDocuments({ path: { deal_id: "id" } });
621
+ ```
622
+
623
+ ---
624
+
625
+ <a id="op-generatedealdocument"></a>
626
+
627
+ ### `g8.api.deals.generateDealDocument(input)`
628
+
629
+ **Generate Deal Document**
630
+
631
+ - HTTP: `POST /api/v1/deals/{deal_id}/documents/types/{doc_type}/generate`
632
+ - operationId: `generate_deal_document_deals__deal_id__documents_types__doc_type__generate_post` (also callable as `g8.api.call("generate_deal_document_deals__deal_id__documents_types__doc_type__generate_post", input)`)
633
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
634
+ - API-key scope: `deals:run`
635
+
636
+ Generate ONE document. SPENDS CREDITS.
637
+
638
+ IDEMPOTENT ONLY IN THE SENSE THAT IT WILL NOT DUPLICATE: if the document
639
+ already exists this OVERWRITES it, and the response says so with
640
+ `is_regeneration`. It does not skip, so a retried call is a second spend.
641
+
642
+ Queued, not synchronous - poll `/documents/generation-status`.
643
+
644
+ **Input**
645
+
646
+ | Field | Type | Required | Description |
647
+ |---|---|---|---|
648
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
649
+ | `path.doc_type` | `"deal_risks" \| "next_steps" \| "close_plan" \| "scope_of_work" \| "roi_analysis" \| "competitive_analysis"` | yes | Which generated document. One of the six the deal synthesis produces; anything else is a 422 naming them. |
650
+
651
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
652
+
653
+ Other envelope fields: `pagination` (PaginationMeta).
654
+
655
+ **Example**
656
+
657
+ ```ts
658
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
659
+ const result = await g8.api.deals.generateDealDocument({ path: { deal_id: "id", doc_type: "deal_risks" } });
660
+ ```
661
+
662
+ ---
663
+
664
+ <a id="op-getcompanydeals"></a>
665
+
666
+ ### `g8.api.deals.getCompanyDeals(input)`
667
+
668
+ **Get Company Deals**
669
+
670
+ - HTTP: `GET /api/v1/companies/{company_id}/deals`
671
+ - operationId: `get_company_deals_companies__company_id__deals_get` (also callable as `g8.api.call("get_company_deals_companies__company_id__deals_get", input)`)
672
+ - Tier: `read`: reads data; safe to call and to retry
673
+ - API-key scope: `deals:read`
674
+ - ★ Hand-written: [`g8.deals.forCompany()`](../sdk-clients.md#g8-deals-forcompany)
675
+
676
+ Get all deals associated with a company.
677
+
678
+ **Input**
679
+
680
+ | Field | Type | Required | Description |
681
+ |---|---|---|---|
682
+ | `path.company_id` | `integer` | yes | Company ID |
683
+
684
+ **Returns** `ApiResponse_list_ContactDealResponse__`: the envelope `{ data: Array<ContactDealResponse>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
685
+
686
+ Other envelope fields: `pagination` (PaginationMeta).
687
+
688
+ `ContactDealResponse` fields:
689
+
690
+ | Field | Type | Required | Description |
691
+ |---|---|---|---|
692
+ | `close_date` | `string \| null` | no | |
693
+ | `created_at` | `string \| null` | no | |
694
+ | `currency` | `string \| null` | no | |
695
+ | `deal_id` | `string \| null` | no | |
696
+ | `name` | `string \| null` | no | |
697
+ | `owner_id` | `string \| null` | no | |
698
+ | `pipeline_id` | `string \| null` | no | |
699
+ | `role` | `string \| null` | no | |
700
+ | `stage` | `string \| null` | no | |
701
+ | `value` | `number \| null` | no | |
702
+
703
+ **Example**
704
+
705
+ ```ts
706
+ const result = await g8.api.deals.getCompanyDeals({ path: { company_id: 123 } });
707
+ ```
708
+
709
+ ---
710
+
711
+ <a id="op-getcontactdeals"></a>
712
+
713
+ ### `g8.api.deals.getContactDeals(input)`
714
+
715
+ **Get Contact Deals**
716
+
717
+ - HTTP: `GET /api/v1/contacts/{contact_id}/deals`
718
+ - operationId: `get_contact_deals_contacts__contact_id__deals_get` (also callable as `g8.api.call("get_contact_deals_contacts__contact_id__deals_get", input)`)
719
+ - Tier: `read`: reads data; safe to call and to retry
720
+ - API-key scope: `deals:read`
721
+ - ★ Hand-written: [`g8.deals.forContact()`](../sdk-clients.md#g8-deals-forcontact)
722
+
723
+ Get all deals associated with a contact.
724
+
725
+ **Input**
726
+
727
+ | Field | Type | Required | Description |
728
+ |---|---|---|---|
729
+ | `path.contact_id` | `integer` | yes | Contact ID |
730
+
731
+ **Returns** `ApiResponse_list_ContactDealResponse__`: the envelope `{ data: Array<ContactDealResponse>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
732
+
733
+ Other envelope fields: `pagination` (PaginationMeta).
734
+
735
+ `ContactDealResponse` fields:
736
+
737
+ | Field | Type | Required | Description |
738
+ |---|---|---|---|
739
+ | `close_date` | `string \| null` | no | |
740
+ | `created_at` | `string \| null` | no | |
741
+ | `currency` | `string \| null` | no | |
742
+ | `deal_id` | `string \| null` | no | |
743
+ | `name` | `string \| null` | no | |
744
+ | `owner_id` | `string \| null` | no | |
745
+ | `pipeline_id` | `string \| null` | no | |
746
+ | `role` | `string \| null` | no | |
747
+ | `stage` | `string \| null` | no | |
748
+ | `value` | `number \| null` | no | |
749
+
750
+ **Example**
751
+
752
+ ```ts
753
+ const result = await g8.api.deals.getContactDeals({ path: { contact_id: 123 } });
754
+ ```
755
+
756
+ ---
757
+
758
+ <a id="op-getdeal"></a>
759
+
760
+ ### `g8.api.deals.getDeal(input)`
761
+
762
+ **Get Deal**
763
+
764
+ - HTTP: `GET /api/v1/deals/{deal_id}`
765
+ - operationId: `get_deal_deals__deal_id__get` (also callable as `g8.api.call("get_deal_deals__deal_id__get", input)`)
766
+ - Tier: `read`: reads data; safe to call and to retry
767
+ - API-key scope: `deals:read`
768
+ - ★ Hand-written: [`g8.deals.get()`](../sdk-clients.md#g8-deals-get)
769
+
770
+ Get a single deal by ID.
771
+
772
+ **Input**
773
+
774
+ | Field | Type | Required | Description |
775
+ |---|---|---|---|
776
+ | `path.deal_id` | `string` | yes | Deal ID (UUID) |
777
+
778
+ **Returns** `ApiResponse_DealResponse_`: the envelope `{ data: DealResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
779
+
780
+ Other envelope fields: `pagination` (PaginationMeta).
781
+
782
+ `DealResponse` fields:
783
+
784
+ | Field | Type | Required | Description |
785
+ |---|---|---|---|
786
+ | `amount` | `number \| null` | no | |
787
+ | `close_date` | `string \| null` | no | |
788
+ | `closed_lost_reason` | `string \| null` | no | |
789
+ | `company_id` | `unknown \| null` | no | |
790
+ | `contact_count` | `integer` | no | default `0` |
791
+ | `contacts` | `Array<ContactBrief> \| null` | no | |
792
+ | `created_at` | `string \| null` | no | |
793
+ | `currency` | `string \| null` | no | |
794
+ | `description` | `string \| null` | no | |
795
+ | `id` | `string \| null` | no | |
796
+ | `last_activity_at` | `string \| null` | no | |
797
+ | `name` | `string \| null` | no | |
798
+ | `owner_email` | `string \| null` | no | |
799
+ | `owner_id` | `string \| null` | no | |
800
+ | `owner_name` | `string \| null` | no | |
801
+ | `pipeline_id` | `string \| null` | no | |
802
+ | `primary_contact` | `ContactBrief \| null` | no | |
803
+ | `revision` | `integer \| null` | no | CRM revision after a conditional update |
804
+ | `stage_id` | `string \| null` | no | |
805
+ | `stage_name` | `string \| null` | no | |
806
+ | `updated_at` | `string \| null` | no | |
807
+
808
+ **Example**
809
+
810
+ ```ts
811
+ const result = await g8.api.deals.getDeal({ path: { deal_id: "id" } });
812
+ ```
813
+
814
+ ---
815
+
816
+ <a id="op-getdealanalytics"></a>
817
+
818
+ ### `g8.api.deals.getDealAnalytics(input?)`
819
+
820
+ **Get Deal Analytics**
821
+
822
+ - HTTP: `GET /api/v1/deals/analytics`
823
+ - operationId: `get_deal_analytics_deals_analytics_get` (also callable as `g8.api.call("get_deal_analytics_deals_analytics_get", input)`)
824
+ - Tier: `read`: reads data; safe to call and to retry
825
+ - API-key scope: `deals:read`
826
+
827
+ Pipeline totals, stage breakdown, win rate and velocity over the deals the key can see.
828
+
829
+ **Input**
830
+
831
+ | Field | Type | Required | Description |
832
+ |---|---|---|---|
833
+ | `query.pipeline_id` | `string \| null` | no | Only this pipeline. |
834
+ | `query.owner_ids` | `Array<string> \| null` | no | Only these owners. Repeatable. |
835
+ | `query.stage_ids` | `Array<string> \| null` | no | Only these stages. Repeatable. |
836
+ | `query.close_date_from` | `string \| null` | no | Close date lower bound, YYYY-MM-DD. |
837
+ | `query.close_date_to` | `string \| null` | no | Close date upper bound, YYYY-MM-DD. |
838
+ | `query.search` | `string \| null` | no | Match on deal or account name. |
839
+ | `query.segmentFilter` | `string \| null` | no | Advanced filter tree as JSON, the same one `GET /deals` accepts. 400 if unparseable. |
840
+
841
+ **Returns** `ApiResponse_CrmRecordPayload_`: the envelope `{ data: CrmRecordPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
842
+
843
+ Other envelope fields: `pagination` (PaginationMeta).
844
+
845
+ **Example**
846
+
847
+ ```ts
848
+ const result = await g8.api.deals.getDealAnalytics();
849
+ ```
850
+
851
+ ---
852
+
853
+ <a id="op-getdealcrossfire"></a>
854
+
855
+ ### `g8.api.deals.getDealCrossfire(input)`
856
+
857
+ **Get Deal Crossfire**
858
+
859
+ - HTTP: `GET /api/v1/deals/{deal_id}/crossfire`
860
+ - operationId: `get_deal_crossfire_deals__deal_id__crossfire_get` (also callable as `g8.api.call("get_deal_crossfire_deals__deal_id__crossfire_get", input)`)
861
+ - Tier: `read`: reads data; safe to call and to retry
862
+ - API-key scope: `deals:read`
863
+
864
+ Competitive pressure on this deal.
865
+
866
+ Open-shaped: this is an ADVISORY read whose contents grow with the
867
+ product, and a dropped field reads as "nothing to worry about" rather than
868
+ "we did not tell you".
869
+
870
+ **Input**
871
+
872
+ | Field | Type | Required | Description |
873
+ |---|---|---|---|
874
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
875
+
876
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
877
+
878
+ Other envelope fields: `pagination` (PaginationMeta).
879
+
880
+ **Example**
881
+
882
+ ```ts
883
+ const result = await g8.api.deals.getDealCrossfire({ path: { deal_id: "id" } });
884
+ ```
885
+
886
+ ---
887
+
888
+ <a id="op-getdealdetail"></a>
889
+
890
+ ### `g8.api.deals.getDealDetail(input)`
891
+
892
+ **Get Deal Detail**
893
+
894
+ - HTTP: `GET /api/v1/deals/{deal_id}/detail`
895
+ - operationId: `get_deal_detail_deals__deal_id__detail_get` (also callable as `g8.api.call("get_deal_detail_deals__deal_id__detail_get", input)`)
896
+ - Tier: `read`: reads data; safe to call and to retry
897
+ - API-key scope: `deals:read`
898
+
899
+ The full deal record the detail page reads.
900
+
901
+ **Input**
902
+
903
+ | Field | Type | Required | Description |
904
+ |---|---|---|---|
905
+ | `path.deal_id` | `string` | yes | Deal id. |
906
+ | `query.include_revision` | `boolean` | no | Include the optimistic-concurrency revision. Null in the response means this org has no revision tracking, so a save is unconditional - it does NOT mean revision 1. default `false` |
907
+
908
+ **Returns** `ApiResponse_DealDetail_`: the envelope `{ data: DealDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
909
+
910
+ Other envelope fields: `pagination` (PaginationMeta).
911
+
912
+ `DealDetail` fields:
913
+
914
+ | Field | Type | Required | Description |
915
+ |---|---|---|---|
916
+ | `amount` | `number \| null` | no | |
917
+ | `close_date` | `string (date-time) \| null` | no | |
918
+ | `company_id` | `string \| null` | no | |
919
+ | `created_at` | `string (date-time) \| null` | no | |
920
+ | `currency` | `string \| null` | no | |
921
+ | `description` | `string \| null` | no | |
922
+ | `id` | `string \| null` | no | |
923
+ | `name` | `string \| null` | no | |
924
+ | `owner_id` | `string \| null` | no | |
925
+ | `pipeline_id` | `string \| null` | no | |
926
+ | `revision` | `integer \| null` | no | Optimistic-concurrency token. None means this org has no revision tracking, so a save is unconditional - it does NOT mean 1. |
927
+ | `stage` | `string \| null` | no | |
928
+ | `stage_id` | `string \| null` | no | |
929
+ | `status` | `string \| null` | no | |
930
+ | `updated_at` | `string (date-time) \| null` | no | |
931
+
932
+ **Example**
933
+
934
+ ```ts
935
+ const result = await g8.api.deals.getDealDetail({ path: { deal_id: "id" } });
936
+ ```
937
+
938
+ ---
939
+
940
+ <a id="op-getdealdocument"></a>
941
+
942
+ ### `g8.api.deals.getDealDocument(input)`
943
+
944
+ **Get Deal Document**
945
+
946
+ - HTTP: `GET /api/v1/deals/{deal_id}/documents/types/{doc_type}`
947
+ - operationId: `get_deal_document_deals__deal_id__documents_types__doc_type__get` (also callable as `g8.api.call("get_deal_document_deals__deal_id__documents_types__doc_type__get", input)`)
948
+ - Tier: `read`: reads data; safe to call and to retry
949
+ - API-key scope: `deals:read`
950
+
951
+ One generated document, in full.
952
+
953
+ There is at most ONE document per type per deal, which is why the type
954
+ identifies it. 404 when it has not been generated yet.
955
+
956
+ **Input**
957
+
958
+ | Field | Type | Required | Description |
959
+ |---|---|---|---|
960
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
961
+ | `path.doc_type` | `"deal_risks" \| "next_steps" \| "close_plan" \| "scope_of_work" \| "roi_analysis" \| "competitive_analysis"` | yes | Which generated document. One of the six the deal synthesis produces; anything else is a 422 naming them. |
962
+
963
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
964
+
965
+ Other envelope fields: `pagination` (PaginationMeta).
966
+
967
+ **Example**
968
+
969
+ ```ts
970
+ const result = await g8.api.deals.getDealDocument({ path: { deal_id: "id", doc_type: "deal_risks" } });
971
+ ```
972
+
973
+ ---
974
+
975
+ <a id="op-getdealdocumentgenerationstatus"></a>
976
+
977
+ ### `g8.api.deals.getDealDocumentGenerationStatus(input)`
978
+
979
+ **Get Deal Document Generation Status**
980
+
981
+ - HTTP: `GET /api/v1/deals/{deal_id}/documents/generation-status`
982
+ - operationId: `get_deal_document_generation_status_deals__deal_id__documents_generation_status_get` (also callable as `g8.api.call("get_deal_document_generation_status_deals__deal_id__documents_generation_status_get", input)`)
983
+ - Tier: `read`: reads data; safe to call and to retry
984
+ - API-key scope: `deals:read`
985
+
986
+ How the generation is going - the cheap read to POLL.
987
+
988
+ Counts rather than content: total, ready, generating, failed. Listing the
989
+ documents transfers every body, which is the wrong call in a poll loop.
990
+
991
+ **Input**
992
+
993
+ | Field | Type | Required | Description |
994
+ |---|---|---|---|
995
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
996
+
997
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
998
+
999
+ Other envelope fields: `pagination` (PaginationMeta).
1000
+
1001
+ **Example**
1002
+
1003
+ ```ts
1004
+ const result = await g8.api.deals.getDealDocumentGenerationStatus({ path: { deal_id: "id" } });
1005
+ ```
1006
+
1007
+ ---
1008
+
1009
+ <a id="op-getdealsignals"></a>
1010
+
1011
+ ### `g8.api.deals.getDealSignals(input)`
1012
+
1013
+ **Get Deal Signals**
1014
+
1015
+ - HTTP: `GET /api/v1/deals/{deal_id}/signals`
1016
+ - operationId: `get_deal_signals_deals__deal_id__signals_get` (also callable as `g8.api.call("get_deal_signals_deals__deal_id__signals_get", input)`)
1017
+ - Tier: `read`: reads data; safe to call and to retry
1018
+ - API-key scope: `deals:read`
1019
+
1020
+ Intent and activity signals attached to this deal.
1021
+
1022
+ Returned as an open object rather than a pinned shape: the signals payload
1023
+ is assembled from several upstreams and declaring a schema here would
1024
+ silently DROP a signal type the moment one is added.
1025
+
1026
+ **Input**
1027
+
1028
+ | Field | Type | Required | Description |
1029
+ |---|---|---|---|
1030
+ | `path.deal_id` | `string` | yes | Deal id. |
1031
+
1032
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1033
+
1034
+ Other envelope fields: `pagination` (PaginationMeta).
1035
+
1036
+ **Example**
1037
+
1038
+ ```ts
1039
+ const result = await g8.api.deals.getDealSignals({ path: { deal_id: "id" } });
1040
+ ```
1041
+
1042
+ ---
1043
+
1044
+ <a id="op-getdealstagevelocity"></a>
1045
+
1046
+ ### `g8.api.deals.getDealStageVelocity(input?)`
1047
+
1048
+ **Get Deal Stage Velocity**
1049
+
1050
+ - HTTP: `GET /api/v1/deals/stage-velocity`
1051
+ - operationId: `get_deal_stage_velocity_deals_stage_velocity_get` (also callable as `g8.api.call("get_deal_stage_velocity_deals_stage_velocity_get", input)`)
1052
+ - Tier: `read`: reads data; safe to call and to retry
1053
+ - API-key scope: `deals:read`
1054
+
1055
+ Time in stage, stage conversion and stuck deals over the deals the key can see.
1056
+
1057
+ **Input**
1058
+
1059
+ | Field | Type | Required | Description |
1060
+ |---|---|---|---|
1061
+ | `query.pipeline_id` | `string \| null` | no | Only this pipeline (UUID). |
1062
+ | `query.owner_ids` | `Array<string> \| null` | no | Only these owners. Repeatable, at most 100. |
1063
+ | `query.stuck_threshold_days` | `integer` | no | A deal with no stage change in this many days is 'stuck'. default `30` |
1064
+
1065
+ **Returns** `ApiResponse_DealStageVelocityPayload_`: the envelope `{ data: DealStageVelocityPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1066
+
1067
+ Other envelope fields: `pagination` (PaginationMeta).
1068
+
1069
+ `DealStageVelocityPayload` fields:
1070
+
1071
+ | Field | Type | Required | Description |
1072
+ |---|---|---|---|
1073
+ | `stuck_deals` | `DealStageVelocityStuckSummary` | yes | |
1074
+ | `by_stage` | `Array<DealStageVelocityBucket>` | no | |
1075
+ | `disclosures` | `Array<string>` | no | |
1076
+
1077
+ **Example**
1078
+
1079
+ ```ts
1080
+ const result = await g8.api.deals.getDealStageVelocity();
1081
+ ```
1082
+
1083
+ ---
1084
+
1085
+ <a id="op-listaccountdeals"></a>
1086
+
1087
+ ### `g8.api.deals.listAccountDeals(input)`
1088
+
1089
+ **List Account Deals**
1090
+
1091
+ - HTTP: `GET /api/v1/accounts/{account_id}/deals`
1092
+ - operationId: `list_account_deals_accounts__account_id__deals_get` (also callable as `g8.api.call("list_account_deals_accounts__account_id__deals_get", input)`)
1093
+ - Tier: `read`: reads data; safe to call and to retry
1094
+ - API-key scope: `deals:read`
1095
+
1096
+ Deals on one account.
1097
+
1098
+ No per-record gate: a LIST is filtered by `deal_scope`, which the app
1099
+ handler takes as a parameter and applies itself. Gating row by row here
1100
+ would be both redundant and wrong - there is no single deal id to check.
1101
+
1102
+ **Input**
1103
+
1104
+ | Field | Type | Required | Description |
1105
+ |---|---|---|---|
1106
+ | `path.account_id` | `string` | yes | Account id. |
1107
+
1108
+ **Returns** `ApiResponse_DealListResponse_`: the envelope `{ data: DealListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1109
+
1110
+ Other envelope fields: `pagination` (PaginationMeta).
1111
+
1112
+ `DealListResponse` fields:
1113
+
1114
+ | Field | Type | Required | Description |
1115
+ |---|---|---|---|
1116
+ | `deals` | `Array<DealSummary>` | no | |
1117
+ | `total` | `integer` | no | default `0` |
1118
+
1119
+ **Example**
1120
+
1121
+ ```ts
1122
+ const result = await g8.api.deals.listAccountDeals({ path: { account_id: "id" } });
1123
+ ```
1124
+
1125
+ ---
1126
+
1127
+ <a id="op-listdealclosereasons"></a>
1128
+
1129
+ ### `g8.api.deals.listDealCloseReasons(input?)`
1130
+
1131
+ **List Deal Close Reasons**
1132
+
1133
+ - HTTP: `GET /api/v1/deals/close-reasons`
1134
+ - operationId: `list_deal_close_reasons_deals_close_reasons_get` (also callable as `g8.api.call("list_deal_close_reasons_deals_close_reasons_get", input)`)
1135
+ - Tier: `read`: reads data; safe to call and to retry
1136
+ - API-key scope: `deals:read`
1137
+
1138
+ The org's close reasons, and what this caller may do with them.
1139
+
1140
+ `can_manage` comes back WITH the list, resolved by the same rule the
1141
+ archive endpoint enforces - the app does that deliberately so the control a
1142
+ UI renders and the permission the endpoint applies cannot drift. A
1143
+ rebuilder without it has to guess which rows are removable.
1144
+
1145
+ LITERAL PATH: registered before `deals_router` so `/deals/{deal_id}` cannot
1146
+ read "close-reasons" as a deal id.
1147
+
1148
+ **Input**
1149
+
1150
+ | Field | Type | Required | Description |
1151
+ |---|---|---|---|
1152
+ | `query.kind` | `string \| null` | no | Filter to one list, e.g. won or lost. |
1153
+
1154
+ **Returns** `ApiResponse_CloseReasonListResponse_`: the envelope `{ data: CloseReasonListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1155
+
1156
+ Other envelope fields: `pagination` (PaginationMeta).
1157
+
1158
+ `CloseReasonListResponse` fields:
1159
+
1160
+ | Field | Type | Required | Description |
1161
+ |---|---|---|---|
1162
+ | `can_manage` | `boolean \| null` | no | Whether this caller may archive reasons they did not create. |
1163
+ | `reasons` | `Array<Record<string, unknown>>` | no | |
1164
+
1165
+ **Example**
1166
+
1167
+ ```ts
1168
+ const result = await g8.api.deals.listDealCloseReasons();
1169
+ ```
1170
+
1171
+ ---
1172
+
1173
+ <a id="op-listdealcolumns"></a>
1174
+
1175
+ ### `g8.api.deals.listDealColumns(input?)`
1176
+
1177
+ **List Deal Columns**
1178
+
1179
+ - HTTP: `GET /api/v1/deals/columns`
1180
+ - operationId: `list_deal_columns_deals_columns_get` (also callable as `g8.api.call("list_deal_columns_deals_columns_get", input)`)
1181
+ - Tier: `read`: reads data; safe to call and to retry
1182
+ - API-key scope: `deals:read`
1183
+
1184
+ The custom columns the deals grid can show.
1185
+
1186
+ The source of the keys `PUT /deals/{id}/columns/values` accepts - writing
1187
+ to anything else is refused.
1188
+
1189
+ **Input**
1190
+
1191
+ | Field | Type | Required | Description |
1192
+ |---|---|---|---|
1193
+ | `query.list_id` | `integer \| null` | no | Only columns scoped to this list, plus the global ones. Omit for the global set alone. |
1194
+
1195
+ **Returns** `ApiResponse_DealCollectionPayload_`: the envelope `{ data: DealCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1196
+
1197
+ Other envelope fields: `pagination` (PaginationMeta).
1198
+
1199
+ `DealCollectionPayload` fields:
1200
+
1201
+ | Field | Type | Required | Description |
1202
+ |---|---|---|---|
1203
+ | `items` | `Array<unknown>` | no | |
1204
+
1205
+ **Example**
1206
+
1207
+ ```ts
1208
+ const result = await g8.api.deals.listDealColumns();
1209
+ ```
1210
+
1211
+ ---
1212
+
1213
+ <a id="op-listdealcontacts"></a>
1214
+
1215
+ ### `g8.api.deals.listDealContacts(input)`
1216
+
1217
+ **List Deal Contacts**
1218
+
1219
+ - HTTP: `GET /api/v1/deals/{deal_id}/contacts`
1220
+ - operationId: `list_deal_contacts_deals__deal_id__contacts_get` (also callable as `g8.api.call("list_deal_contacts_deals__deal_id__contacts_get", input)`)
1221
+ - Tier: `read`: reads data; safe to call and to retry
1222
+ - API-key scope: `deals:read`
1223
+
1224
+ Everyone linked to this deal, with their role on it.
1225
+
1226
+ **Input**
1227
+
1228
+ | Field | Type | Required | Description |
1229
+ |---|---|---|---|
1230
+ | `path.deal_id` | `string` | yes | Deal id. |
1231
+
1232
+ **Returns** `ApiResponse_DealContactListResponse_`: the envelope `{ data: DealContactListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1233
+
1234
+ Other envelope fields: `pagination` (PaginationMeta).
1235
+
1236
+ `DealContactListResponse` fields:
1237
+
1238
+ | Field | Type | Required | Description |
1239
+ |---|---|---|---|
1240
+ | `contacts` | `Array<DealContact>` | no | |
1241
+ | `total` | `integer` | no | default `0` |
1242
+
1243
+ **Example**
1244
+
1245
+ ```ts
1246
+ const result = await g8.api.deals.listDealContacts({ path: { deal_id: "id" } });
1247
+ ```
1248
+
1249
+ ---
1250
+
1251
+ <a id="op-listdealcustomfielddiconfig"></a>
1252
+
1253
+ ### `g8.api.deals.listDealCustomFieldDiConfig(input?)`
1254
+
1255
+ **List Deal Custom Field Di Config**
1256
+
1257
+ - HTTP: `GET /api/v1/deals/custom-fields/di-config`
1258
+ - operationId: `list_deal_custom_field_di_config_deals_custom_fields_di_config_get` (also callable as `g8.api.call("list_deal_custom_field_di_config_deals_custom_fields_di_config_get", input)`)
1259
+ - Tier: `read`: reads data; safe to call and to retry
1260
+ - API-key scope: `deals:read`
1261
+
1262
+ Which deal custom fields exist and how they map outward.
1263
+
1264
+ No per-record gate: this is org-level configuration, not a deal.
1265
+
1266
+ NOTE ON ROUTING ORDER: this path is LITERAL and would otherwise be
1267
+ swallowed by `/deals/{deal_id}` in the existing deals router, which would
1268
+ read "custom-fields" as a deal id. That is why this router is registered
1269
+ BEFORE it in `app.py` - see the comment there.
1270
+
1271
+ **Input**
1272
+
1273
+ | Field | Type | Required | Description |
1274
+ |---|---|---|---|
1275
+ | `query.crm_provider` | `string \| null` | no | Filter to one CRM provider's mappings. |
1276
+
1277
+ **Returns** `ApiResponse_CustomFieldDiConfigListResponse_`: the envelope `{ data: CustomFieldDiConfigListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1278
+
1279
+ Other envelope fields: `pagination` (PaginationMeta).
1280
+
1281
+ `CustomFieldDiConfigListResponse` fields:
1282
+
1283
+ | Field | Type | Required | Description |
1284
+ |---|---|---|---|
1285
+ | `configs` | `Array<Record<string, unknown>>` | no | |
1286
+ | `total` | `integer` | no | default `0` |
1287
+
1288
+ **Example**
1289
+
1290
+ ```ts
1291
+ const result = await g8.api.deals.listDealCustomFieldDiConfig();
1292
+ ```
1293
+
1294
+ ---
1295
+
1296
+ <a id="op-listdealdocuments"></a>
1297
+
1298
+ ### `g8.api.deals.listDealDocuments(input)`
1299
+
1300
+ **List Deal Documents**
1301
+
1302
+ - HTTP: `GET /api/v1/deals/{deal_id}/documents`
1303
+ - operationId: `list_deal_documents_deals__deal_id__documents_get` (also callable as `g8.api.call("list_deal_documents_deals__deal_id__documents_get", input)`)
1304
+ - Tier: `read`: reads data; safe to call and to retry
1305
+ - API-key scope: `deals:read`
1306
+
1307
+ Every generated document on this deal, newest first.
1308
+
1309
+ Carries each document's body, so it is the wrong read for a poll loop -
1310
+ use `/documents/generation-status` for that.
1311
+
1312
+ **Input**
1313
+
1314
+ | Field | Type | Required | Description |
1315
+ |---|---|---|---|
1316
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
1317
+ | `query.folder` | `string \| null` | no | `strategy` or `analysis`. Not validated by the app - an unrecognised folder matches nothing rather than failing. |
1318
+
1319
+ **Returns** `ApiResponse_DocumentListPayload_`: the envelope `{ data: DocumentListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1320
+
1321
+ Other envelope fields: `pagination` (PaginationMeta).
1322
+
1323
+ `DocumentListPayload` fields:
1324
+
1325
+ | Field | Type | Required | Description |
1326
+ |---|---|---|---|
1327
+ | `items` | `Array<unknown>` | no | |
1328
+
1329
+ **Example**
1330
+
1331
+ ```ts
1332
+ const result = await g8.api.deals.listDealDocuments({ path: { deal_id: "id" } });
1333
+ ```
1334
+
1335
+ ---
1336
+
1337
+ <a id="op-listdealhistory"></a>
1338
+
1339
+ ### `g8.api.deals.listDealHistory(input)`
1340
+
1341
+ **List Deal History**
1342
+
1343
+ - HTTP: `GET /api/v1/deals/{deal_id}/history`
1344
+ - operationId: `list_deal_history_deals__deal_id__history_get` (also callable as `g8.api.call("list_deal_history_deals__deal_id__history_get", input)`)
1345
+ - Tier: `read`: reads data; safe to call and to retry
1346
+ - API-key scope: `deals:read`
1347
+
1348
+ What changed on this deal, and who changed it.
1349
+
1350
+ **Input**
1351
+
1352
+ | Field | Type | Required | Description |
1353
+ |---|---|---|---|
1354
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
1355
+ | `query.limit` | `integer` | no | The app's cap, and it is a real ceiling rather than a default to raise: a long history pages through `offset`. default `200` |
1356
+ | `query.offset` | `integer` | no | default `0` |
1357
+
1358
+ **Returns** `ApiResponse_DealCollectionPayload_`: the envelope `{ data: DealCollectionPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1359
+
1360
+ Other envelope fields: `pagination` (PaginationMeta).
1361
+
1362
+ `DealCollectionPayload` fields:
1363
+
1364
+ | Field | Type | Required | Description |
1365
+ |---|---|---|---|
1366
+ | `items` | `Array<unknown>` | no | |
1367
+
1368
+ **Example**
1369
+
1370
+ ```ts
1371
+ const result = await g8.api.deals.listDealHistory({ path: { deal_id: "id" } });
1372
+ ```
1373
+
1374
+ ---
1375
+
1376
+ <a id="op-listdeallineitems"></a>
1377
+
1378
+ ### `g8.api.deals.listDealLineItems(input)`
1379
+
1380
+ **List Deal Line Items**
1381
+
1382
+ - HTTP: `GET /api/v1/deals/{deal_id}/line-items`
1383
+ - operationId: `list_deal_line_items_deals__deal_id__line_items_get` (also callable as `g8.api.call("list_deal_line_items_deals__deal_id__line_items_get", input)`)
1384
+ - Tier: `read`: reads data; safe to call and to retry
1385
+ - API-key scope: `deals:read`
1386
+
1387
+ A deal's line items, its derived amount, and whether it disagrees with its linked quote.
1388
+
1389
+ **Input**
1390
+
1391
+ | Field | Type | Required | Description |
1392
+ |---|---|---|---|
1393
+ | `path.deal_id` | `string` | yes | Deal id. |
1394
+
1395
+ **Returns** `ApiResponse_DealLineItemsPayload_`: the envelope `{ data: DealLineItemsPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1396
+
1397
+ Other envelope fields: `pagination` (PaginationMeta).
1398
+
1399
+ `DealLineItemsPayload` fields:
1400
+
1401
+ | Field | Type | Required | Description |
1402
+ |---|---|---|---|
1403
+ | `deal_id` | `string` | yes | |
1404
+ | `amount` | `number \| null` | no | |
1405
+ | `amount_mismatch` | `boolean` | no | default `false` |
1406
+ | `currency` | `string \| null` | no | |
1407
+ | `line_items` | `Array<DealLineItemRecord>` | no | |
1408
+ | `linked_quote_total` | `number \| null` | no | |
1409
+
1410
+ **Example**
1411
+
1412
+ ```ts
1413
+ const result = await g8.api.deals.listDealLineItems({ path: { deal_id: "id" } });
1414
+ ```
1415
+
1416
+ ---
1417
+
1418
+ <a id="op-listdeals"></a>
1419
+
1420
+ ### `g8.api.deals.listDeals(input?)`
1421
+
1422
+ **List Deals**
1423
+
1424
+ - HTTP: `GET /api/v1/deals`
1425
+ - operationId: `list_deals_deals_get` (also callable as `g8.api.call("list_deals_deals_get", input)`)
1426
+ - Tier: `read`: reads data; safe to call and to retry
1427
+ - API-key scope: `deals:read`
1428
+ - ★ Hand-written: [`g8.deals.list()`](../sdk-clients.md#g8-deals-list)
1429
+
1430
+ List all deals org-wide with optional filters and pagination.
1431
+
1432
+ **Input**
1433
+
1434
+ | Field | Type | Required | Description |
1435
+ |---|---|---|---|
1436
+ | `query.page` | `integer` | no | Page number default `1` |
1437
+ | `query.limit` | `integer` | no | Items per page default `50` |
1438
+ | `query.stage_id` | `string \| null` | no | Filter by stage ID |
1439
+ | `query.pipeline_id` | `string \| null` | no | Filter by pipeline ID |
1440
+ | `query.search` | `string \| null` | no | Search by deal name |
1441
+ | `query.owner_id` | `string \| null` | no | Filter by owner ID |
1442
+ | `query.owner_email` | `string \| null` | no | Filter by owner email |
1443
+ | `query.outcome` | `"won" \| "lost" \| "open" \| null` | no | Filter by deal outcome. A deal is won, lost, or open - exactly one. Prefer this over is_closed_won: the boolean's false branch means 'not won', which returns open AND unclassified deals alongside lost ones, and is the wrong cohort for closed-lost re-engagement. |
1444
+ | `query.is_closed_won` | `boolean \| null` | no | LEGACY - prefer outcome=. Retained for backwards compatibility with existing consumers. true means won; false means NOT won (open, lost and unclassified deals), which is rarely what a caller intends. |
1445
+ | `query.last_activity_before` | `string (date-time) \| null` | no | Only deals last touched before this timestamp |
1446
+ | `query.stale_before` | `string (date-time) \| null` | no | Deals last touched before this timestamp OR never touched at all. Union of last_activity_before and the no-activity cohort - use this for 'my stale deals' (last_activity_before alone excludes deals with no recorded activity, since NULL is never earlier-than). |
1447
+ | `query.has_activity` | `boolean \| null` | no | Filter by whether the deal has recorded activity |
1448
+ | `query.has_contact` | `boolean \| null` | no | Filter by whether the deal has a route to any contact. false returns the orphaned-deal cohort: no cb_deal_contacts row AND no live primary contact (a primary_contact_id pointing at a soft-deleted or merged-away contact counts as no route). Same definition the Data Quality panel counts, so the two can never disagree. |
1449
+ | `query.close_after` | `string (date-time) \| null` | no | Only deals whose close_date is on/after this timestamp (inclusive lower bound). Pair with close_before for a period window, and with outcome=won for 'deals we closed-won in this period'. A period count needs BOTH a lower bound and the outcome join: close_before alone sums the entire deal history into every period. Deals with a NULL close_date are excluded (a deal with no close date is not closing… |
1450
+ | `query.close_before` | `string (date-time) \| null` | no | Only deals whose close_date is strictly before this timestamp (exclusive upper bound). The window is half-open [close_after, close_before) so adjacent periods never double-count a deal that closes exactly on a boundary. A naive timestamp is treated as UTC (the close_date column is timestamp without time zone). |
1451
+
1452
+ **Returns** `ApiResponse_list_DealResponse__`: the envelope `{ data: Array<DealResponse>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1453
+
1454
+ Other envelope fields: `pagination` (PaginationMeta).
1455
+
1456
+ `DealResponse` fields:
1457
+
1458
+ | Field | Type | Required | Description |
1459
+ |---|---|---|---|
1460
+ | `amount` | `number \| null` | no | |
1461
+ | `close_date` | `string \| null` | no | |
1462
+ | `closed_lost_reason` | `string \| null` | no | |
1463
+ | `company_id` | `unknown \| null` | no | |
1464
+ | `contact_count` | `integer` | no | default `0` |
1465
+ | `contacts` | `Array<ContactBrief> \| null` | no | |
1466
+ | `created_at` | `string \| null` | no | |
1467
+ | `currency` | `string \| null` | no | |
1468
+ | `description` | `string \| null` | no | |
1469
+ | `id` | `string \| null` | no | |
1470
+ | `last_activity_at` | `string \| null` | no | |
1471
+ | `name` | `string \| null` | no | |
1472
+ | `owner_email` | `string \| null` | no | |
1473
+ | `owner_id` | `string \| null` | no | |
1474
+ | `owner_name` | `string \| null` | no | |
1475
+ | `pipeline_id` | `string \| null` | no | |
1476
+ | `primary_contact` | `ContactBrief \| null` | no | |
1477
+ | `revision` | `integer \| null` | no | CRM revision after a conditional update |
1478
+ | `stage_id` | `string \| null` | no | |
1479
+ | `stage_name` | `string \| null` | no | |
1480
+ | `updated_at` | `string \| null` | no | |
1481
+
1482
+ **Example**
1483
+
1484
+ ```ts
1485
+ const result = await g8.api.deals.listDeals();
1486
+ ```
1487
+
1488
+ ---
1489
+
1490
+ <a id="op-listpipelines"></a>
1491
+
1492
+ ### `g8.api.deals.listPipelines(input?)`
1493
+
1494
+ **List Pipelines**
1495
+
1496
+ - HTTP: `GET /api/v1/deals/pipelines`
1497
+ - operationId: `list_pipelines_deals_pipelines_get` (also callable as `g8.api.call("list_pipelines_deals_pipelines_get", input)`)
1498
+ - Tier: `read`: reads data; safe to call and to retry
1499
+ - API-key scope: `deals:read`
1500
+ - ★ Hand-written: [`g8.deals.pipelines()`](../sdk-clients.md#g8-deals-pipelines)
1501
+
1502
+ List all deal pipelines and their stages.
1503
+
1504
+ **Input**: none.
1505
+
1506
+ **Returns** `ApiResponse_list_PipelineResponse__`: the envelope `{ data: Array<PipelineResponse>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1507
+
1508
+ Other envelope fields: `pagination` (PaginationMeta).
1509
+
1510
+ `PipelineResponse` fields:
1511
+
1512
+ | Field | Type | Required | Description |
1513
+ |---|---|---|---|
1514
+ | `id` | `string` | yes | |
1515
+ | `name` | `string` | yes | |
1516
+ | `is_default` | `boolean` | no | default `false` |
1517
+ | `stages` | `Array<PipelineStageResponse>` | no | default `[]` |
1518
+
1519
+ **Example**
1520
+
1521
+ ```ts
1522
+ const result = await g8.api.deals.listPipelines();
1523
+ ```
1524
+
1525
+ ---
1526
+
1527
+ <a id="op-mergedeal"></a>
1528
+
1529
+ ### `g8.api.deals.mergeDeal(input)`
1530
+
1531
+ **Merge Deal**
1532
+
1533
+ - HTTP: `POST /api/v1/deals/{deal_id}/merge`
1534
+ - operationId: `merge_deal_deals__deal_id__merge_post` (also callable as `g8.api.call("merge_deal_deals__deal_id__merge_post", input)`)
1535
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
1536
+ - API-key scope: `deals:delete`
1537
+
1538
+ Merge `secondary_id` into this deal. NOT REVERSIBLE.
1539
+
1540
+ The secondary deal stops existing; its contacts, notes and activity move
1541
+ onto the survivor. `field_overrides` is the only way to keep a value from
1542
+ the deal being merged away.
1543
+
1544
+ Preview it first. There is no unmerge.
1545
+
1546
+ **Input**
1547
+
1548
+ | Field | Type | Required | Description |
1549
+ |---|---|---|---|
1550
+ | `path.deal_id` | `string` | yes | The deal that SURVIVES. |
1551
+ | `body` | `MergeDealRequest` | yes | Request body; fields below. |
1552
+
1553
+ Body fields (`MergeDealRequest`):
1554
+
1555
+ | Field | Type | Required | Description |
1556
+ |---|---|---|---|
1557
+ | `body.secondary_id` | `string` | yes | The deal to merge AWAY. Must be a UUID; the path deal survives. |
1558
+ | `body.field_overrides` | `Array<DealFieldOverride>` | no | Decide individual fields yourself instead of taking the app's rules. |
1559
+ | `body.suggestion_id` | `string \| null` | no | The duplicate-suggestion this merge acts on, if any. |
1560
+ | `body.trigger` | `"manual" \| "queue" \| "bulk_criterion"` | no | What prompted the merge. Recorded on the audit row. default `"manual"` |
1561
+
1562
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1563
+
1564
+ Other envelope fields: `pagination` (PaginationMeta).
1565
+
1566
+ **Example**
1567
+
1568
+ ```ts
1569
+ // destructive: deletes or archives data; confirm with a human before calling.
1570
+ const result = await g8.api.deals.mergeDeal({ path: { deal_id: "id" }, body: { secondary_id: "id" } });
1571
+ ```
1572
+
1573
+ ---
1574
+
1575
+ <a id="op-movedealtopipeline"></a>
1576
+
1577
+ ### `g8.api.deals.moveDealToPipeline(input)`
1578
+
1579
+ **Move Deal To Pipeline**
1580
+
1581
+ - HTTP: `PUT /api/v1/deals/{deal_id}/pipeline`
1582
+ - operationId: `move_deal_to_pipeline_deals__deal_id__pipeline_put` (also callable as `g8.api.call("move_deal_to_pipeline_deals__deal_id__pipeline_put", input)`)
1583
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1584
+ - API-key scope: `deals:write`
1585
+
1586
+ Move a deal into a different pipeline.
1587
+
1588
+ The deal keeps its identity and history. Its STAGE does not carry over -
1589
+ the target pipeline has its own stages and the app re-seats the deal within
1590
+ them, so a caller should read the deal back rather than assume its stage.
1591
+
1592
+ The path is `/pipeline` rather than the app's `/move-pipeline`: the verb is
1593
+ already in the PUT.
1594
+
1595
+ **Input**
1596
+
1597
+ | Field | Type | Required | Description |
1598
+ |---|---|---|---|
1599
+ | `path.deal_id` | `string` | yes | Deal id. |
1600
+ | `body` | `DealMovePipelineRequest` | yes | Request body; fields below. |
1601
+
1602
+ Body fields (`DealMovePipelineRequest`):
1603
+
1604
+ | Field | Type | Required | Description |
1605
+ |---|---|---|---|
1606
+ | `body.target_pipeline_id` | `string` | yes | Pipeline to move the deal into. |
1607
+
1608
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1609
+
1610
+ Other envelope fields: `pagination` (PaginationMeta).
1611
+
1612
+ **Example**
1613
+
1614
+ ```ts
1615
+ const result = await g8.api.deals.moveDealToPipeline({ path: { deal_id: "id" }, body: { target_pipeline_id: "id" } });
1616
+ ```
1617
+
1618
+ ---
1619
+
1620
+ <a id="op-previewdealmerge"></a>
1621
+
1622
+ ### `g8.api.deals.previewDealMerge(input)`
1623
+
1624
+ **Preview Deal Merge**
1625
+
1626
+ - HTTP: `GET /api/v1/deals/{deal_id}/merge/preview`
1627
+ - operationId: `preview_deal_merge_deals__deal_id__merge_preview_get` (also callable as `g8.api.call("preview_deal_merge_deals__deal_id__merge_preview_get", input)`)
1628
+ - Tier: `read`: reads data; safe to call and to retry
1629
+ - API-key scope: `deals:read`
1630
+
1631
+ What the merge WOULD do. Changes nothing.
1632
+
1633
+ Worth calling first for the same reason the app does: merging is not
1634
+ reversible, and this is the only place that says which field values change
1635
+ and which records move before they do.
1636
+
1637
+ **Input**
1638
+
1639
+ | Field | Type | Required | Description |
1640
+ |---|---|---|---|
1641
+ | `path.deal_id` | `string` | yes | The deal that SURVIVES. |
1642
+ | `query.secondary` | `string` | yes | The deal that would be merged AWAY. |
1643
+
1644
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1645
+
1646
+ Other envelope fields: `pagination` (PaginationMeta).
1647
+
1648
+ **Example**
1649
+
1650
+ ```ts
1651
+ const result = await g8.api.deals.previewDealMerge({ path: { deal_id: "id" }, query: { secondary: "example" } });
1652
+ ```
1653
+
1654
+ ---
1655
+
1656
+ <a id="op-regeneratedealdocument"></a>
1657
+
1658
+ ### `g8.api.deals.regenerateDealDocument(input)`
1659
+
1660
+ **Regenerate Deal Document**
1661
+
1662
+ - HTTP: `POST /api/v1/deals/{deal_id}/documents/types/{doc_type}/regenerate`
1663
+ - operationId: `regenerate_deal_document_deals__deal_id__documents_types__doc_type__regenerate_post` (also callable as `g8.api.call("regenerate_deal_document_deals__deal_id__documents_types__doc_type__regenerate_post", input)`)
1664
+ - Tier: `billable`: spends credits; the SDK never blindly retries it; confirm cost before bulk use
1665
+ - API-key scope: `deals:run`
1666
+
1667
+ Re-write a document that already exists. SPENDS CREDITS.
1668
+
1669
+ The difference from `/generate` is what happens when the document is
1670
+ MISSING: this 404s, `/generate` creates it. Use this when you want to be
1671
+ sure you are replacing rather than creating.
1672
+
1673
+ **Input**
1674
+
1675
+ | Field | Type | Required | Description |
1676
+ |---|---|---|---|
1677
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
1678
+ | `path.doc_type` | `"deal_risks" \| "next_steps" \| "close_plan" \| "scope_of_work" \| "roi_analysis" \| "competitive_analysis"` | yes | Which generated document. One of the six the deal synthesis produces; anything else is a 422 naming them. |
1679
+
1680
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1681
+
1682
+ Other envelope fields: `pagination` (PaginationMeta).
1683
+
1684
+ **Example**
1685
+
1686
+ ```ts
1687
+ // billable: spends credits; the SDK never blindly retries it; confirm cost before bulk use.
1688
+ const result = await g8.api.deals.regenerateDealDocument({ path: { deal_id: "id", doc_type: "deal_risks" } });
1689
+ ```
1690
+
1691
+ ---
1692
+
1693
+ <a id="op-removedealcontact"></a>
1694
+
1695
+ ### `g8.api.deals.removeDealContact(input)`
1696
+
1697
+ **Remove Deal Contact**
1698
+
1699
+ - HTTP: `DELETE /api/v1/deals/{deal_id}/contacts/{person_id}`
1700
+ - operationId: `remove_deal_contact_deals__deal_id__contacts__person_id__delete` (also callable as `g8.api.call("remove_deal_contact_deals__deal_id__contacts__person_id__delete", input)`)
1701
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
1702
+ - API-key scope: `deals:delete`
1703
+
1704
+ Unlink a contact from the deal. The contact record itself is untouched.
1705
+
1706
+ **Input**
1707
+
1708
+ | Field | Type | Required | Description |
1709
+ |---|---|---|---|
1710
+ | `path.deal_id` | `string` | yes | Deal id. |
1711
+ | `path.person_id` | `string` | yes | Contact id. |
1712
+
1713
+ **Returns**: no JSON body is declared for the success response.
1714
+
1715
+ **Example**
1716
+
1717
+ ```ts
1718
+ // destructive: deletes or archives data; confirm with a human before calling.
1719
+ const result = await g8.api.deals.removeDealContact({ path: { deal_id: "id", person_id: "id" } });
1720
+ ```
1721
+
1722
+ ---
1723
+
1724
+ <a id="op-replacedeallineitems"></a>
1725
+
1726
+ ### `g8.api.deals.replaceDealLineItems(input)`
1727
+
1728
+ **Replace Deal Line Items**
1729
+
1730
+ - HTTP: `PUT /api/v1/deals/{deal_id}/line-items`
1731
+ - operationId: `replace_deal_line_items_deals__deal_id__line_items_put` (also callable as `g8.api.call("replace_deal_line_items_deals__deal_id__line_items_put", input)`)
1732
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1733
+ - API-key scope: `deals:write`
1734
+
1735
+ Replace a deal's line items. The FULL set, not a delta.
1736
+
1737
+ A non-empty set makes the deal amount the sum of the lines (audited in the
1738
+ deal history). An empty set clears the lines and keeps the typed amount.
1739
+
1740
+ **Input**
1741
+
1742
+ | Field | Type | Required | Description |
1743
+ |---|---|---|---|
1744
+ | `path.deal_id` | `string` | yes | Deal id. |
1745
+ | `body` | `DealLineItemsReplaceBody` | yes | Request body; fields below. |
1746
+
1747
+ Body fields (`DealLineItemsReplaceBody`):
1748
+
1749
+ | Field | Type | Required | Description |
1750
+ |---|---|---|---|
1751
+ | `body.line_items` | `Array<DealLineItemWrite>` | no | |
1752
+
1753
+ **Returns** `ApiResponse_DealLineItemsPayload_`: the envelope `{ data: DealLineItemsPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1754
+
1755
+ Other envelope fields: `pagination` (PaginationMeta).
1756
+
1757
+ `DealLineItemsPayload` fields:
1758
+
1759
+ | Field | Type | Required | Description |
1760
+ |---|---|---|---|
1761
+ | `deal_id` | `string` | yes | |
1762
+ | `amount` | `number \| null` | no | |
1763
+ | `amount_mismatch` | `boolean` | no | default `false` |
1764
+ | `currency` | `string \| null` | no | |
1765
+ | `line_items` | `Array<DealLineItemRecord>` | no | |
1766
+ | `linked_quote_total` | `number \| null` | no | |
1767
+
1768
+ **Example**
1769
+
1770
+ ```ts
1771
+ const result = await g8.api.deals.replaceDealLineItems({ path: { deal_id: "id" }, body: {} });
1772
+ ```
1773
+
1774
+ ---
1775
+
1776
+ <a id="op-setdealcolumnvalues"></a>
1777
+
1778
+ ### `g8.api.deals.setDealColumnValues(input)`
1779
+
1780
+ **Set Deal Column Values**
1781
+
1782
+ - HTTP: `PUT /api/v1/deals/{deal_id}/columns/values`
1783
+ - operationId: `set_deal_column_values_deals__deal_id__columns_values_put` (also callable as `g8.api.call("set_deal_column_values_deals__deal_id__columns_values_put", input)`)
1784
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1785
+ - API-key scope: `deals:write`
1786
+
1787
+ Write custom column values on one deal.
1788
+
1789
+ A null CLEARS that column rather than leaving it alone. Keys come from
1790
+ `GET /deals/columns`; anything else is refused.
1791
+
1792
+ **Input**
1793
+
1794
+ | Field | Type | Required | Description |
1795
+ |---|---|---|---|
1796
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
1797
+ | `body` | `SetDealColumnValuesRequest` | yes | Request body; fields below. |
1798
+ | `query.list_id` | `integer \| null` | no | Resolve list-scoped columns against this list. |
1799
+
1800
+ Body fields (`SetDealColumnValuesRequest`):
1801
+
1802
+ | Field | Type | Required | Description |
1803
+ |---|---|---|---|
1804
+ | `body.values` | `Record<string, string \| integer \| number \| boolean \| null>` | yes | Column key -> value. A null clears that column. |
1805
+
1806
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1807
+
1808
+ Other envelope fields: `pagination` (PaginationMeta).
1809
+
1810
+ **Example**
1811
+
1812
+ ```ts
1813
+ const result = await g8.api.deals.setDealColumnValues({ path: { deal_id: "id" }, body: { values: {} } });
1814
+ ```
1815
+
1816
+ ---
1817
+
1818
+ <a id="op-setdealcompany"></a>
1819
+
1820
+ ### `g8.api.deals.setDealCompany(input)`
1821
+
1822
+ **Set Deal Company**
1823
+
1824
+ - HTTP: `PUT /api/v1/deals/{deal_id}/company`
1825
+ - operationId: `set_deal_company_deals__deal_id__company_put` (also callable as `g8.api.call("set_deal_company_deals__deal_id__company_put", input)`)
1826
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1827
+ - API-key scope: `deals:write`
1828
+
1829
+ Attach or change the company on a deal.
1830
+
1831
+ `mashup_company_id` is the CANONICAL company id, not a
1832
+ `cb_company_extensions` / ABM overlay id. They are different tables with
1833
+ different ids, and the wrong one attaches the deal to nothing.
1834
+
1835
+ **Input**
1836
+
1837
+ | Field | Type | Required | Description |
1838
+ |---|---|---|---|
1839
+ | `path.deal_id` | `string` | yes | Deal id. |
1840
+ | `body` | `DealCompanyRequest` | yes | Request body; fields below. |
1841
+
1842
+ Body fields (`DealCompanyRequest`):
1843
+
1844
+ | Field | Type | Required | Description |
1845
+ |---|---|---|---|
1846
+ | `body.mashup_company_id` | `integer` | yes | The CANONICAL company id (`mashup_companies`), not a `cb_company_extensions` / ABM overlay id. The two are different tables with different ids and passing the wrong one attaches the deal to nothing. |
1847
+
1848
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1849
+
1850
+ Other envelope fields: `pagination` (PaginationMeta).
1851
+
1852
+ **Example**
1853
+
1854
+ ```ts
1855
+ const result = await g8.api.deals.setDealCompany({ path: { deal_id: "id" }, body: { mashup_company_id: 123 } });
1856
+ ```
1857
+
1858
+ ---
1859
+
1860
+ <a id="op-setdealcontactrole"></a>
1861
+
1862
+ ### `g8.api.deals.setDealContactRole(input)`
1863
+
1864
+ **Set Deal Contact Role**
1865
+
1866
+ - HTTP: `PUT /api/v1/deals/{deal_id}/contacts/{contact_id}`
1867
+ - operationId: `set_deal_contact_role_deals__deal_id__contacts__contact_id__put` (also callable as `g8.api.call("set_deal_contact_role_deals__deal_id__contacts__contact_id__put", input)`)
1868
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1869
+ - API-key scope: `deals:write`
1870
+
1871
+ Set (or clear) a contact's buying-committee role on a deal.
1872
+
1873
+ The role lives on the deal-contact LINK (`cb_deal_contacts.role`), not on
1874
+ the contact: the same person can be a champion on one deal and an end user
1875
+ on another. This endpoint only re-roles an EXISTING link — it never
1876
+ creates one, so attaching and roling stay separately auditable. Use
1877
+ ``PATCH /deals/{deal_id}`` with ``add_contact_ids`` (optionally alongside
1878
+ ``contact_roles``) to link a contact first.
1879
+
1880
+ ``{contact_id}`` is the ``mashup_contact_id``, the same integer id this API
1881
+ uses for a contact everywhere else (``GET /contacts/{id}``, the ``id`` on
1882
+ every ``ContactBrief``). The internal app route calls the identical value
1883
+ ``{person_id}``; that name is a historical misnomer and is not repeated
1884
+ here.
1885
+
1886
+ Body is ``{"role": "champion"}``; an explicit ``{"role": null}`` clears the
1887
+ role. ``role`` is required — an empty body is a 422, because a PUT that
1888
+ names no new state for the sub-resource is a caller bug, and reading
1889
+ omission as "clear" would destroy data on a typo.
1890
+
1891
+ Returns the updated contact. 404 when the deal does not exist in this org
1892
+ or the contact is not linked to it; 422 on a role outside the vocabulary.
1893
+
1894
+ **Input**
1895
+
1896
+ | Field | Type | Required | Description |
1897
+ |---|---|---|---|
1898
+ | `path.deal_id` | `string` | yes | Deal ID (UUID) |
1899
+ | `path.contact_id` | `integer` | yes | mashup_contact_id (BigInt) of a contact already linked to this deal |
1900
+ | `body` | `DealContactRoleUpdateRequest` | yes | Request body; fields below. |
1901
+
1902
+ Body fields (`DealContactRoleUpdateRequest`):
1903
+
1904
+ | Field | Type | Required | Description |
1905
+ |---|---|---|---|
1906
+ | `body.role` | `string \| null` | yes | Buying-committee role for this contact on this deal. One of: champion, decision_maker, influencer, blocker, coach, end_user. Pass null to clear the role. |
1907
+
1908
+ **Returns** `ApiResponse_ContactBrief_`: the envelope `{ data: ContactBrief, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1909
+
1910
+ Other envelope fields: `pagination` (PaginationMeta).
1911
+
1912
+ `ContactBrief` fields:
1913
+
1914
+ | Field | Type | Required | Description |
1915
+ |---|---|---|---|
1916
+ | `id` | `integer` | yes | |
1917
+ | `email` | `string \| null` | no | |
1918
+ | `name` | `string \| null` | no | |
1919
+ | `role` | `string \| null` | no | |
1920
+ | `title` | `string \| null` | no | |
1921
+
1922
+ **Example**
1923
+
1924
+ ```ts
1925
+ const result = await g8.api.deals.setDealContactRole({
1926
+ path: { deal_id: "id", contact_id: 123 },
1927
+ body: { role: "example" },
1928
+ });
1929
+ ```
1930
+
1931
+ ---
1932
+
1933
+ <a id="op-setprimarydealcontact"></a>
1934
+
1935
+ ### `g8.api.deals.setPrimaryDealContact(input)`
1936
+
1937
+ **Set Primary Deal Contact**
1938
+
1939
+ - HTTP: `PUT /api/v1/deals/{deal_id}/contacts/{person_id}/primary`
1940
+ - operationId: `set_primary_deal_contact_deals__deal_id__contacts__person_id__primary_put` (also callable as `g8.api.call("set_primary_deal_contact_deals__deal_id__contacts__person_id__primary_put", input)`)
1941
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1942
+ - API-key scope: `deals:write`
1943
+
1944
+ Make this person the deal's primary contact.
1945
+
1946
+ A deal has ONE primary, so this demotes whoever held it - there is no
1947
+ separate call to unset the previous one.
1948
+
1949
+ **Input**
1950
+
1951
+ | Field | Type | Required | Description |
1952
+ |---|---|---|---|
1953
+ | `path.deal_id` | `string` | yes | Deal id. |
1954
+ | `path.person_id` | `string` | yes | Contact id to make primary. |
1955
+
1956
+ **Returns** `ApiResponse_DealContact_`: the envelope `{ data: DealContact, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1957
+
1958
+ Other envelope fields: `pagination` (PaginationMeta).
1959
+
1960
+ `DealContact` fields:
1961
+
1962
+ | Field | Type | Required | Description |
1963
+ |---|---|---|---|
1964
+ | `buying_role` | `string \| null` | no | General buying role from the contact record. |
1965
+ | `created_at` | `string (date-time) \| null` | no | |
1966
+ | `email` | `string \| null` | no | |
1967
+ | `id` | `string \| null` | no | Link id, not the person id. |
1968
+ | `is_primary` | `boolean \| null` | no | |
1969
+ | `name` | `string \| null` | no | |
1970
+ | `person_id` | `string \| null` | no | |
1971
+ | `role` | `string \| null` | no | Role on THIS deal. |
1972
+ | `title` | `string \| null` | no | |
1973
+
1974
+ **Example**
1975
+
1976
+ ```ts
1977
+ const result = await g8.api.deals.setPrimaryDealContact({ path: { deal_id: "id", person_id: "id" } });
1978
+ ```
1979
+
1980
+ ---
1981
+
1982
+ <a id="op-setrivalattach"></a>
1983
+
1984
+ ### `g8.api.deals.setRivalAttach(input)`
1985
+
1986
+ **Set Rival Attach**
1987
+
1988
+ - HTTP: `POST /api/v1/deals/{deal_id}/rival-attach`
1989
+ - operationId: `set_rival_attach_deals__deal_id__rival_attach_post` (also callable as `g8.api.call("set_rival_attach_deals__deal_id__rival_attach_post", input)`)
1990
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1991
+ - API-key scope: `deals:write`
1992
+
1993
+ Record which competitor is on this deal, and how it is going.
1994
+
1995
+ A null `competitor_id` DETACHES the current one - the same route both
1996
+ attaches and clears.
1997
+
1998
+ **Input**
1999
+
2000
+ | Field | Type | Required | Description |
2001
+ |---|---|---|---|
2002
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
2003
+ | `body` | `RivalAttachRequest` | yes | Request body; fields below. |
2004
+
2005
+ Body fields (`RivalAttachRequest`):
2006
+
2007
+ | Field | Type | Required | Description |
2008
+ |---|---|---|---|
2009
+ | `body.status` | `string` | yes | Where the deal stands against them. |
2010
+ | `body.competitor_id` | `string \| null` | no | The competitor. Null detaches the current one. |
2011
+
2012
+ **Returns** `ApiResponse_DealPayload_`: the envelope `{ data: DealPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2013
+
2014
+ Other envelope fields: `pagination` (PaginationMeta).
2015
+
2016
+ **Example**
2017
+
2018
+ ```ts
2019
+ const result = await g8.api.deals.setRivalAttach({ path: { deal_id: "id" }, body: { status: "example" } });
2020
+ ```
2021
+
2022
+ ---
2023
+
2024
+ <a id="op-updatedeal"></a>
2025
+
2026
+ ### `g8.api.deals.updateDeal(input)`
2027
+
2028
+ **Update Deal**
2029
+
2030
+ - HTTP: `PATCH /api/v1/deals/{deal_id}`
2031
+ - operationId: `update_deal_deals__deal_id__patch` (also callable as `g8.api.call("update_deal_deals__deal_id__patch", input)`)
2032
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2033
+ - API-key scope: `deals:write`
2034
+ - ★ Hand-written: [`g8.deals.update()`](../sdk-clients.md#g8-deals-update)
2035
+
2036
+ Update a deal (partial update).
2037
+
2038
+ Contact operations run in a fixed order within the single transaction:
2039
+ ``remove_contact_ids`` -> ``add_contact_ids`` -> ``contact_roles``. That
2040
+ order is what makes the useful combinations work:
2041
+
2042
+ * a contact linked by ``add_contact_ids`` in THIS request can be given a
2043
+ role by ``contact_roles`` in the same call (roles run last);
2044
+ * an id in both ``remove_contact_ids`` and ``add_contact_ids`` ends up
2045
+ linked (add runs after remove), so a role for it still applies;
2046
+ * an id in ``remove_contact_ids`` and ``contact_roles`` but NOT in
2047
+ ``add_contact_ids`` is unlinked by the time roles run, so it is a 422
2048
+ naming that id rather than a role written to a row that no longer
2049
+ exists.
2050
+
2051
+ A ``contact_roles`` entry for a contact that is neither already linked nor
2052
+ being added is a 422; the whole transaction rolls back, so a partially
2053
+ applied batch is not a state this endpoint can produce.
2054
+
2055
+ ``background_tasks`` carries the ``deal.stage_changed`` fan-out only. It is
2056
+ injected, not a body field, so it does not appear in the OpenAPI schema and
2057
+ the request contract is unchanged (pinned by
2058
+ ``developer_api/tests/test_deal_stage_events.py``). Publishing there rather
2059
+ than inline keeps the Redis round trip off the caller's latency budget and
2060
+ makes "strictly after the commit" structural: the task is queued only after
2061
+ the session context has exited, and FastAPI attaches background tasks to the
2062
+ SUCCESS response, so a raise anywhere above publishes nothing.
2063
+
2064
+ **Input**
2065
+
2066
+ | Field | Type | Required | Description |
2067
+ |---|---|---|---|
2068
+ | `path.deal_id` | `string` | yes | Deal ID (UUID) |
2069
+ | `body` | `DealUpdateRequest` | yes | Request body; fields below. |
2070
+
2071
+ Body fields (`DealUpdateRequest`):
2072
+
2073
+ | Field | Type | Required | Description |
2074
+ |---|---|---|---|
2075
+ | `body.add_contact_ids` | `Array<integer>` | no | mashup_contact_ids to add to the deal (must match the deal's company; idempotent) |
2076
+ | `body.amount` | `number \| null` | no | Deal monetary value |
2077
+ | `body.close_date` | `string \| null` | no | Expected close date (ISO 8601) |
2078
+ | `body.contact_roles` | `Record<string, string \| null> \| null` | no | Buying-committee roles keyed by mashup_contact_id, e.g. {"5500429": "champion", "5500914": null}. Valid roles: champion, decision_maker, influencer, blocker, coach, end_user. null clears a role. Each id must already be linked to the deal or be present in add_contact_ids in the same request (422 otherwise). |
2079
+ | `body.currency` | `string \| null` | no | Currency code |
2080
+ | `body.description` | `string \| null` | no | Deal description |
2081
+ | `body.expected_revision` | `integer \| null` | no | Apply only if the canonical CRM revision still matches; otherwise return 409. Omit for existing PATCH behavior. min 1 |
2082
+ | `body.name` | `string \| null` | no | Deal name |
2083
+ | `body.owner_id` | `string \| null` | no | Reassign deal owner (member id, email, or PropelAuth uid). Cannot be cleared. |
2084
+ | `body.remove_contact_ids` | `Array<integer>` | no | mashup_contact_ids to remove from the deal (idempotent — unlinked skipped) |
2085
+ | `body.stage_id` | `string \| null` | no | Stage ID |
2086
+
2087
+ **Returns** `ApiResponse_DealResponse_`: the envelope `{ data: DealResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2088
+
2089
+ Other envelope fields: `pagination` (PaginationMeta).
2090
+
2091
+ `DealResponse` fields:
2092
+
2093
+ | Field | Type | Required | Description |
2094
+ |---|---|---|---|
2095
+ | `amount` | `number \| null` | no | |
2096
+ | `close_date` | `string \| null` | no | |
2097
+ | `closed_lost_reason` | `string \| null` | no | |
2098
+ | `company_id` | `unknown \| null` | no | |
2099
+ | `contact_count` | `integer` | no | default `0` |
2100
+ | `contacts` | `Array<ContactBrief> \| null` | no | |
2101
+ | `created_at` | `string \| null` | no | |
2102
+ | `currency` | `string \| null` | no | |
2103
+ | `description` | `string \| null` | no | |
2104
+ | `id` | `string \| null` | no | |
2105
+ | `last_activity_at` | `string \| null` | no | |
2106
+ | `name` | `string \| null` | no | |
2107
+ | `owner_email` | `string \| null` | no | |
2108
+ | `owner_id` | `string \| null` | no | |
2109
+ | `owner_name` | `string \| null` | no | |
2110
+ | `pipeline_id` | `string \| null` | no | |
2111
+ | `primary_contact` | `ContactBrief \| null` | no | |
2112
+ | `revision` | `integer \| null` | no | CRM revision after a conditional update |
2113
+ | `stage_id` | `string \| null` | no | |
2114
+ | `stage_name` | `string \| null` | no | |
2115
+ | `updated_at` | `string \| null` | no | |
2116
+
2117
+ **Example**
2118
+
2119
+ ```ts
2120
+ const result = await g8.api.deals.updateDeal({ path: { deal_id: "id" }, body: {} });
2121
+ ```
2122
+
2123
+ ---
2124
+
2125
+ <a id="op-updatedealdocument"></a>
2126
+
2127
+ ### `g8.api.deals.updateDealDocument(input)`
2128
+
2129
+ **Update Deal Document**
2130
+
2131
+ - HTTP: `PUT /api/v1/deals/{deal_id}/documents/{document_id}`
2132
+ - operationId: `update_deal_document_deals__deal_id__documents__document_id__put` (also callable as `g8.api.call("update_deal_document_deals__deal_id__documents__document_id__put", input)`)
2133
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2134
+ - API-key scope: `deals:write`
2135
+
2136
+ Edit a generated document by hand.
2137
+
2138
+ Keyed by document ID, not by type - this is the one place the two
2139
+ identifier spaces differ, and it is why the type-keyed routes live under
2140
+ `/documents/types/`.
2141
+
2142
+ An omitted field is left alone; `structured_data` REPLACES the stored
2143
+ object rather than merging into it. A later regeneration OVERWRITES the
2144
+ edit, so edit last.
2145
+
2146
+ **Input**
2147
+
2148
+ | Field | Type | Required | Description |
2149
+ |---|---|---|---|
2150
+ | `path.deal_id` | `string` | yes | Deal id (UUID). |
2151
+ | `path.document_id` | `string` | yes | Document id, from the list read. |
2152
+ | `body` | `DealDocumentUpdateRequest` | yes | Request body; fields below. |
2153
+
2154
+ Body fields (`DealDocumentUpdateRequest`):
2155
+
2156
+ | Field | Type | Required | Description |
2157
+ |---|---|---|---|
2158
+ | `body.content` | `string \| null` | no | The document body. |
2159
+ | `body.structured_data` | `Record<string, unknown> \| null` | no | The machine-readable half. Replaces, does not merge. |
2160
+
2161
+ **Returns** `ApiResponse_DocumentPayload_`: the envelope `{ data: DocumentPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2162
+
2163
+ Other envelope fields: `pagination` (PaginationMeta).
2164
+
2165
+ **Example**
2166
+
2167
+ ```ts
2168
+ const result = await g8.api.deals.updateDealDocument({ path: { deal_id: "id", document_id: "id" }, body: {} });
2169
+ ```
2170
+
2171
+ ---
2172
+
2173
+ <a id="op-updatedealnote"></a>
2174
+
2175
+ ### `g8.api.deals.updateDealNote(input)`
2176
+
2177
+ **Update Deal Note**
2178
+
2179
+ - HTTP: `PUT /api/v1/deals/{deal_id}/notes/{note_id}`
2180
+ - operationId: `update_deal_note_deals__deal_id__notes__note_id__put` (also callable as `g8.api.call("update_deal_note_deals__deal_id__notes__note_id__put", input)`)
2181
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2182
+ - API-key scope: `deals:write`
2183
+
2184
+ Rewrite a note.
2185
+
2186
+ `content` is a full REPLACEMENT, not a patch, and `mentioned_users` is who
2187
+ is mentioned AFTER the edit - omitting someone removes their mention. Send
2188
+ the whole state you want, not the delta.
2189
+
2190
+ **Input**
2191
+
2192
+ | Field | Type | Required | Description |
2193
+ |---|---|---|---|
2194
+ | `path.deal_id` | `string` | yes | Deal id. |
2195
+ | `path.note_id` | `string` | yes | Note id. |
2196
+ | `body` | `DealNoteUpdateRequest` | yes | Request body; fields below. |
2197
+
2198
+ Body fields (`DealNoteUpdateRequest`):
2199
+
2200
+ | Field | Type | Required | Description |
2201
+ |---|---|---|---|
2202
+ | `body.content` | `string` | yes | Full replacement body - this is not a patch. |
2203
+ | `body.mentioned_users` | `Array<DealNoteMention>` | no | Who is mentioned AFTER the edit. Omitting someone removes their mention, because the list replaces rather than adds. |
2204
+
2205
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2206
+
2207
+ Other envelope fields: `pagination` (PaginationMeta).
2208
+
2209
+ **Example**
2210
+
2211
+ ```ts
2212
+ const result = await g8.api.deals.updateDealNote({
2213
+ path: { deal_id: "id", note_id: "id" },
2214
+ body: { content: "example" },
2215
+ });
2216
+ ```
2217
+
2218
+ ---
2219
+
2220
+ <a id="op-upsertdealcustomfielddiconfig"></a>
2221
+
2222
+ ### `g8.api.deals.upsertDealCustomFieldDiConfig(input)`
2223
+
2224
+ **Upsert Deal Custom Field Di Config**
2225
+
2226
+ - HTTP: `POST /api/v1/deals/custom-fields/di-config`
2227
+ - operationId: `upsert_deal_custom_field_di_config_deals_custom_fields_di_config_post` (also callable as `g8.api.call("upsert_deal_custom_field_di_config_deals_custom_fields_di_config_post", input)`)
2228
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2229
+ - API-key scope: `deals:write`
2230
+
2231
+ Replace the deal custom-field mappings.
2232
+
2233
+ ENTRY GATE: manager tier (DEALS_WRITE_TEAM / DEALS_WRITE_ALL /
2234
+ DEALS_MANAGE), the SAME route dependency the app declares - the values here
2235
+ are interpolated into the Deal Intelligence LLM prompt, so an own-scope rep
2236
+ must not be able to poison org-wide DI. The coarse `deals:write` scope does
2237
+ not distinguish own/team/all/manage, so this RBAC gate is what stops a
2238
+ rep-minted key reaching a manager-only surface.
2239
+
2240
+ `items` is the FULL desired set for the providers it names, not a delta -
2241
+ the app upserts exactly what is sent. The READ half of this pair shipped in
2242
+ #20744; this completes it.
2243
+
2244
+ **Input**
2245
+
2246
+ | Field | Type | Required | Description |
2247
+ |---|---|---|---|
2248
+ | `body` | `CustomFieldDiConfigUpsertRequest` | yes | Request body; fields below. |
2249
+
2250
+ Body fields (`CustomFieldDiConfigUpsertRequest`):
2251
+
2252
+ | Field | Type | Required | Description |
2253
+ |---|---|---|---|
2254
+ | `body.items` | `Array<CustomFieldDiConfigItem>` | yes | min items 1, max items 100 |
2255
+
2256
+ **Returns** `ApiResponse_DealOpResponse_`: the envelope `{ data: DealOpResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2257
+
2258
+ Other envelope fields: `pagination` (PaginationMeta).
2259
+
2260
+ **Example**
2261
+
2262
+ ```ts
2263
+ const result = await g8.api.deals.upsertDealCustomFieldDiConfig({ body: { items: [{ crm_provider: "example", field_id: "id" }] } });
2264
+ ```
2265
+
2266
+ ---
2267
+
2268
+ ## Referenced types
2269
+
2270
+ Named types that appear in the tables above. Full TypeScript definitions: `G8Contract.<Name>` (`import type { G8Contract } from "@graph8/sdk"`).
2271
+
2272
+ <a id="type-bulkdealchange"></a>
2273
+
2274
+ ### `BulkDealChange`
2275
+
2276
+ The change applied to EVERY deal in the batch. PUT semantics, and the distinction matters: `null` leaves a value alone, an EMPTY STRING clears it. So omitting a field and sending `""` are different instructions, and the second one is destructive.
2277
+
2278
+ | Field | Type | Required | Description |
2279
+ |---|---|---|---|
2280
+ | `amount` | `number \| null` | no | |
2281
+ | `close_date` | `string (date-time) \| null` | no | |
2282
+ | `currency` | `string \| null` | no | |
2283
+ | `custom_fields` | `Record<string, unknown> \| null` | no | |
2284
+ | `description` | `string \| null` | no | |
2285
+ | `next_step` | `string \| null` | no | |
2286
+ | `owner_id` | `string \| null` | no | |
2287
+ | `pipeline_id` | `string \| null` | no | |
2288
+ | `stage` | `string \| null` | no | |
2289
+ | `stage_id` | `string \| null` | no | |
2290
+
2291
+ <a id="type-customfielddiconfigitem"></a>
2292
+
2293
+ ### `CustomFieldDiConfigItem`
2294
+
2295
+ One custom-field mapping. Typed rather than left an open dict: `crm_provider` and `field_id` are REQUIRED upstream, and an open list let a missing one reach the app's model as a raw ValidationError from inside the proxy - a 500 for a plain client error. The 255 caps are the underlying VARCHAR widths, and `display_name` additionally feeds the Deal Intelligence LLM prompt, so its bound is a token-budget and prompt-injection concern rather than cosmetic.
2296
+
2297
+ | Field | Type | Required | Description |
2298
+ |---|---|---|---|
2299
+ | `crm_provider` | `string` | yes | salesforce, hubspot or pipedrive. |
2300
+ | `field_id` | `string` | yes | The CRM's own field id. max length 255 |
2301
+ | `display_name` | `string \| null` | no | max length 255 |
2302
+ | `id` | `string \| null` | no | |
2303
+ | `include_in_di_summary` | `boolean` | no | default `false` |
2304
+ | `include_in_forecast_probability` | `boolean` | no | default `false` |
2305
+
2306
+ <a id="type-dealfieldoverride"></a>
2307
+
2308
+ ### `DealFieldOverride`
2309
+
2310
+ Which side of the merge wins one field. Without an override the app picks per its own rules. Name a field here to decide it yourself - the only way to keep a value from the deal that is being merged AWAY.
2311
+
2312
+ | Field | Type | Required | Description |
2313
+ |---|---|---|---|
2314
+ | `field` | `string` | yes | |
2315
+ | `winner` | `"primary" \| "secondary"` | yes | |
2316
+
2317
+ <a id="type-deallineitemrecord"></a>
2318
+
2319
+ ### `DealLineItemRecord`
2320
+
2321
+ A deal line item. Money fields are in cents.
2322
+
2323
+ | Field | Type | Required | Description |
2324
+ |---|---|---|---|
2325
+ | `discount_pct` | `number` | yes | |
2326
+ | `id` | `string` | yes | |
2327
+ | `line_total` | `integer` | yes | |
2328
+ | `product_name` | `string` | yes | |
2329
+ | `quantity` | `integer` | yes | |
2330
+ | `sort_order` | `integer` | yes | |
2331
+ | `unit_amount` | `integer` | yes | |
2332
+ | `billing_frequency` | `string \| null` | no | |
2333
+ | `description` | `string \| null` | no | |
2334
+ | `manual_product_id` | `string \| null` | no | |
2335
+ | `stripe_price_id` | `string \| null` | no | |
2336
+ | `stripe_product_id` | `string \| null` | no | |
2337
+
2338
+ <a id="type-deallineitemwrite"></a>
2339
+
2340
+ ### `DealLineItemWrite`
2341
+
2342
+ One line item in a replace request. Money is in CENTS. `line_total` is not accepted: the server recomputes it from `unit_amount`, `quantity` and `discount_pct`.
2343
+
2344
+ | Field | Type | Required | Description |
2345
+ |---|---|---|---|
2346
+ | `product_name` | `string` | yes | min length 1, max length 500 |
2347
+ | `unit_amount` | `integer` | yes | Unit price in cents. min 0, max 1000000000 |
2348
+ | `billing_frequency` | `string \| null` | no | max length 50 |
2349
+ | `description` | `string \| null` | no | max length 2000 |
2350
+ | `discount_pct` | `number` | no | default `0`, min 0, max 100 |
2351
+ | `manual_product_id` | `string \| null` | no | Id of a manually-defined product. |
2352
+ | `quantity` | `integer` | no | default `1`, min 1, max 10000 |
2353
+ | `sort_order` | `integer` | no | default `0` |
2354
+ | `stripe_price_id` | `string \| null` | no | Catalog price id, when catalog-backed. |
2355
+ | `stripe_product_id` | `string \| null` | no | Catalog product id, when catalog-backed. |
2356
+
2357
+ <a id="type-dealnotemention"></a>
2358
+
2359
+ ### `DealNoteMention`
2360
+
2361
+ | Field | Type | Required | Description |
2362
+ |---|---|---|---|
2363
+ | `id` | `string` | yes | |
2364
+ | `email` | `string \| null` | no | |
2365
+ | `name` | `string \| null` | no | |
2366
+
2367
+ <a id="type-dealstagevelocitybucket"></a>
2368
+
2369
+ ### `DealStageVelocityBucket`
2370
+
2371
+ Movement through one stage. `avg_days_in_stage` and `conversion_rate` are null (not 0) when there is no sample: an average over zero completed dwells is undefined.
2372
+
2373
+ | Field | Type | Required | Description |
2374
+ |---|---|---|---|
2375
+ | `completed_dwells` | `integer` | yes | |
2376
+ | `entered_count` | `integer` | yes | |
2377
+ | `fell_back_count` | `integer` | yes | |
2378
+ | `position` | `integer` | yes | |
2379
+ | `progressed_count` | `integer` | yes | |
2380
+ | `stage_id` | `string` | yes | |
2381
+ | `stage_name` | `string` | yes | |
2382
+ | `still_in_stage_count` | `integer` | yes | |
2383
+ | `avg_days_in_stage` | `number \| null` | no | |
2384
+ | `conversion_rate` | `number \| null` | no | |
2385
+
2386
+ <a id="type-dealstagevelocitystucksummary"></a>
2387
+
2388
+ ### `DealStageVelocityStuckSummary`
2389
+
2390
+ `total_count` is exact; `deals` is capped at 100 (`truncated` says so).
2391
+
2392
+ | Field | Type | Required | Description |
2393
+ |---|---|---|---|
2394
+ | `threshold_days` | `integer` | yes | |
2395
+ | `total_count` | `integer` | yes | |
2396
+ | `truncated` | `boolean` | yes | |
2397
+ | `deals` | `Array<DealStageVelocityStuckDeal>` | no | |
2398
+
2399
+ <a id="type-dealsummary"></a>
2400
+
2401
+ ### `DealSummary`
2402
+
2403
+ One deal as it appears in a list.
2404
+
2405
+ | Field | Type | Required | Description |
2406
+ |---|---|---|---|
2407
+ | `amount` | `number \| null` | no | |
2408
+ | `close_date` | `string (date-time) \| null` | no | |
2409
+ | `created_at` | `string (date-time) \| null` | no | |
2410
+ | `currency` | `string \| null` | no | |
2411
+ | `id` | `string \| null` | no | |
2412
+ | `name` | `string \| null` | no | |
2413
+ | `owner_id` | `string \| null` | no | |
2414
+ | `pipeline_id` | `string \| null` | no | |
2415
+ | `stage` | `string \| null` | no | |
2416
+ | `status` | `string \| null` | no | |
2417
+
2418
+ <a id="type-pipelinestageresponse"></a>
2419
+
2420
+ ### `PipelineStageResponse`
2421
+
2422
+ | Field | Type | Required | Description |
2423
+ |---|---|---|---|
2424
+ | `id` | `string` | yes | |
2425
+ | `name` | `string` | yes | |
2426
+ | `channel_scripts` | `Record<string, string>` | no | |
2427
+ | `color` | `string \| null` | no | |
2428
+ | `position` | `integer \| null` | no | |
2429
+ | `probability` | `integer \| null` | no | |
2430
+ | `recommended_elements` | `Array<string>` | no | |
2431
+ | `required_elements` | `Array<string>` | no | |
2432
+ | `stage_type` | `string \| null` | no | |