@graph8/sdk 0.251.0 → 0.262.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/README.md +9 -2
  2. package/dist/cli.js +216 -0
  3. package/dist/index.d.mts +105 -7
  4. package/dist/index.d.ts +105 -7
  5. package/dist/index.js +44 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +44 -3
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/react.d.mts +103 -7
  10. package/dist/react.d.ts +103 -7
  11. package/dist/react.js +62 -11
  12. package/dist/react.js.map +1 -1
  13. package/dist/react.mjs +53 -12
  14. package/dist/react.mjs.map +1 -1
  15. package/dist/types/README.md +7 -0
  16. package/dist/types/agency.d.ts +20 -0
  17. package/dist/types/agentSetup.d.ts +57 -0
  18. package/dist/types/api.d.ts +127 -0
  19. package/dist/types/appClient.d.ts +99 -0
  20. package/dist/types/appPlatform.d.ts +269 -0
  21. package/dist/types/appTokens.d.ts +125 -0
  22. package/dist/types/apps.d.ts +130 -0
  23. package/dist/types/audiences.d.ts +88 -0
  24. package/dist/types/calendar.d.ts +55 -0
  25. package/dist/types/campaigns.d.ts +61 -0
  26. package/dist/types/chat.d.ts +35 -0
  27. package/dist/types/cli.d.ts +14 -0
  28. package/dist/types/companies.d.ts +123 -0
  29. package/dist/types/contacts.d.ts +200 -0
  30. package/dist/types/copilot.d.ts +31 -0
  31. package/dist/types/core.d.ts +1052 -0
  32. package/dist/types/deals.d.ts +215 -0
  33. package/dist/types/enrich.d.ts +51 -0
  34. package/dist/types/fields.d.ts +84 -0
  35. package/dist/types/forms.d.ts +16 -0
  36. package/dist/types/http.d.ts +141 -0
  37. package/dist/types/inbox.d.ts +123 -0
  38. package/dist/types/index.d.ts +63 -0
  39. package/dist/types/intent.d.ts +196 -0
  40. package/dist/types/lists.d.ts +44 -0
  41. package/dist/types/mailboxes.d.ts +240 -0
  42. package/dist/types/marketplace.d.ts +62 -0
  43. package/dist/types/meetings.d.ts +70 -0
  44. package/dist/types/newsletter.d.ts +212 -0
  45. package/dist/types/notes.d.ts +57 -0
  46. package/dist/types/objects.d.ts +281 -0
  47. package/dist/types/pipelines.d.ts +135 -0
  48. package/dist/types/quotes.d.ts +143 -0
  49. package/dist/types/react.d.ts +978 -0
  50. package/dist/types/search.d.ts +99 -0
  51. package/dist/types/sequences.d.ts +255 -0
  52. package/dist/types/signals.d.ts +28 -0
  53. package/dist/types/skills.d.ts +176 -0
  54. package/dist/types/snippet.d.ts +24 -0
  55. package/dist/types/studio.d.ts +161 -0
  56. package/dist/types/tasks.d.ts +101 -0
  57. package/dist/types/types.d.ts +45 -0
  58. package/dist/types/utils.d.ts +21 -0
  59. package/dist/types/version.d.ts +10 -0
  60. package/dist/types/visitors.d.ts +29 -0
  61. package/dist/types/voice.d.ts +304 -0
  62. package/dist/types/webhooks.d.ts +71 -0
  63. package/dist/types/workflows.d.ts +229 -0
  64. package/docs/agents.md +748 -0
  65. package/docs/api/README.md +165 -0
  66. package/docs/api/accounts.d.ts +396 -0
  67. package/docs/api/accounts.md +644 -0
  68. package/docs/api/adCampaigns.d.ts +707 -0
  69. package/docs/api/adCampaigns.md +1091 -0
  70. package/docs/api/adCreatives.d.ts +996 -0
  71. package/docs/api/adCreatives.md +1708 -0
  72. package/docs/api/agency.d.ts +556 -0
  73. package/docs/api/agency.md +845 -0
  74. package/docs/api/agent.d.ts +330 -0
  75. package/docs/api/agent.md +514 -0
  76. package/docs/api/agents.d.ts +1622 -0
  77. package/docs/api/agents.md +2860 -0
  78. package/docs/api/aiInbox.d.ts +1984 -0
  79. package/docs/api/aiInbox.md +3490 -0
  80. package/docs/api/analytics.d.ts +1273 -0
  81. package/docs/api/analytics.md +2095 -0
  82. package/docs/api/apiKeys.d.ts +252 -0
  83. package/docs/api/apiKeys.md +318 -0
  84. package/docs/api/appDeployments.d.ts +236 -0
  85. package/docs/api/appDeployments.md +471 -0
  86. package/docs/api/appDomains.d.ts +171 -0
  87. package/docs/api/appDomains.md +281 -0
  88. package/docs/api/appLogs.d.ts +120 -0
  89. package/docs/api/appLogs.md +159 -0
  90. package/docs/api/appObjects.d.ts +415 -0
  91. package/docs/api/appObjects.md +568 -0
  92. package/docs/api/appPages.d.ts +557 -0
  93. package/docs/api/appPages.md +796 -0
  94. package/docs/api/appPlatformTokens.d.ts +123 -0
  95. package/docs/api/appPlatformTokens.md +172 -0
  96. package/docs/api/appointments.d.ts +2361 -0
  97. package/docs/api/appointments.md +3917 -0
  98. package/docs/api/apps.d.ts +822 -0
  99. package/docs/api/apps.md +1342 -0
  100. package/docs/api/assertUpsert.d.ts +286 -0
  101. package/docs/api/assertUpsert.md +370 -0
  102. package/docs/api/audienceSyncs.d.ts +259 -0
  103. package/docs/api/audienceSyncs.md +395 -0
  104. package/docs/api/brandKit.d.ts +686 -0
  105. package/docs/api/brandKit.md +1133 -0
  106. package/docs/api/bugReports.d.ts +181 -0
  107. package/docs/api/bugReports.md +268 -0
  108. package/docs/api/by-path.md +3260 -0
  109. package/docs/api/calendarInvites.d.ts +117 -0
  110. package/docs/api/calendarInvites.md +148 -0
  111. package/docs/api/campaignWorkflows.d.ts +152 -0
  112. package/docs/api/campaignWorkflows.md +200 -0
  113. package/docs/api/campaigns.d.ts +721 -0
  114. package/docs/api/campaigns.md +1236 -0
  115. package/docs/api/channels.d.ts +171 -0
  116. package/docs/api/channels.md +235 -0
  117. package/docs/api/cliCampaigns.d.ts +205 -0
  118. package/docs/api/cliCampaigns.md +256 -0
  119. package/docs/api/cliPipelines.d.ts +324 -0
  120. package/docs/api/cliPipelines.md +562 -0
  121. package/docs/api/clickHouse.d.ts +115 -0
  122. package/docs/api/clickHouse.md +138 -0
  123. package/docs/api/companies.d.ts +1636 -0
  124. package/docs/api/companies.md +2211 -0
  125. package/docs/api/companyIntelligence.d.ts +299 -0
  126. package/docs/api/companyIntelligence.md +488 -0
  127. package/docs/api/contacts.d.ts +2173 -0
  128. package/docs/api/contacts.md +3143 -0
  129. package/docs/api/content.d.ts +968 -0
  130. package/docs/api/content.md +1667 -0
  131. package/docs/api/contentGridSkills.d.ts +177 -0
  132. package/docs/api/contentGridSkills.md +271 -0
  133. package/docs/api/copilot.d.ts +1017 -0
  134. package/docs/api/copilot.md +1765 -0
  135. package/docs/api/crmSyncs.d.ts +215 -0
  136. package/docs/api/crmSyncs.md +301 -0
  137. package/docs/api/customerSuccess.d.ts +491 -0
  138. package/docs/api/customerSuccess.md +776 -0
  139. package/docs/api/deals.d.ts +1697 -0
  140. package/docs/api/deals.md +2436 -0
  141. package/docs/api/deliverability.d.ts +418 -0
  142. package/docs/api/deliverability.md +677 -0
  143. package/docs/api/desk.d.ts +1765 -0
  144. package/docs/api/desk.md +3007 -0
  145. package/docs/api/dialer.d.ts +1185 -0
  146. package/docs/api/dialer.md +2166 -0
  147. package/docs/api/dialerAnalytics.d.ts +187 -0
  148. package/docs/api/dialerAnalytics.md +257 -0
  149. package/docs/api/documents.d.ts +895 -0
  150. package/docs/api/documents.md +1440 -0
  151. package/docs/api/duplicates.d.ts +195 -0
  152. package/docs/api/duplicates.md +315 -0
  153. package/docs/api/eSign.d.ts +38 -0
  154. package/docs/api/eSign.md +54 -0
  155. package/docs/api/eSignature.d.ts +242 -0
  156. package/docs/api/eSignature.md +341 -0
  157. package/docs/api/enrichment.d.ts +3207 -0
  158. package/docs/api/enrichment.md +5225 -0
  159. package/docs/api/events.d.ts +115 -0
  160. package/docs/api/events.md +105 -0
  161. package/docs/api/fields.d.ts +482 -0
  162. package/docs/api/fields.md +566 -0
  163. package/docs/api/forms.d.ts +1012 -0
  164. package/docs/api/forms.md +1542 -0
  165. package/docs/api/gtmCampaigns.d.ts +662 -0
  166. package/docs/api/gtmCampaigns.md +1044 -0
  167. package/docs/api/gtmContext.d.ts +1187 -0
  168. package/docs/api/gtmContext.md +2112 -0
  169. package/docs/api/gtmDeliverability.d.ts +60 -0
  170. package/docs/api/gtmDeliverability.md +63 -0
  171. package/docs/api/gtmKnowledgeBase.d.ts +76 -0
  172. package/docs/api/gtmKnowledgeBase.md +91 -0
  173. package/docs/api/gtmLaunchHelpers.d.ts +123 -0
  174. package/docs/api/gtmLaunchHelpers.md +148 -0
  175. package/docs/api/gtmLibrary.d.ts +448 -0
  176. package/docs/api/gtmLibrary.md +780 -0
  177. package/docs/api/health.d.ts +39 -0
  178. package/docs/api/health.md +58 -0
  179. package/docs/api/imageLibrary.d.ts +341 -0
  180. package/docs/api/imageLibrary.md +569 -0
  181. package/docs/api/imports.d.ts +157 -0
  182. package/docs/api/imports.md +174 -0
  183. package/docs/api/inbox.d.ts +709 -0
  184. package/docs/api/inbox.md +1067 -0
  185. package/docs/api/install.d.ts +213 -0
  186. package/docs/api/install.md +317 -0
  187. package/docs/api/installedApps.d.ts +131 -0
  188. package/docs/api/installedApps.md +241 -0
  189. package/docs/api/integrationStatus.d.ts +142 -0
  190. package/docs/api/integrationStatus.md +205 -0
  191. package/docs/api/integrations.d.ts +2327 -0
  192. package/docs/api/integrations.md +3791 -0
  193. package/docs/api/intent.d.ts +482 -0
  194. package/docs/api/intent.md +858 -0
  195. package/docs/api/knowledge.d.ts +501 -0
  196. package/docs/api/knowledge.md +843 -0
  197. package/docs/api/knowledgeBase.d.ts +84 -0
  198. package/docs/api/knowledgeBase.md +96 -0
  199. package/docs/api/landingPages.d.ts +1411 -0
  200. package/docs/api/landingPages.md +2488 -0
  201. package/docs/api/leads.d.ts +133 -0
  202. package/docs/api/leads.md +180 -0
  203. package/docs/api/library.d.ts +217 -0
  204. package/docs/api/library.md +338 -0
  205. package/docs/api/linkedIn.d.ts +227 -0
  206. package/docs/api/linkedIn.md +289 -0
  207. package/docs/api/linkedInOutreach.d.ts +727 -0
  208. package/docs/api/linkedInOutreach.md +990 -0
  209. package/docs/api/lists.d.ts +1106 -0
  210. package/docs/api/lists.md +1609 -0
  211. package/docs/api/logs.d.ts +71 -0
  212. package/docs/api/logs.md +70 -0
  213. package/docs/api/mailboxes.d.ts +1050 -0
  214. package/docs/api/mailboxes.md +1690 -0
  215. package/docs/api/marketingIntelligence.d.ts +256 -0
  216. package/docs/api/marketingIntelligence.md +454 -0
  217. package/docs/api/marketplace.d.ts +3173 -0
  218. package/docs/api/marketplace.md +5953 -0
  219. package/docs/api/mcp.d.ts +69 -0
  220. package/docs/api/mcp.md +69 -0
  221. package/docs/api/me.d.ts +54 -0
  222. package/docs/api/me.md +56 -0
  223. package/docs/api/meetings.d.ts +539 -0
  224. package/docs/api/meetings.md +747 -0
  225. package/docs/api/newsletter.d.ts +1613 -0
  226. package/docs/api/newsletter.md +2746 -0
  227. package/docs/api/notes.d.ts +517 -0
  228. package/docs/api/notes.md +888 -0
  229. package/docs/api/notifications.d.ts +94 -0
  230. package/docs/api/notifications.md +105 -0
  231. package/docs/api/objects.d.ts +621 -0
  232. package/docs/api/objects.md +1098 -0
  233. package/docs/api/openSearch.d.ts +234 -0
  234. package/docs/api/openSearch.md +297 -0
  235. package/docs/api/ops.d.ts +299 -0
  236. package/docs/api/ops.md +339 -0
  237. package/docs/api/orgGovernance.d.ts +393 -0
  238. package/docs/api/orgGovernance.md +623 -0
  239. package/docs/api/orgVideos.d.ts +184 -0
  240. package/docs/api/orgVideos.md +252 -0
  241. package/docs/api/organizationSettings.d.ts +626 -0
  242. package/docs/api/organizationSettings.md +911 -0
  243. package/docs/api/phoneNumbers.d.ts +484 -0
  244. package/docs/api/phoneNumbers.md +777 -0
  245. package/docs/api/profile.d.ts +329 -0
  246. package/docs/api/profile.md +540 -0
  247. package/docs/api/programmaticPages.d.ts +400 -0
  248. package/docs/api/programmaticPages.md +626 -0
  249. package/docs/api/providerDomains.d.ts +866 -0
  250. package/docs/api/providerDomains.md +1446 -0
  251. package/docs/api/providerUsage.d.ts +129 -0
  252. package/docs/api/providerUsage.md +186 -0
  253. package/docs/api/public.d.ts +69 -0
  254. package/docs/api/public.md +78 -0
  255. package/docs/api/publicCopilot.d.ts +67 -0
  256. package/docs/api/publicCopilot.md +80 -0
  257. package/docs/api/publicSignals.d.ts +66 -0
  258. package/docs/api/publicSignals.md +71 -0
  259. package/docs/api/publicVisitors.d.ts +97 -0
  260. package/docs/api/publicVisitors.md +118 -0
  261. package/docs/api/quotes.d.ts +1564 -0
  262. package/docs/api/quotes.md +2553 -0
  263. package/docs/api/radar.d.ts +808 -0
  264. package/docs/api/radar.md +1431 -0
  265. package/docs/api/radarReports.d.ts +208 -0
  266. package/docs/api/radarReports.md +306 -0
  267. package/docs/api/recordRoles.d.ts +143 -0
  268. package/docs/api/recordRoles.md +175 -0
  269. package/docs/api/repos.d.ts +146 -0
  270. package/docs/api/repos.md +211 -0
  271. package/docs/api/research.d.ts +295 -0
  272. package/docs/api/research.md +534 -0
  273. package/docs/api/revenue.d.ts +402 -0
  274. package/docs/api/revenue.md +608 -0
  275. package/docs/api/revenueAnalytics.d.ts +147 -0
  276. package/docs/api/revenueAnalytics.md +212 -0
  277. package/docs/api/revenueLifecycle.d.ts +207 -0
  278. package/docs/api/revenueLifecycle.md +274 -0
  279. package/docs/api/revenueRecords.d.ts +372 -0
  280. package/docs/api/revenueRecords.md +563 -0
  281. package/docs/api/roles.d.ts +431 -0
  282. package/docs/api/roles.md +812 -0
  283. package/docs/api/salesCoach.d.ts +877 -0
  284. package/docs/api/salesCoach.md +1540 -0
  285. package/docs/api/sandbox.d.ts +210 -0
  286. package/docs/api/sandbox.md +380 -0
  287. package/docs/api/scans.d.ts +104 -0
  288. package/docs/api/scans.md +136 -0
  289. package/docs/api/scheduleBuy.d.ts +293 -0
  290. package/docs/api/scheduleBuy.md +431 -0
  291. package/docs/api/scraping.d.ts +266 -0
  292. package/docs/api/scraping.md +383 -0
  293. package/docs/api/sdrAnalytics.d.ts +138 -0
  294. package/docs/api/sdrAnalytics.md +246 -0
  295. package/docs/api/search.d.ts +598 -0
  296. package/docs/api/search.md +866 -0
  297. package/docs/api/seo.d.ts +447 -0
  298. package/docs/api/seo.md +660 -0
  299. package/docs/api/sequenceLifecycle.d.ts +439 -0
  300. package/docs/api/sequenceLifecycle.md +513 -0
  301. package/docs/api/sequences.d.ts +1936 -0
  302. package/docs/api/sequences.md +3232 -0
  303. package/docs/api/settings.d.ts +448 -0
  304. package/docs/api/settings.md +731 -0
  305. package/docs/api/signals.d.ts +1441 -0
  306. package/docs/api/signals.md +2526 -0
  307. package/docs/api/signatures.d.ts +719 -0
  308. package/docs/api/signatures.md +1247 -0
  309. package/docs/api/skills.d.ts +230 -0
  310. package/docs/api/skills.md +466 -0
  311. package/docs/api/snippet.d.ts +85 -0
  312. package/docs/api/snippet.md +106 -0
  313. package/docs/api/socialPublishing.d.ts +824 -0
  314. package/docs/api/socialPublishing.md +1245 -0
  315. package/docs/api/studioDocuments.d.ts +244 -0
  316. package/docs/api/studioDocuments.md +348 -0
  317. package/docs/api/support.d.ts +90 -0
  318. package/docs/api/support.md +76 -0
  319. package/docs/api/suppressions.d.ts +241 -0
  320. package/docs/api/suppressions.md +343 -0
  321. package/docs/api/surveys.d.ts +847 -0
  322. package/docs/api/surveys.md +1223 -0
  323. package/docs/api/tasks.d.ts +813 -0
  324. package/docs/api/tasks.md +1344 -0
  325. package/docs/api/teamMembers.d.ts +668 -0
  326. package/docs/api/teamMembers.md +1040 -0
  327. package/docs/api/teams.d.ts +784 -0
  328. package/docs/api/teams.md +1395 -0
  329. package/docs/api/usage.d.ts +277 -0
  330. package/docs/api/usage.md +389 -0
  331. package/docs/api/visitors.d.ts +690 -0
  332. package/docs/api/visitors.md +1075 -0
  333. package/docs/api/voice.d.ts +4661 -0
  334. package/docs/api/voice.md +7905 -0
  335. package/docs/api/webAnalytics.d.ts +964 -0
  336. package/docs/api/webAnalytics.md +1452 -0
  337. package/docs/api/webChat.d.ts +1704 -0
  338. package/docs/api/webChat.md +2048 -0
  339. package/docs/api/webhooks.d.ts +251 -0
  340. package/docs/api/webhooks.md +386 -0
  341. package/docs/api/websiteEditor.d.ts +324 -0
  342. package/docs/api/websiteEditor.md +517 -0
  343. package/docs/api/work.d.ts +2298 -0
  344. package/docs/api/work.md +3096 -0
  345. package/docs/api/workbench.d.ts +2962 -0
  346. package/docs/api/workbench.md +4884 -0
  347. package/docs/api/workflows.d.ts +1218 -0
  348. package/docs/api/workflows.md +2302 -0
  349. package/docs/sdk-clients.md +4339 -0
  350. package/package.json +10 -3
@@ -0,0 +1,2553 @@
1
+ <!-- Generated by sdk/js/scripts/generate-agent-docs.ts from developer-contract/openapi.json. Regenerated on every build. -->
2
+
3
+ # `g8.api.quotes`: Quotes
4
+
5
+ 56 operations (26 read, 6 write, 7 destructive, 17 external).
6
+
7
+ 12 of these also have a hand-written method (`g8.quotes`), 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: [quotes.d.ts](quotes.d.ts).
20
+
21
+ ## Operations
22
+
23
+ | Call | HTTP | Tier | Scope | Summary |
24
+ |---|---|---|---|---|
25
+ | [`archiveQuote`](#op-archivequote) | `POST /api/v1/quotes/{quote_id}/archive` | destructive | `quotes:delete` | Archive Quote |
26
+ | [`batchQuoteAction`](#op-batchquoteaction) | `POST /api/v1/quotes/batch` | external | `quotes:run` | Batch Quote Action |
27
+ | [`bulkUpdateStripeProductSettings`](#op-bulkupdatestripeproductsettings) | `PATCH /api/v1/stripe/product-settings/bulk` | write | `quotes:write` | Bulk Update Stripe Product Settings |
28
+ | [`calculateMailboxCapacity`](#op-calculatemailboxcapacity) | `POST /api/v1/quotes/mailbox-capacity` | read | `quotes:read` | Calculate Mailbox Capacity |
29
+ | [`connectStripeApiKey`](#op-connectstripeapikey) | `POST /api/v1/stripe/api-key` | external | `quotes:run` | Connect Stripe Api Key |
30
+ | [`createManualProduct`](#op-createmanualproduct) | `POST /api/v1/manual-products` | write | `quotes:write` | Create Manual Product |
31
+ | [`createQuote`](#op-createquote) ★ | `POST /api/v1/quotes` | external | `quotes:run` | Create Quote |
32
+ | [`createQuoteBillingContact`](#op-createquotebillingcontact) | `POST /api/v1/quote-billing-contact` | external | `quotes:run` | Create Quote Billing Contact |
33
+ | [`createQuoteContact`](#op-createquotecontact) | `POST /api/v1/quote-contacts` | external | `quotes:run` | Create Quote Contact |
34
+ | [`createQuoteTemplate`](#op-createquotetemplate) | `POST /api/v1/quote-templates` | external | `quotes:run` | Create Quote Template |
35
+ | [`deleteManualProduct`](#op-deletemanualproduct) | `DELETE /api/v1/manual-products/{product_id}` | destructive | `quotes:delete` | Delete Manual Product |
36
+ | [`deleteQuote`](#op-deletequote) ★ | `DELETE /api/v1/quotes/{quote_id}` | destructive | `quotes:delete` | Delete Quote |
37
+ | [`deleteQuoteDocument`](#op-deletequotedocument) | `DELETE /api/v1/quote-settings/documents/{doc_id}` | destructive | `quotes:delete` | Delete Quote Document |
38
+ | [`deleteQuoteTemplate`](#op-deletequotetemplate) | `DELETE /api/v1/quote-templates/{template_id}` | destructive | `quotes:delete` | Delete Quote Template |
39
+ | [`downloadQuoteEvidence`](#op-downloadquoteevidence) | `GET /api/v1/quotes/{quote_id}/evidence/{evidence_id}` | read | `quotes:read` | Download Quote Evidence |
40
+ | [`duplicateQuote`](#op-duplicatequote) ★ | `POST /api/v1/quotes/{quote_id}/duplicate` | external | `quotes:run` | Duplicate Quote |
41
+ | [`editQuoteAsDraft`](#op-editquoteasdraft) ★ | `POST /api/v1/quotes/{quote_id}/edit-as-draft` | external | `quotes:run` | Edit Quote As Draft |
42
+ | [`expireQuote`](#op-expirequote) | `POST /api/v1/quotes/{quote_id}/expire` | destructive | `quotes:delete` | Expire Quote |
43
+ | [`getCompanyQuotes`](#op-getcompanyquotes) ★ | `GET /api/v1/companies/{company_id}/quotes` | read | `quotes:read` | Get Company Quotes |
44
+ | [`getCompanyRevenueSummary`](#op-getcompanyrevenuesummary) | `GET /api/v1/stripe/companies/{company_id}/revenue-summary` | read | `quotes:read` | Get Company Revenue Summary |
45
+ | [`getCompanyStripeInvoices`](#op-getcompanystripeinvoices) | `GET /api/v1/stripe/companies/{company_id}/invoices` | read | `quotes:read` | Get Company Stripe Invoices |
46
+ | [`getCompanyStripeSubscriptions`](#op-getcompanystripesubscriptions) | `GET /api/v1/stripe/companies/{company_id}/subscriptions` | read | `quotes:read` | Get Company Stripe Subscriptions |
47
+ | [`getContactQuotes`](#op-getcontactquotes) ★ | `GET /api/v1/contacts/{contact_id}/quotes` | read | `quotes:read` | Get Contact Quotes |
48
+ | [`getQuote`](#op-getquote) ★ | `GET /api/v1/quotes/{quote_id}` | read | `quotes:read` | Get Quote |
49
+ | [`getQuotePdf`](#op-getquotepdf) | `GET /api/v1/quotes/{quote_id}/pdf` | read | `quotes:read` | Get Quote Pdf |
50
+ | [`getQuoteSettings`](#op-getquotesettings) ★ | `GET /api/v1/quote-settings` | read | `quotes:read` | Get Quote Settings |
51
+ | [`getStripeData`](#op-getstripedata) | `GET /api/v1/stripe/connections/{connection_id}/data` | read | `quotes:read` | Get Stripe Data |
52
+ | [`getStripeDataPage`](#op-getstripedatapage) | `GET /api/v1/stripe/connections/{connection_id}/data/{resource}` | read | `quotes:read` | Get Stripe Data Page |
53
+ | [`getStripeIntegrationStatus`](#op-getstripeintegrationstatus) | `GET /api/v1/stripe/integration-status` | read | `quotes:read` | Get Stripe Integration Status |
54
+ | [`listManualProducts`](#op-listmanualproducts) | `GET /api/v1/manual-products` | read | `quotes:read` | List Manual Products |
55
+ | [`listQuotableProducts`](#op-listquotableproducts) ★ | `GET /api/v1/quotable-products` | read | `quotes:read` | List Quotable Products |
56
+ | [`listQuoteDocuments`](#op-listquotedocuments) | `GET /api/v1/quote-settings/documents` | read | `quotes:read` | List Quote Documents |
57
+ | [`listQuoteEvidence`](#op-listquoteevidence) | `GET /api/v1/quotes/{quote_id}/evidence` | read | `quotes:read` | List Quote Evidence |
58
+ | [`listQuoteTemplates`](#op-listquotetemplates) | `GET /api/v1/quote-templates` | read | `quotes:read` | List Quote Templates |
59
+ | [`listQuotes`](#op-listquotes) ★ | `GET /api/v1/quotes` | read | `quotes:read` | List Quotes |
60
+ | [`listStripeProductSettings`](#op-liststripeproductsettings) | `GET /api/v1/stripe/product-settings` | read | `quotes:read` | List Stripe Product Settings |
61
+ | [`listStripeProductSubscribers`](#op-liststripeproductsubscribers) | `GET /api/v1/stripe/products/{product_id}/subscribers` | read | `quotes:read` | List Stripe Product Subscribers |
62
+ | [`listStripeProducts`](#op-liststripeproducts) | `GET /api/v1/stripe/products` | read | `quotes:read` | List Stripe Products |
63
+ | [`markQuoteAccepted`](#op-markquoteaccepted) | `POST /api/v1/quotes/{quote_id}/mark-accepted` | external | `quotes:run` | Mark Quote Accepted |
64
+ | [`previewPaymentSchedule`](#op-previewpaymentschedule) | `POST /api/v1/quotes/payment-schedule` | read | `quotes:read` | Preview Payment Schedule |
65
+ | [`previewQuoteDraft`](#op-previewquotedraft) | `POST /api/v1/quotes/preview-draft` | read | `quotes:read` | Preview Quote Draft |
66
+ | [`previewQuoteSend`](#op-previewquotesend) | `POST /api/v1/quotes/{quote_id}/send-preview` | read | `quotes:read` | Preview Quote Send |
67
+ | [`revokeQuote`](#op-revokequote) | `POST /api/v1/quotes/{quote_id}/revoke` | destructive | `quotes:delete` | Revoke Quote |
68
+ | [`searchQuoteContacts`](#op-searchquotecontacts) | `GET /api/v1/quote-contacts` | read | `quotes:read` | Search Quote Contacts |
69
+ | [`sendQuote`](#op-sendquote) ★ | `POST /api/v1/quotes/{quote_id}/send` | external | `quotes:run` | Send Quote |
70
+ | [`triggerStripeSync`](#op-triggerstripesync) | `POST /api/v1/stripe/sync` | external | `quotes:run` | Trigger Stripe Sync |
71
+ | [`unarchiveQuote`](#op-unarchivequote) | `POST /api/v1/quotes/{quote_id}/unarchive` | external | `quotes:run` | Unarchive Quote |
72
+ | [`updateManualProduct`](#op-updatemanualproduct) | `PATCH /api/v1/manual-products/{product_id}` | write | `quotes:write` | Update Manual Product |
73
+ | [`updateQuotePatch`](#op-updatequotepatch) | `PATCH /api/v1/quotes/{quote_id}` | external | `quotes:run` | Update Quote |
74
+ | [`updateQuotePut`](#op-updatequoteput) ★ | `PUT /api/v1/quotes/{quote_id}` | external | `quotes:run` | Update Quote |
75
+ | [`updateQuoteSettings`](#op-updatequotesettings) | `PUT /api/v1/quote-settings` | external | `quotes:run` | Update Quote Settings |
76
+ | [`updateQuoteTemplate`](#op-updatequotetemplate) | `PUT /api/v1/quote-templates/{template_id}` | external | `quotes:run` | Update Quote Template |
77
+ | [`updateStripeCustomerMapping`](#op-updatestripecustomermapping) | `PATCH /api/v1/stripe/customers/{customer_id}/mapping` | write | `quotes:write` | Update Stripe Customer Mapping |
78
+ | [`uploadQuoteDocument`](#op-uploadquotedocument) | `POST /api/v1/quote-settings/documents` | external | `quotes:run` | Upload Quote Document |
79
+ | [`uploadQuoteEvidence`](#op-uploadquoteevidence) | `POST /api/v1/quotes/{quote_id}/evidence` | write | `quotes:write` | Upload Quote Evidence |
80
+ | [`upsertStripeProductSettings`](#op-upsertstripeproductsettings) | `PUT /api/v1/stripe/product-settings/{stripe_product_id}` | write | `quotes:write` | Upsert Stripe Product Settings |
81
+
82
+ ---
83
+
84
+ <a id="op-archivequote"></a>
85
+
86
+ ### `g8.api.quotes.archiveQuote(input)`
87
+
88
+ **Archive Quote**
89
+
90
+ - HTTP: `POST /api/v1/quotes/{quote_id}/archive`
91
+ - operationId: `archive_quote_quotes__quote_id__archive_post` (also callable as `g8.api.call("archive_quote_quotes__quote_id__archive_post", input)`)
92
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
93
+ - API-key scope: `quotes:delete`
94
+
95
+ Take a quote off the active list. REVERSIBLE - see `/unarchive`.
96
+
97
+ **Input**
98
+
99
+ | Field | Type | Required | Description |
100
+ |---|---|---|---|
101
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
102
+
103
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
104
+
105
+ Other envelope fields: `pagination` (PaginationMeta).
106
+
107
+ **Example**
108
+
109
+ ```ts
110
+ // destructive: deletes or archives data; confirm with a human before calling.
111
+ const result = await g8.api.quotes.archiveQuote({ path: { quote_id: "id" } });
112
+ ```
113
+
114
+ ---
115
+
116
+ <a id="op-batchquoteaction"></a>
117
+
118
+ ### `g8.api.quotes.batchQuoteAction(input)`
119
+
120
+ **Batch Quote Action**
121
+
122
+ - HTTP: `POST /api/v1/quotes/batch`
123
+ - operationId: `batch_quote_action_quotes_batch_post` (also callable as `g8.api.call("batch_quote_action_quotes_batch_post", input)`)
124
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
125
+ - API-key scope: `quotes:run`
126
+
127
+ Archive, expire or revoke up to 200 quotes.
128
+
129
+ READ THE PER-ROW RESULT, not the HTTP status. Each quote runs in its own
130
+ transaction, so a 200 here means "the batch ran", not "every quote moved":
131
+ an out-of-scope id comes back `forbidden`, an unknown one `error`, and a
132
+ quote whose status makes the action meaningless comes back `skipped`.
133
+
134
+ **Input**
135
+
136
+ | Field | Type | Required | Description |
137
+ |---|---|---|---|
138
+ | `body` | `BatchQuoteActionRequest` | yes | Request body; fields below. |
139
+
140
+ Body fields (`BatchQuoteActionRequest`):
141
+
142
+ | Field | Type | Required | Description |
143
+ |---|---|---|---|
144
+ | `body.action` | `"archive" \| "expire" \| "revoke"` | yes | What to do to every quote in the list. |
145
+ | `body.quote_ids` | `Array<string>` | yes | Quote ids. An out-of-scope or unknown id is reported per-row, not fatal. min items 1, max items 200 |
146
+
147
+ **Returns** `ApiResponse_QuoteListPayload_`: the envelope `{ data: QuoteListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
148
+
149
+ Other envelope fields: `pagination` (PaginationMeta).
150
+
151
+ `QuoteListPayload` fields:
152
+
153
+ | Field | Type | Required | Description |
154
+ |---|---|---|---|
155
+ | `items` | `Array<unknown>` | no | |
156
+
157
+ **Example**
158
+
159
+ ```ts
160
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
161
+ const result = await g8.api.quotes.batchQuoteAction({ body: { action: "archive", quote_ids: ["id"] } });
162
+ ```
163
+
164
+ ---
165
+
166
+ <a id="op-bulkupdatestripeproductsettings"></a>
167
+
168
+ ### `g8.api.quotes.bulkUpdateStripeProductSettings(input)`
169
+
170
+ **Bulk Update Stripe Product Settings**
171
+
172
+ - HTTP: `PATCH /api/v1/stripe/product-settings/bulk`
173
+ - operationId: `bulk_update_stripe_product_settings_stripe_product_settings_bulk_patch` (also callable as `g8.api.call("bulk_update_stripe_product_settings_stripe_product_settings_bulk_patch", input)`)
174
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
175
+ - API-key scope: `quotes:write`
176
+
177
+ Apply the same settings to many products. Org Admin or Owner key only.
178
+
179
+ **Input**
180
+
181
+ | Field | Type | Required | Description |
182
+ |---|---|---|---|
183
+ | `body` | `BulkProductSettingsRequest` | yes | Request body; fields below. |
184
+
185
+ Body fields (`BulkProductSettingsRequest`):
186
+
187
+ | Field | Type | Required | Description |
188
+ |---|---|---|---|
189
+ | `body.stripe_product_ids` | `Array<string>` | yes | Stripe product ids to update. |
190
+ | `body.updates` | `ProductSettingsUpdateRequest` | yes | |
191
+
192
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
193
+
194
+ Other envelope fields: `pagination` (PaginationMeta).
195
+
196
+ **Example**
197
+
198
+ ```ts
199
+ const result = await g8.api.quotes.bulkUpdateStripeProductSettings({ body: { stripe_product_ids: ["id"], updates: {} } });
200
+ ```
201
+
202
+ ---
203
+
204
+ <a id="op-calculatemailboxcapacity"></a>
205
+
206
+ ### `g8.api.quotes.calculateMailboxCapacity(input)`
207
+
208
+ **Calculate Mailbox Capacity**
209
+
210
+ - HTTP: `POST /api/v1/quotes/mailbox-capacity`
211
+ - operationId: `calculate_mailbox_capacity_quotes_mailbox_capacity_post` (also callable as `g8.api.call("calculate_mailbox_capacity_quotes_mailbox_capacity_post", input)`)
212
+ - Tier: `read`: reads data; safe to call and to retry
213
+ - API-key scope: `quotes:read`
214
+
215
+ Mailboxes and domains needed to reach `contacts_per_month`, for a 30-,
216
+ 7- and 1-day delivery window, with their cost. ARITHMETIC ONLY: nothing is
217
+ bought or written. POST only because the inputs are a body.
218
+
219
+ **Input**
220
+
221
+ | Field | Type | Required | Description |
222
+ |---|---|---|---|
223
+ | `body` | `MailboxCapacityRequest` | yes | Request body; fields below. |
224
+
225
+ Body fields (`MailboxCapacityRequest`):
226
+
227
+ | Field | Type | Required | Description |
228
+ |---|---|---|---|
229
+ | `body.contacts_per_month` | `integer` | yes | Target contacts to reach per month. min 0 |
230
+ | `body.domain_tld` | `string` | no | TLD for the per-domain cost estimate. default `".com"` |
231
+ | `body.warmed` | `boolean` | no | Mailbox warmup state. Advisory under the current platform-wide daily cap. default `false` |
232
+
233
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
234
+
235
+ Other envelope fields: `pagination` (PaginationMeta).
236
+
237
+ **Example**
238
+
239
+ ```ts
240
+ const result = await g8.api.quotes.calculateMailboxCapacity({ body: { contacts_per_month: 0 } });
241
+ ```
242
+
243
+ ---
244
+
245
+ <a id="op-connectstripeapikey"></a>
246
+
247
+ ### `g8.api.quotes.connectStripeApiKey(input)`
248
+
249
+ **Connect Stripe Api Key**
250
+
251
+ - HTTP: `POST /api/v1/stripe/api-key`
252
+ - operationId: `connect_stripe_api_key_stripe_api_key_post` (also callable as `g8.api.call("connect_stripe_api_key_stripe_api_key_post", input)`)
253
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
254
+ - API-key scope: `quotes:run`
255
+
256
+ Connect Stripe with a restricted API key. REACHES STRIPE to validate it.
257
+
258
+ Replaces any key already stored for the org. The key is write-only: the
259
+ response carries the connection id and whether it is a live-mode key,
260
+ never the key. Products sync within fifteen minutes, or immediately with
261
+ `POST /stripe/sync`.
262
+
263
+ **Input**
264
+
265
+ | Field | Type | Required | Description |
266
+ |---|---|---|---|
267
+ | `body` | `StripeApiKeyRequest` | yes | Request body; fields below. |
268
+
269
+ Body fields (`StripeApiKeyRequest`):
270
+
271
+ | Field | Type | Required | Description |
272
+ |---|---|---|---|
273
+ | `body.api_key` | `string` | yes | Stripe restricted or secret key: rk_live_, rk_test_, sk_live_ or sk_test_. min length 10 |
274
+
275
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
276
+
277
+ Other envelope fields: `pagination` (PaginationMeta).
278
+
279
+ **Example**
280
+
281
+ ```ts
282
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
283
+ const result = await g8.api.quotes.connectStripeApiKey({ body: { api_key: "xxxxxxxxxx" } });
284
+ ```
285
+
286
+ ---
287
+
288
+ <a id="op-createmanualproduct"></a>
289
+
290
+ ### `g8.api.quotes.createManualProduct(input)`
291
+
292
+ **Create Manual Product**
293
+
294
+ - HTTP: `POST /api/v1/manual-products`
295
+ - operationId: `create_manual_product_manual_products_post` (also callable as `g8.api.call("create_manual_product_manual_products_post", input)`)
296
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
297
+ - API-key scope: `quotes:write`
298
+
299
+ Add a product to the manual catalogue. Org Admin or Owner key only.
300
+
301
+ **Input**
302
+
303
+ | Field | Type | Required | Description |
304
+ |---|---|---|---|
305
+ | `body` | `ManualProductCreateRequest` | yes | Request body; fields below. |
306
+
307
+ Body fields (`ManualProductCreateRequest`):
308
+
309
+ | Field | Type | Required | Description |
310
+ |---|---|---|---|
311
+ | `body.default_unit_amount` | `integer` | yes | In cents. min 0, max 1000000000 |
312
+ | `body.name` | `string` | yes | min length 1, max length 500 |
313
+ | `body.active` | `boolean` | no | default `true` |
314
+ | `body.billing_frequency` | `"one_time" \| "month" \| "year" \| "quarter"` | no | default `"one_time"` |
315
+ | `body.category` | `string \| null` | no | max length 100 |
316
+ | `body.currency` | `string` | no | default `"USD"`, min length 3, max length 3 |
317
+ | `body.description` | `string \| null` | no | max length 5000 |
318
+ | `body.quotable` | `boolean` | no | default `true` |
319
+ | `body.sort_order` | `integer` | no | default `0`, min 0, max 10000 |
320
+
321
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
322
+
323
+ Other envelope fields: `pagination` (PaginationMeta).
324
+
325
+ **Example**
326
+
327
+ ```ts
328
+ const result = await g8.api.quotes.createManualProduct({ body: { default_unit_amount: 0, name: "Example" } });
329
+ ```
330
+
331
+ ---
332
+
333
+ <a id="op-createquote"></a>
334
+
335
+ ### `g8.api.quotes.createQuote(input)`
336
+
337
+ **Create Quote**
338
+
339
+ - HTTP: `POST /api/v1/quotes`
340
+ - operationId: `create_quote_quotes_post` (also callable as `g8.api.call("create_quote_quotes_post", input)`)
341
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
342
+ - API-key scope: `quotes:run`
343
+ - ★ Hand-written: [`g8.quotes.create()`](../sdk-clients.md#g8-quotes-create)
344
+
345
+ Create a new quote in `draft` status. Always creates — never sends.
346
+
347
+ **Input**
348
+
349
+ | Field | Type | Required | Description |
350
+ |---|---|---|---|
351
+ | `body` | `QuoteCreateRequest` | yes | Request body; fields below. |
352
+
353
+ Body fields (`QuoteCreateRequest`):
354
+
355
+ | Field | Type | Required | Description |
356
+ |---|---|---|---|
357
+ | `body.line_items` | `Array<QuoteLineItemRequest>` | yes | min items 1 |
358
+ | `body.title` | `string` | yes | min length 1, max length 500 |
359
+ | `body.accepted_payment_methods` | `Array<"ach" \| "credit_card" \| "wire"> \| null` | no | |
360
+ | `body.billing_address` | `string \| null` | no | max length 2000 |
361
+ | `body.billing_contact_id` | `integer \| null` | no | |
362
+ | `body.billing_email` | `string \| null` | no | max length 255 |
363
+ | `body.billing_legal_name` | `string \| null` | no | max length 255 |
364
+ | `body.billing_primary_email` | `string \| null` | no | max length 255 |
365
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
366
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
367
+ | `body.contract_end_date` | `string \| null` | no | |
368
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
369
+ | `body.contract_start_date` | `string \| null` | no | |
370
+ | `body.currency` | `string` | no | default `"USD"`, min length 3, max length 3 |
371
+ | `body.deal_id` | `string \| null` | no | |
372
+ | `body.marketing_rights` | `Array<"logo" \| "quote" \| "case_study"> \| null` | no | |
373
+ | `body.mashup_company_id` | `integer \| null` | no | |
374
+ | `body.notes` | `string \| null` | no | max length 10000 |
375
+ | `body.owner_id` | `string \| null` | no | max length 255 |
376
+ | `body.payment_terms` | `"due_on_receipt" \| "net_15" \| "net_30" \| "net_45" \| "net_60" \| "net_90"` | no | default `"net_30"` |
377
+ | `body.privacy_content` | `string \| null` | no | max length 50000 |
378
+ | `body.public_notes` | `string \| null` | no | max length 50000 |
379
+ | `body.signer_contact_id` | `integer \| null` | no | |
380
+ | `body.signer_email` | `string \| null` | no | max length 255 |
381
+ | `body.signer_name` | `string \| null` | no | max length 255 |
382
+ | `body.tax_amount` | `integer` | no | default `0`, min 0, max 1000000000 |
383
+ | `body.template_id` | `string \| null` | no | |
384
+ | `body.terms_content` | `string \| null` | no | max length 50000 |
385
+ | `body.valid_until` | `string \| null` | no | |
386
+
387
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
388
+
389
+ Other envelope fields: `pagination` (PaginationMeta).
390
+
391
+ `QuoteDetail` fields:
392
+
393
+ | Field | Type | Required | Description |
394
+ |---|---|---|---|
395
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
396
+ | `envelope` | `Record<string, unknown> \| null` | no | |
397
+ | `id` | `string \| null` | no | |
398
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
399
+ | `quote_number` | `string \| null` | no | |
400
+ | `status` | `string \| null` | no | |
401
+ | `title` | `string \| null` | no | |
402
+
403
+ **Example**
404
+
405
+ ```ts
406
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
407
+ const result = await g8.api.quotes.createQuote({
408
+ body: {
409
+ line_items: [{ product_name: "Example", unit_amount: 0 }],
410
+ title: "Example",
411
+ },
412
+ });
413
+ ```
414
+
415
+ ---
416
+
417
+ <a id="op-createquotebillingcontact"></a>
418
+
419
+ ### `g8.api.quotes.createQuoteBillingContact(input)`
420
+
421
+ **Create Quote Billing Contact**
422
+
423
+ - HTTP: `POST /api/v1/quote-billing-contact`
424
+ - operationId: `create_quote_billing_contact_quote_billing_contact_post` (also callable as `g8.api.call("create_quote_billing_contact_quote_billing_contact_post", input)`)
425
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
426
+ - API-key scope: `quotes:run`
427
+
428
+ Create the FINANCE contact a quote bills to. Name and email only.
429
+
430
+ **Input**
431
+
432
+ | Field | Type | Required | Description |
433
+ |---|---|---|---|
434
+ | `body` | `QuoteBillingContactCreateRequest` | yes | Request body; fields below. |
435
+
436
+ Body fields (`QuoteBillingContactCreateRequest`):
437
+
438
+ | Field | Type | Required | Description |
439
+ |---|---|---|---|
440
+ | `body.email` | `string` | yes | max length 255 |
441
+ | `body.mashup_company_id` | `integer` | yes | Company the contact belongs to. min 1 |
442
+ | `body.deal_id` | `string \| null` | no | |
443
+ | `body.name` | `string \| null` | no | max length 255 |
444
+
445
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
446
+
447
+ Other envelope fields: `pagination` (PaginationMeta).
448
+
449
+ **Example**
450
+
451
+ ```ts
452
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
453
+ const result = await g8.api.quotes.createQuoteBillingContact({ body: { email: "jane@acme.com", mashup_company_id: 1 } });
454
+ ```
455
+
456
+ ---
457
+
458
+ <a id="op-createquotecontact"></a>
459
+
460
+ ### `g8.api.quotes.createQuoteContact(input)`
461
+
462
+ **Create Quote Contact**
463
+
464
+ - HTTP: `POST /api/v1/quote-contacts`
465
+ - operationId: `create_quote_contact_quote_contacts_post` (also callable as `g8.api.call("create_quote_contact_quote_contacts_post", input)`)
466
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
467
+ - API-key scope: `quotes:run`
468
+
469
+ Create a SIGNER contact and link it to the deal and company.
470
+
471
+ The full CRM contact, so the new row is immediately usable as the signer
472
+ rather than being a name on an email. For the finance contact a quote bills
473
+ to, use `/quote-billing-contact`.
474
+
475
+ **Input**
476
+
477
+ | Field | Type | Required | Description |
478
+ |---|---|---|---|
479
+ | `body` | `QuoteContactCreateRequest` | yes | Request body; fields below. |
480
+
481
+ Body fields (`QuoteContactCreateRequest`):
482
+
483
+ | Field | Type | Required | Description |
484
+ |---|---|---|---|
485
+ | `body.email` | `string` | yes | min length 3, max length 320 |
486
+ | `body.buying_role` | `string \| null` | no | |
487
+ | `body.deal_id` | `string \| null` | no | Deal to link it to. |
488
+ | `body.department` | `string \| null` | no | |
489
+ | `body.first_name` | `string \| null` | no | |
490
+ | `body.last_name` | `string \| null` | no | |
491
+ | `body.linkedin_url` | `string \| null` | no | |
492
+ | `body.mashup_company_id` | `integer \| null` | no | Company to link the new contact to. |
493
+ | `body.mobile_phone` | `string \| null` | no | |
494
+ | `body.phone` | `string \| null` | no | |
495
+ | `body.title` | `string \| null` | no | |
496
+
497
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
498
+
499
+ Other envelope fields: `pagination` (PaginationMeta).
500
+
501
+ **Example**
502
+
503
+ ```ts
504
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
505
+ const result = await g8.api.quotes.createQuoteContact({ body: { email: "jane@acme.com" } });
506
+ ```
507
+
508
+ ---
509
+
510
+ <a id="op-createquotetemplate"></a>
511
+
512
+ ### `g8.api.quotes.createQuoteTemplate(input)`
513
+
514
+ **Create Quote Template**
515
+
516
+ - HTTP: `POST /api/v1/quote-templates`
517
+ - operationId: `create_quote_template_quote_templates_post` (also callable as `g8.api.call("create_quote_template_quote_templates_post", input)`)
518
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
519
+ - API-key scope: `quotes:run`
520
+
521
+ Create a template. ORG ADMIN - it changes what every future quote starts as.
522
+
523
+ **Input**
524
+
525
+ | Field | Type | Required | Description |
526
+ |---|---|---|---|
527
+ | `body` | `QuoteTemplateRequest` | yes | Request body; fields below. |
528
+
529
+ Body fields (`QuoteTemplateRequest`):
530
+
531
+ | Field | Type | Required | Description |
532
+ |---|---|---|---|
533
+ | `body.name` | `string` | yes | min length 1, max length 255 |
534
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
535
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
536
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
537
+ | `body.default_line_items` | `Array<Record<string, unknown>> \| null` | no | |
538
+ | `body.default_payment_terms` | `string \| null` | no | |
539
+ | `body.default_valid_days` | `integer \| null` | no | min 1, max 365 |
540
+ | `body.description` | `string \| null` | no | |
541
+ | `body.document_ids` | `Array<string> \| null` | no | Legal documents to attach to every quote built from this template. Ids come from `GET /quote-settings/documents`. |
542
+ | `body.is_default` | `boolean` | no | default `false` |
543
+ | `body.terms_override` | `string \| null` | no | |
544
+
545
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
546
+
547
+ Other envelope fields: `pagination` (PaginationMeta).
548
+
549
+ **Example**
550
+
551
+ ```ts
552
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
553
+ const result = await g8.api.quotes.createQuoteTemplate({ body: { name: "Example" } });
554
+ ```
555
+
556
+ ---
557
+
558
+ <a id="op-deletemanualproduct"></a>
559
+
560
+ ### `g8.api.quotes.deleteManualProduct(input)`
561
+
562
+ **Delete Manual Product**
563
+
564
+ - HTTP: `DELETE /api/v1/manual-products/{product_id}`
565
+ - operationId: `delete_manual_product_manual_products__product_id__delete` (also callable as `g8.api.call("delete_manual_product_manual_products__product_id__delete", input)`)
566
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
567
+ - API-key scope: `quotes:delete`
568
+
569
+ Retire a manual product. A soft delete: line items on existing quotes keep it.
570
+
571
+ **Input**
572
+
573
+ | Field | Type | Required | Description |
574
+ |---|---|---|---|
575
+ | `path.product_id` | `string (uuid)` | yes | Manual product id. |
576
+
577
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
578
+
579
+ Other envelope fields: `pagination` (PaginationMeta).
580
+
581
+ **Example**
582
+
583
+ ```ts
584
+ // destructive: deletes or archives data; confirm with a human before calling.
585
+ const result = await g8.api.quotes.deleteManualProduct({ path: { product_id: "00000000-0000-0000-0000-000000000000" } });
586
+ ```
587
+
588
+ ---
589
+
590
+ <a id="op-deletequote"></a>
591
+
592
+ ### `g8.api.quotes.deleteQuote(input)`
593
+
594
+ **Delete Quote**
595
+
596
+ - HTTP: `DELETE /api/v1/quotes/{quote_id}`
597
+ - operationId: `delete_quote_quotes__quote_id__delete` (also callable as `g8.api.call("delete_quote_quotes__quote_id__delete", input)`)
598
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
599
+ - API-key scope: `quotes:delete`
600
+ - ★ Hand-written: [`g8.quotes.delete()`](../sdk-clients.md#g8-quotes-delete)
601
+
602
+ Delete a draft quote. 400s on any non-draft status (legal-record preservation).
603
+
604
+ **Input**
605
+
606
+ | Field | Type | Required | Description |
607
+ |---|---|---|---|
608
+ | `path.quote_id` | `string` | yes | Quote UUID |
609
+
610
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
611
+
612
+ Other envelope fields: `pagination` (PaginationMeta).
613
+
614
+ **Example**
615
+
616
+ ```ts
617
+ // destructive: deletes or archives data; confirm with a human before calling.
618
+ const result = await g8.api.quotes.deleteQuote({ path: { quote_id: "id" } });
619
+ ```
620
+
621
+ ---
622
+
623
+ <a id="op-deletequotedocument"></a>
624
+
625
+ ### `g8.api.quotes.deleteQuoteDocument(input)`
626
+
627
+ **Delete Quote Document**
628
+
629
+ - HTTP: `DELETE /api/v1/quote-settings/documents/{doc_id}`
630
+ - operationId: `delete_quote_document_quote_settings_documents__doc_id__delete` (also callable as `g8.api.call("delete_quote_document_quote_settings_documents__doc_id__delete", input)`)
631
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
632
+ - API-key scope: `quotes:delete`
633
+
634
+ Remove a document from the library. ORG ADMIN.
635
+
636
+ **Input**
637
+
638
+ | Field | Type | Required | Description |
639
+ |---|---|---|---|
640
+ | `path.doc_id` | `string` | yes | Document id. |
641
+
642
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
643
+
644
+ Other envelope fields: `pagination` (PaginationMeta).
645
+
646
+ **Example**
647
+
648
+ ```ts
649
+ // destructive: deletes or archives data; confirm with a human before calling.
650
+ const result = await g8.api.quotes.deleteQuoteDocument({ path: { doc_id: "id" } });
651
+ ```
652
+
653
+ ---
654
+
655
+ <a id="op-deletequotetemplate"></a>
656
+
657
+ ### `g8.api.quotes.deleteQuoteTemplate(input)`
658
+
659
+ **Delete Quote Template**
660
+
661
+ - HTTP: `DELETE /api/v1/quote-templates/{template_id}`
662
+ - operationId: `delete_quote_template_quote_templates__template_id__delete` (also callable as `g8.api.call("delete_quote_template_quote_templates__template_id__delete", input)`)
663
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
664
+ - API-key scope: `quotes:delete`
665
+
666
+ Delete a template. ORG ADMIN. Quotes already built from it are untouched.
667
+
668
+ **Input**
669
+
670
+ | Field | Type | Required | Description |
671
+ |---|---|---|---|
672
+ | `path.template_id` | `string` | yes | Template id. |
673
+
674
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
675
+
676
+ Other envelope fields: `pagination` (PaginationMeta).
677
+
678
+ **Example**
679
+
680
+ ```ts
681
+ // destructive: deletes or archives data; confirm with a human before calling.
682
+ const result = await g8.api.quotes.deleteQuoteTemplate({ path: { template_id: "id" } });
683
+ ```
684
+
685
+ ---
686
+
687
+ <a id="op-downloadquoteevidence"></a>
688
+
689
+ ### `g8.api.quotes.downloadQuoteEvidence(input)`
690
+
691
+ **Download Quote Evidence**
692
+
693
+ - HTTP: `GET /api/v1/quotes/{quote_id}/evidence/{evidence_id}`
694
+ - operationId: `download_quote_evidence_quotes__quote_id__evidence__evidence_id__get` (also callable as `g8.api.call("download_quote_evidence_quotes__quote_id__evidence__evidence_id__get", input)`)
695
+ - Tier: `read`: reads data; safe to call and to retry
696
+ - API-key scope: `quotes:read`
697
+
698
+ A download URL for one attached PDF. The URL expires after 60 seconds.
699
+
700
+ **Input**
701
+
702
+ | Field | Type | Required | Description |
703
+ |---|---|---|---|
704
+ | `path.quote_id` | `string (uuid)` | yes | Quote id. |
705
+ | `path.evidence_id` | `string (uuid)` | yes | Evidence id. |
706
+
707
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
708
+
709
+ Other envelope fields: `pagination` (PaginationMeta).
710
+
711
+ **Example**
712
+
713
+ ```ts
714
+ const result = await g8.api.quotes.downloadQuoteEvidence({
715
+ path: {
716
+ quote_id: "00000000-0000-0000-0000-000000000000",
717
+ evidence_id: "00000000-0000-0000-0000-000000000000",
718
+ },
719
+ });
720
+ ```
721
+
722
+ ---
723
+
724
+ <a id="op-duplicatequote"></a>
725
+
726
+ ### `g8.api.quotes.duplicateQuote(input)`
727
+
728
+ **Duplicate Quote**
729
+
730
+ - HTTP: `POST /api/v1/quotes/{quote_id}/duplicate`
731
+ - operationId: `duplicate_quote_quotes__quote_id__duplicate_post` (also callable as `g8.api.call("duplicate_quote_quotes__quote_id__duplicate_post", input)`)
732
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
733
+ - API-key scope: `quotes:run`
734
+ - ★ Hand-written: [`g8.quotes.duplicate()`](../sdk-clients.md#g8-quotes-duplicate)
735
+
736
+ Clone any quote into a new draft. Title gets ``(Copy)`` suffix.
737
+
738
+ **Input**
739
+
740
+ | Field | Type | Required | Description |
741
+ |---|---|---|---|
742
+ | `path.quote_id` | `string` | yes | Source quote UUID (any status) |
743
+
744
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
745
+
746
+ Other envelope fields: `pagination` (PaginationMeta).
747
+
748
+ `QuoteDetail` fields:
749
+
750
+ | Field | Type | Required | Description |
751
+ |---|---|---|---|
752
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
753
+ | `envelope` | `Record<string, unknown> \| null` | no | |
754
+ | `id` | `string \| null` | no | |
755
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
756
+ | `quote_number` | `string \| null` | no | |
757
+ | `status` | `string \| null` | no | |
758
+ | `title` | `string \| null` | no | |
759
+
760
+ **Example**
761
+
762
+ ```ts
763
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
764
+ const result = await g8.api.quotes.duplicateQuote({ path: { quote_id: "id" } });
765
+ ```
766
+
767
+ ---
768
+
769
+ <a id="op-editquoteasdraft"></a>
770
+
771
+ ### `g8.api.quotes.editQuoteAsDraft(input)`
772
+
773
+ **Edit Quote As Draft**
774
+
775
+ - HTTP: `POST /api/v1/quotes/{quote_id}/edit-as-draft`
776
+ - operationId: `edit_quote_as_draft_quotes__quote_id__edit_as_draft_post` (also callable as `g8.api.call("edit_quote_as_draft_quotes__quote_id__edit_as_draft_post", input)`)
777
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
778
+ - API-key scope: `quotes:run`
779
+ - ★ Hand-written: [`g8.quotes.editAsDraft()`](../sdk-clients.md#g8-quotes-editasdraft)
780
+
781
+ Convert a sent quote back into an editable draft via void+clone.
782
+
783
+ Voids the existing signing envelope (so the recipient's link stops
784
+ resolving), marks the source ``voided``, and creates a fresh ``draft``
785
+ with all the line items copied across. Returns
786
+ ``{new_quote_id, new_quote_number, voided_envelope_id, source_quote_id}``.
787
+ The caller should navigate to / update the new draft.
788
+
789
+ **Input**
790
+
791
+ | Field | Type | Required | Description |
792
+ |---|---|---|---|
793
+ | `path.quote_id` | `string` | yes | Source quote UUID (must be in 'sent' status) |
794
+
795
+ **Returns** `ApiResponse_dict_`: the envelope `{ data: Record<string, unknown>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
796
+
797
+ Other envelope fields: `pagination` (PaginationMeta).
798
+
799
+ **Example**
800
+
801
+ ```ts
802
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
803
+ const result = await g8.api.quotes.editQuoteAsDraft({ path: { quote_id: "id" } });
804
+ ```
805
+
806
+ ---
807
+
808
+ <a id="op-expirequote"></a>
809
+
810
+ ### `g8.api.quotes.expireQuote(input)`
811
+
812
+ **Expire Quote**
813
+
814
+ - HTTP: `POST /api/v1/quotes/{quote_id}/expire`
815
+ - operationId: `expire_quote_quotes__quote_id__expire_post` (also callable as `g8.api.call("expire_quote_quotes__quote_id__expire_post", input)`)
816
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
817
+ - API-key scope: `quotes:delete`
818
+
819
+ Mark a quote expired. TERMINAL - the customer's link stops working.
820
+
821
+ **Input**
822
+
823
+ | Field | Type | Required | Description |
824
+ |---|---|---|---|
825
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
826
+
827
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
828
+
829
+ Other envelope fields: `pagination` (PaginationMeta).
830
+
831
+ **Example**
832
+
833
+ ```ts
834
+ // destructive: deletes or archives data; confirm with a human before calling.
835
+ const result = await g8.api.quotes.expireQuote({ path: { quote_id: "id" } });
836
+ ```
837
+
838
+ ---
839
+
840
+ <a id="op-getcompanyquotes"></a>
841
+
842
+ ### `g8.api.quotes.getCompanyQuotes(input)`
843
+
844
+ **Get Company Quotes**
845
+
846
+ - HTTP: `GET /api/v1/companies/{company_id}/quotes`
847
+ - operationId: `get_company_quotes_companies__company_id__quotes_get` (also callable as `g8.api.call("get_company_quotes_companies__company_id__quotes_get", input)`)
848
+ - Tier: `read`: reads data; safe to call and to retry
849
+ - API-key scope: `quotes:read`
850
+ - ★ Hand-written: [`g8.quotes.forCompany()`](../sdk-clients.md#g8-quotes-forcompany)
851
+
852
+ List every quote attached to a given company (account view).
853
+
854
+ **Input**
855
+
856
+ | Field | Type | Required | Description |
857
+ |---|---|---|---|
858
+ | `path.company_id` | `integer` | yes | MashupCompany ID |
859
+
860
+ **Returns** `ApiResponse_list_QuoteDetail__`: the envelope `{ data: Array<QuoteDetail>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
861
+
862
+ Other envelope fields: `pagination` (PaginationMeta).
863
+
864
+ `QuoteDetail` fields:
865
+
866
+ | Field | Type | Required | Description |
867
+ |---|---|---|---|
868
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
869
+ | `envelope` | `Record<string, unknown> \| null` | no | |
870
+ | `id` | `string \| null` | no | |
871
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
872
+ | `quote_number` | `string \| null` | no | |
873
+ | `status` | `string \| null` | no | |
874
+ | `title` | `string \| null` | no | |
875
+
876
+ **Example**
877
+
878
+ ```ts
879
+ const result = await g8.api.quotes.getCompanyQuotes({ path: { company_id: 123 } });
880
+ ```
881
+
882
+ ---
883
+
884
+ <a id="op-getcompanyrevenuesummary"></a>
885
+
886
+ ### `g8.api.quotes.getCompanyRevenueSummary(input)`
887
+
888
+ **Get Company Revenue Summary**
889
+
890
+ - HTTP: `GET /api/v1/stripe/companies/{company_id}/revenue-summary`
891
+ - operationId: `get_company_revenue_summary_stripe_companies__company_id__revenue_summary_get` (also callable as `g8.api.call("get_company_revenue_summary_stripe_companies__company_id__revenue_summary_get", input)`)
892
+ - Tier: `read`: reads data; safe to call and to retry
893
+ - API-key scope: `quotes:read`
894
+
895
+ Total paid, MRR, invoice count and customer-since date for one company.
896
+
897
+ **Input**
898
+
899
+ | Field | Type | Required | Description |
900
+ |---|---|---|---|
901
+ | `path.company_id` | `integer` | yes | graph8 company id. |
902
+
903
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
904
+
905
+ Other envelope fields: `pagination` (PaginationMeta).
906
+
907
+ **Example**
908
+
909
+ ```ts
910
+ const result = await g8.api.quotes.getCompanyRevenueSummary({ path: { company_id: 123 } });
911
+ ```
912
+
913
+ ---
914
+
915
+ <a id="op-getcompanystripeinvoices"></a>
916
+
917
+ ### `g8.api.quotes.getCompanyStripeInvoices(input)`
918
+
919
+ **Get Company Stripe Invoices**
920
+
921
+ - HTTP: `GET /api/v1/stripe/companies/{company_id}/invoices`
922
+ - operationId: `get_company_stripe_invoices_stripe_companies__company_id__invoices_get` (also callable as `g8.api.call("get_company_stripe_invoices_stripe_companies__company_id__invoices_get", input)`)
923
+ - Tier: `read`: reads data; safe to call and to retry
924
+ - API-key scope: `quotes:read`
925
+
926
+ A company's Stripe invoice history, newest first.
927
+
928
+ **Input**
929
+
930
+ | Field | Type | Required | Description |
931
+ |---|---|---|---|
932
+ | `path.company_id` | `integer` | yes | graph8 company id. |
933
+ | `query.page` | `integer` | no | 1-based page. default `1` |
934
+ | `query.limit` | `integer` | no | default `50` |
935
+
936
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
937
+
938
+ Other envelope fields: `pagination` (PaginationMeta).
939
+
940
+ `BillingListPayload` fields:
941
+
942
+ | Field | Type | Required | Description |
943
+ |---|---|---|---|
944
+ | `items` | `Array<unknown>` | no | |
945
+
946
+ **Example**
947
+
948
+ ```ts
949
+ const result = await g8.api.quotes.getCompanyStripeInvoices({ path: { company_id: 123 } });
950
+ ```
951
+
952
+ ---
953
+
954
+ <a id="op-getcompanystripesubscriptions"></a>
955
+
956
+ ### `g8.api.quotes.getCompanyStripeSubscriptions(input)`
957
+
958
+ **Get Company Stripe Subscriptions**
959
+
960
+ - HTTP: `GET /api/v1/stripe/companies/{company_id}/subscriptions`
961
+ - operationId: `get_company_stripe_subscriptions_stripe_companies__company_id__subscriptions_get` (also callable as `g8.api.call("get_company_stripe_subscriptions_stripe_companies__company_id__subscriptions_get", input)`)
962
+ - Tier: `read`: reads data; safe to call and to retry
963
+ - API-key scope: `quotes:read`
964
+
965
+ A company's current Stripe subscriptions, through its customer mapping.
966
+
967
+ **Input**
968
+
969
+ | Field | Type | Required | Description |
970
+ |---|---|---|---|
971
+ | `path.company_id` | `integer` | yes | graph8 company id. |
972
+
973
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
974
+
975
+ Other envelope fields: `pagination` (PaginationMeta).
976
+
977
+ `BillingListPayload` fields:
978
+
979
+ | Field | Type | Required | Description |
980
+ |---|---|---|---|
981
+ | `items` | `Array<unknown>` | no | |
982
+
983
+ **Example**
984
+
985
+ ```ts
986
+ const result = await g8.api.quotes.getCompanyStripeSubscriptions({ path: { company_id: 123 } });
987
+ ```
988
+
989
+ ---
990
+
991
+ <a id="op-getcontactquotes"></a>
992
+
993
+ ### `g8.api.quotes.getContactQuotes(input)`
994
+
995
+ **Get Contact Quotes**
996
+
997
+ - HTTP: `GET /api/v1/contacts/{contact_id}/quotes`
998
+ - operationId: `get_contact_quotes_contacts__contact_id__quotes_get` (also callable as `g8.api.call("get_contact_quotes_contacts__contact_id__quotes_get", input)`)
999
+ - Tier: `read`: reads data; safe to call and to retry
1000
+ - API-key scope: `quotes:read`
1001
+ - ★ Hand-written: [`g8.quotes.forContact()`](../sdk-clients.md#g8-quotes-forcontact)
1002
+
1003
+ List quotes where this contact is the signer.
1004
+
1005
+ **Input**
1006
+
1007
+ | Field | Type | Required | Description |
1008
+ |---|---|---|---|
1009
+ | `path.contact_id` | `integer` | yes | MashupContact ID (the quote signer) |
1010
+
1011
+ **Returns** `ApiResponse_list_QuoteDetail__`: the envelope `{ data: Array<QuoteDetail>, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1012
+
1013
+ Other envelope fields: `pagination` (PaginationMeta).
1014
+
1015
+ `QuoteDetail` fields:
1016
+
1017
+ | Field | Type | Required | Description |
1018
+ |---|---|---|---|
1019
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
1020
+ | `envelope` | `Record<string, unknown> \| null` | no | |
1021
+ | `id` | `string \| null` | no | |
1022
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
1023
+ | `quote_number` | `string \| null` | no | |
1024
+ | `status` | `string \| null` | no | |
1025
+ | `title` | `string \| null` | no | |
1026
+
1027
+ **Example**
1028
+
1029
+ ```ts
1030
+ const result = await g8.api.quotes.getContactQuotes({ path: { contact_id: 123 } });
1031
+ ```
1032
+
1033
+ ---
1034
+
1035
+ <a id="op-getquote"></a>
1036
+
1037
+ ### `g8.api.quotes.getQuote(input)`
1038
+
1039
+ **Get Quote**
1040
+
1041
+ - HTTP: `GET /api/v1/quotes/{quote_id}`
1042
+ - operationId: `get_quote_quotes__quote_id__get` (also callable as `g8.api.call("get_quote_quotes__quote_id__get", input)`)
1043
+ - Tier: `read`: reads data; safe to call and to retry
1044
+ - API-key scope: `quotes:read`
1045
+ - ★ Hand-written: [`g8.quotes.get()`](../sdk-clients.md#g8-quotes-get)
1046
+
1047
+ Get full quote detail: line items, activity log, envelope tracking, resolved contact/company names.
1048
+
1049
+ **Input**
1050
+
1051
+ | Field | Type | Required | Description |
1052
+ |---|---|---|---|
1053
+ | `path.quote_id` | `string` | yes | Quote UUID |
1054
+
1055
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1056
+
1057
+ Other envelope fields: `pagination` (PaginationMeta).
1058
+
1059
+ `QuoteDetail` fields:
1060
+
1061
+ | Field | Type | Required | Description |
1062
+ |---|---|---|---|
1063
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
1064
+ | `envelope` | `Record<string, unknown> \| null` | no | |
1065
+ | `id` | `string \| null` | no | |
1066
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
1067
+ | `quote_number` | `string \| null` | no | |
1068
+ | `status` | `string \| null` | no | |
1069
+ | `title` | `string \| null` | no | |
1070
+
1071
+ **Example**
1072
+
1073
+ ```ts
1074
+ const result = await g8.api.quotes.getQuote({ path: { quote_id: "id" } });
1075
+ ```
1076
+
1077
+ ---
1078
+
1079
+ <a id="op-getquotepdf"></a>
1080
+
1081
+ ### `g8.api.quotes.getQuotePdf(input)`
1082
+
1083
+ **Get Quote Pdf**
1084
+
1085
+ - HTTP: `GET /api/v1/quotes/{quote_id}/pdf`
1086
+ - operationId: `get_quote_pdf_quotes__quote_id__pdf_get` (also callable as `g8.api.call("get_quote_pdf_quotes__quote_id__pdf_get", input)`)
1087
+ - Tier: `read`: reads data; safe to call and to retry
1088
+ - API-key scope: `quotes:read`
1089
+
1090
+ The quote document, as the customer sees it.
1091
+
1092
+ **Input**
1093
+
1094
+ | Field | Type | Required | Description |
1095
+ |---|---|---|---|
1096
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
1097
+
1098
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1099
+
1100
+ Other envelope fields: `pagination` (PaginationMeta).
1101
+
1102
+ **Example**
1103
+
1104
+ ```ts
1105
+ const result = await g8.api.quotes.getQuotePdf({ path: { quote_id: "id" } });
1106
+ ```
1107
+
1108
+ ---
1109
+
1110
+ <a id="op-getquotesettings"></a>
1111
+
1112
+ ### `g8.api.quotes.getQuoteSettings(input?)`
1113
+
1114
+ **Get Quote Settings**
1115
+
1116
+ - HTTP: `GET /api/v1/quote-settings`
1117
+ - operationId: `get_quote_settings_quote_settings_get` (also callable as `g8.api.call("get_quote_settings_quote_settings_get", input)`)
1118
+ - Tier: `read`: reads data; safe to call and to retry
1119
+ - API-key scope: `quotes:read`
1120
+ - ★ Hand-written: [`g8.quotes.settings()`](../sdk-clients.md#g8-quotes-settings)
1121
+
1122
+ Get org quote settings (branding, default terms, sender identity).
1123
+
1124
+ Auto-creates default settings if none exist for the org.
1125
+
1126
+ **Input**: none.
1127
+
1128
+ **Returns** `ApiResponse_QuoteSettingsResponse_`: the envelope `{ data: QuoteSettingsResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1129
+
1130
+ Other envelope fields: `pagination` (PaginationMeta).
1131
+
1132
+ **Example**
1133
+
1134
+ ```ts
1135
+ const result = await g8.api.quotes.getQuoteSettings();
1136
+ ```
1137
+
1138
+ ---
1139
+
1140
+ <a id="op-getstripedata"></a>
1141
+
1142
+ ### `g8.api.quotes.getStripeData(input)`
1143
+
1144
+ **Get Stripe Data**
1145
+
1146
+ - HTTP: `GET /api/v1/stripe/connections/{connection_id}/data`
1147
+ - operationId: `get_stripe_data_stripe_connections__connection_id__data_get` (also callable as `g8.api.call("get_stripe_data_stripe_connections__connection_id__data_get", input)`)
1148
+ - Tier: `read`: reads data; safe to call and to retry
1149
+ - API-key scope: `quotes:read`
1150
+
1151
+ Recent customers, subscriptions, invoices and charges, read LIVE from Stripe.
1152
+
1153
+ `connection_id` must be the org's own stored connection - any other id is
1154
+ a 404, because connection ids are guessable.
1155
+
1156
+ **Input**
1157
+
1158
+ | Field | Type | Required | Description |
1159
+ |---|---|---|---|
1160
+ | `path.connection_id` | `string` | yes | The org's Stripe connection id. |
1161
+
1162
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1163
+
1164
+ Other envelope fields: `pagination` (PaginationMeta).
1165
+
1166
+ **Example**
1167
+
1168
+ ```ts
1169
+ const result = await g8.api.quotes.getStripeData({ path: { connection_id: "id" } });
1170
+ ```
1171
+
1172
+ ---
1173
+
1174
+ <a id="op-getstripedatapage"></a>
1175
+
1176
+ ### `g8.api.quotes.getStripeDataPage(input)`
1177
+
1178
+ **Get Stripe Data Page**
1179
+
1180
+ - HTTP: `GET /api/v1/stripe/connections/{connection_id}/data/{resource}`
1181
+ - operationId: `get_stripe_data_page_stripe_connections__connection_id__data__resource__get` (also callable as `g8.api.call("get_stripe_data_page_stripe_connections__connection_id__data__resource__get", input)`)
1182
+ - Tier: `read`: reads data; safe to call and to retry
1183
+ - API-key scope: `quotes:read`
1184
+
1185
+ One page of a Stripe list, read live. Cursor-paged: pass `next_cursor`
1186
+ back as `starting_after`; `has_more` false means the last page.
1187
+
1188
+ **Input**
1189
+
1190
+ | Field | Type | Required | Description |
1191
+ |---|---|---|---|
1192
+ | `path.connection_id` | `string` | yes | The org's Stripe connection id. |
1193
+ | `path.resource` | `"customers" \| "subscriptions" \| "invoices" \| "charges"` | yes | Which Stripe list to page through. |
1194
+ | `query.limit` | `integer` | no | default `20` |
1195
+ | `query.starting_after` | `string \| null` | no | `next_cursor` from the previous page. |
1196
+
1197
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1198
+
1199
+ Other envelope fields: `pagination` (PaginationMeta).
1200
+
1201
+ **Example**
1202
+
1203
+ ```ts
1204
+ const result = await g8.api.quotes.getStripeDataPage({ path: { connection_id: "id", resource: "customers" } });
1205
+ ```
1206
+
1207
+ ---
1208
+
1209
+ <a id="op-getstripeintegrationstatus"></a>
1210
+
1211
+ ### `g8.api.quotes.getStripeIntegrationStatus(input?)`
1212
+
1213
+ **Get Stripe Integration Status**
1214
+
1215
+ - HTTP: `GET /api/v1/stripe/integration-status`
1216
+ - operationId: `get_stripe_integration_status_stripe_integration_status_get` (also callable as `g8.api.call("get_stripe_integration_status_stripe_integration_status_get", input)`)
1217
+ - Tier: `read`: reads data; safe to call and to retry
1218
+ - API-key scope: `quotes:read`
1219
+
1220
+ Whether the quote catalogue is ready: `state` is one of `needs_catalog`,
1221
+ `syncing`, `no_quotable_products` or `ready`, counted across Stripe AND the
1222
+ manual catalogue.
1223
+
1224
+ **Input**: none.
1225
+
1226
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1227
+
1228
+ Other envelope fields: `pagination` (PaginationMeta).
1229
+
1230
+ **Example**
1231
+
1232
+ ```ts
1233
+ const result = await g8.api.quotes.getStripeIntegrationStatus();
1234
+ ```
1235
+
1236
+ ---
1237
+
1238
+ <a id="op-listmanualproducts"></a>
1239
+
1240
+ ### `g8.api.quotes.listManualProducts(input?)`
1241
+
1242
+ **List Manual Products**
1243
+
1244
+ - HTTP: `GET /api/v1/manual-products`
1245
+ - operationId: `list_manual_products_manual_products_get` (also callable as `g8.api.call("list_manual_products_manual_products_get", input)`)
1246
+ - Tier: `read`: reads data; safe to call and to retry
1247
+ - API-key scope: `quotes:read`
1248
+
1249
+ The org's own product catalogue - quotable with or without Stripe.
1250
+
1251
+ **Input**
1252
+
1253
+ | Field | Type | Required | Description |
1254
+ |---|---|---|---|
1255
+ | `query.include_inactive` | `boolean` | no | Include inactive products. default `false` |
1256
+ | `query.include_non_quotable` | `boolean` | no | Include products not offered on quotes. default `true` |
1257
+ | `query.category` | `string \| null` | no | |
1258
+ | `query.page` | `integer` | no | 1-based page. default `1` |
1259
+ | `query.limit` | `integer` | no | default `100` |
1260
+
1261
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1262
+
1263
+ Other envelope fields: `pagination` (PaginationMeta).
1264
+
1265
+ `BillingListPayload` fields:
1266
+
1267
+ | Field | Type | Required | Description |
1268
+ |---|---|---|---|
1269
+ | `items` | `Array<unknown>` | no | |
1270
+
1271
+ **Example**
1272
+
1273
+ ```ts
1274
+ const result = await g8.api.quotes.listManualProducts();
1275
+ ```
1276
+
1277
+ ---
1278
+
1279
+ <a id="op-listquotableproducts"></a>
1280
+
1281
+ ### `g8.api.quotes.listQuotableProducts(input?)`
1282
+
1283
+ **List Quotable Products**
1284
+
1285
+ - HTTP: `GET /api/v1/quotable-products`
1286
+ - operationId: `list_quotable_products_quotable_products_get` (also callable as `g8.api.call("list_quotable_products_quotable_products_get", input)`)
1287
+ - Tier: `read`: reads data; safe to call and to retry
1288
+ - API-key scope: `quotes:read`
1289
+ - ★ Hand-written: [`g8.quotes.products()`](../sdk-clients.md#g8-quotes-products)
1290
+
1291
+ List products available for quote line items (Stripe catalog + org manual catalog).
1292
+
1293
+ **Input**
1294
+
1295
+ | Field | Type | Required | Description |
1296
+ |---|---|---|---|
1297
+ | `query.currency` | `string \| null` | no | Filter prices to this currency code (e.g. USD) |
1298
+ | `query.page` | `integer` | no | default `1` |
1299
+ | `query.limit` | `integer` | no | default `100` |
1300
+
1301
+ **Returns** `ApiResponse_QuotableProductsResponse_`: the envelope `{ data: QuotableProductsResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1302
+
1303
+ Other envelope fields: `pagination` (PaginationMeta).
1304
+
1305
+ `QuotableProductsResponse` fields:
1306
+
1307
+ | Field | Type | Required | Description |
1308
+ |---|---|---|---|
1309
+ | `items` | `Array<Record<string, unknown>>` | yes | |
1310
+ | `limit` | `integer` | yes | |
1311
+ | `page` | `integer` | yes | |
1312
+ | `total` | `integer` | yes | |
1313
+
1314
+ **Example**
1315
+
1316
+ ```ts
1317
+ const result = await g8.api.quotes.listQuotableProducts();
1318
+ ```
1319
+
1320
+ ---
1321
+
1322
+ <a id="op-listquotedocuments"></a>
1323
+
1324
+ ### `g8.api.quotes.listQuoteDocuments(input?)`
1325
+
1326
+ **List Quote Documents**
1327
+
1328
+ - HTTP: `GET /api/v1/quote-settings/documents`
1329
+ - operationId: `list_quote_documents_quote_settings_documents_get` (also callable as `g8.api.call("list_quote_documents_quote_settings_documents_get", input)`)
1330
+ - Tier: `read`: reads data; safe to call and to retry
1331
+ - API-key scope: `quotes:read`
1332
+
1333
+ The reusable legal documents a template can attach. A READ.
1334
+
1335
+ **Input**: none.
1336
+
1337
+ **Returns** `ApiResponse_QuoteListPayload_`: the envelope `{ data: QuoteListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1338
+
1339
+ Other envelope fields: `pagination` (PaginationMeta).
1340
+
1341
+ `QuoteListPayload` fields:
1342
+
1343
+ | Field | Type | Required | Description |
1344
+ |---|---|---|---|
1345
+ | `items` | `Array<unknown>` | no | |
1346
+
1347
+ **Example**
1348
+
1349
+ ```ts
1350
+ const result = await g8.api.quotes.listQuoteDocuments();
1351
+ ```
1352
+
1353
+ ---
1354
+
1355
+ <a id="op-listquoteevidence"></a>
1356
+
1357
+ ### `g8.api.quotes.listQuoteEvidence(input)`
1358
+
1359
+ **List Quote Evidence**
1360
+
1361
+ - HTTP: `GET /api/v1/quotes/{quote_id}/evidence`
1362
+ - operationId: `list_quote_evidence_quotes__quote_id__evidence_get` (also callable as `g8.api.call("list_quote_evidence_quotes__quote_id__evidence_get", input)`)
1363
+ - Tier: `read`: reads data; safe to call and to retry
1364
+ - API-key scope: `quotes:read`
1365
+
1366
+ The PDFs attached to a quote, newest first.
1367
+
1368
+ **Input**
1369
+
1370
+ | Field | Type | Required | Description |
1371
+ |---|---|---|---|
1372
+ | `path.quote_id` | `string (uuid)` | yes | Quote id. |
1373
+
1374
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1375
+
1376
+ Other envelope fields: `pagination` (PaginationMeta).
1377
+
1378
+ `BillingListPayload` fields:
1379
+
1380
+ | Field | Type | Required | Description |
1381
+ |---|---|---|---|
1382
+ | `items` | `Array<unknown>` | no | |
1383
+
1384
+ **Example**
1385
+
1386
+ ```ts
1387
+ const result = await g8.api.quotes.listQuoteEvidence({ path: { quote_id: "00000000-0000-0000-0000-000000000000" } });
1388
+ ```
1389
+
1390
+ ---
1391
+
1392
+ <a id="op-listquotetemplates"></a>
1393
+
1394
+ ### `g8.api.quotes.listQuoteTemplates(input?)`
1395
+
1396
+ **List Quote Templates**
1397
+
1398
+ - HTTP: `GET /api/v1/quote-templates`
1399
+ - operationId: `list_quote_templates_quote_templates_get` (also callable as `g8.api.call("list_quote_templates_quote_templates_get", input)`)
1400
+ - Tier: `read`: reads data; safe to call and to retry
1401
+ - API-key scope: `quotes:read`
1402
+
1403
+ Reusable quote templates. A READ - any key, not just an admin's.
1404
+
1405
+ Matching the app, where listing is `get_current_user` and only the writes
1406
+ below are admin-gated.
1407
+
1408
+ **Input**: none.
1409
+
1410
+ **Returns** `ApiResponse_QuoteListPayload_`: the envelope `{ data: QuoteListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1411
+
1412
+ Other envelope fields: `pagination` (PaginationMeta).
1413
+
1414
+ `QuoteListPayload` fields:
1415
+
1416
+ | Field | Type | Required | Description |
1417
+ |---|---|---|---|
1418
+ | `items` | `Array<unknown>` | no | |
1419
+
1420
+ **Example**
1421
+
1422
+ ```ts
1423
+ const result = await g8.api.quotes.listQuoteTemplates();
1424
+ ```
1425
+
1426
+ ---
1427
+
1428
+ <a id="op-listquotes"></a>
1429
+
1430
+ ### `g8.api.quotes.listQuotes(input?)`
1431
+
1432
+ **List Quotes**
1433
+
1434
+ - HTTP: `GET /api/v1/quotes`
1435
+ - operationId: `list_quotes_quotes_get` (also callable as `g8.api.call("list_quotes_quotes_get", input)`)
1436
+ - Tier: `read`: reads data; safe to call and to retry
1437
+ - API-key scope: `quotes:read`
1438
+ - ★ Hand-written: [`g8.quotes.list()`](../sdk-clients.md#g8-quotes-list)
1439
+
1440
+ List quotes for the org with optional status / company / deal / owner filters.
1441
+
1442
+ **Input**
1443
+
1444
+ | Field | Type | Required | Description |
1445
+ |---|---|---|---|
1446
+ | `query.status` | `string \| null` | no | Filter by quote status: draft, sent, viewed, accepted, declined, voided, expired |
1447
+ | `query.mashup_company_id` | `integer \| null` | no | Filter quotes for a specific company |
1448
+ | `query.deal_id` | `string \| null` | no | Filter quotes linked to a specific deal (UUID) |
1449
+ | `query.owner_id` | `string \| null` | no | Filter quotes owned by a specific user (email) |
1450
+ | `query.page` | `integer` | no | default `1` |
1451
+ | `query.limit` | `integer` | no | default `50` |
1452
+
1453
+ **Returns** `ApiResponse_QuoteListResponse_`: the envelope `{ data: QuoteListResponse, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1454
+
1455
+ Other envelope fields: `pagination` (PaginationMeta).
1456
+
1457
+ `QuoteListResponse` fields:
1458
+
1459
+ | Field | Type | Required | Description |
1460
+ |---|---|---|---|
1461
+ | `items` | `Array<QuoteSummary>` | yes | |
1462
+ | `limit` | `integer` | yes | |
1463
+ | `page` | `integer` | yes | |
1464
+ | `total` | `integer` | yes | |
1465
+
1466
+ **Example**
1467
+
1468
+ ```ts
1469
+ const result = await g8.api.quotes.listQuotes();
1470
+ ```
1471
+
1472
+ ---
1473
+
1474
+ <a id="op-liststripeproductsettings"></a>
1475
+
1476
+ ### `g8.api.quotes.listStripeProductSettings(input?)`
1477
+
1478
+ **List Stripe Product Settings**
1479
+
1480
+ - HTTP: `GET /api/v1/stripe/product-settings`
1481
+ - operationId: `list_stripe_product_settings_stripe_product_settings_get` (also callable as `g8.api.call("list_stripe_product_settings_stripe_product_settings_get", input)`)
1482
+ - Tier: `read`: reads data; safe to call and to retry
1483
+ - API-key scope: `quotes:read`
1484
+
1485
+ Every synced product with its quote-builder name, category and `quotable` flag.
1486
+
1487
+ **Input**: none.
1488
+
1489
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1490
+
1491
+ Other envelope fields: `pagination` (PaginationMeta).
1492
+
1493
+ `BillingListPayload` fields:
1494
+
1495
+ | Field | Type | Required | Description |
1496
+ |---|---|---|---|
1497
+ | `items` | `Array<unknown>` | no | |
1498
+
1499
+ **Example**
1500
+
1501
+ ```ts
1502
+ const result = await g8.api.quotes.listStripeProductSettings();
1503
+ ```
1504
+
1505
+ ---
1506
+
1507
+ <a id="op-liststripeproductsubscribers"></a>
1508
+
1509
+ ### `g8.api.quotes.listStripeProductSubscribers(input)`
1510
+
1511
+ **List Stripe Product Subscribers**
1512
+
1513
+ - HTTP: `GET /api/v1/stripe/products/{product_id}/subscribers`
1514
+ - operationId: `list_stripe_product_subscribers_stripe_products__product_id__subscribers_get` (also callable as `g8.api.call("list_stripe_product_subscribers_stripe_products__product_id__subscribers_get", input)`)
1515
+ - Tier: `read`: reads data; safe to call and to retry
1516
+ - API-key scope: `quotes:read`
1517
+
1518
+ Customers subscribed to one product, with the graph8 company each maps to.
1519
+
1520
+ **Input**
1521
+
1522
+ | Field | Type | Required | Description |
1523
+ |---|---|---|---|
1524
+ | `path.product_id` | `string` | yes | Stripe product id. |
1525
+ | `query.page` | `integer` | no | 1-based page. default `1` |
1526
+ | `query.limit` | `integer` | no | default `100` |
1527
+ | `query.filter_model` | `string \| null` | no | Grid filter model as JSON, as the app's grid sends it. |
1528
+ | `query.sort_model` | `string \| null` | no | Grid sort model as JSON. |
1529
+
1530
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1531
+
1532
+ Other envelope fields: `pagination` (PaginationMeta).
1533
+
1534
+ `BillingListPayload` fields:
1535
+
1536
+ | Field | Type | Required | Description |
1537
+ |---|---|---|---|
1538
+ | `items` | `Array<unknown>` | no | |
1539
+
1540
+ **Example**
1541
+
1542
+ ```ts
1543
+ const result = await g8.api.quotes.listStripeProductSubscribers({ path: { product_id: "id" } });
1544
+ ```
1545
+
1546
+ ---
1547
+
1548
+ <a id="op-liststripeproducts"></a>
1549
+
1550
+ ### `g8.api.quotes.listStripeProducts(input?)`
1551
+
1552
+ **List Stripe Products**
1553
+
1554
+ - HTTP: `GET /api/v1/stripe/products`
1555
+ - operationId: `list_stripe_products_stripe_products_get` (also callable as `g8.api.call("list_stripe_products_stripe_products_get", input)`)
1556
+ - Tier: `read`: reads data; safe to call and to retry
1557
+ - API-key scope: `quotes:read`
1558
+
1559
+ Synced Stripe products with price range, subscriber counts and MRR.
1560
+
1561
+ **Input**
1562
+
1563
+ | Field | Type | Required | Description |
1564
+ |---|---|---|---|
1565
+ | `query.page` | `integer` | no | 1-based page. default `1` |
1566
+ | `query.limit` | `integer` | no | default `100` |
1567
+ | `query.filter_model` | `string \| null` | no | Grid filter model as JSON, as the app's grid sends it. |
1568
+ | `query.sort_model` | `string \| null` | no | Grid sort model as JSON. |
1569
+
1570
+ **Returns** `ApiResponse_BillingListPayload_`: the envelope `{ data: BillingListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1571
+
1572
+ Other envelope fields: `pagination` (PaginationMeta).
1573
+
1574
+ `BillingListPayload` fields:
1575
+
1576
+ | Field | Type | Required | Description |
1577
+ |---|---|---|---|
1578
+ | `items` | `Array<unknown>` | no | |
1579
+
1580
+ **Example**
1581
+
1582
+ ```ts
1583
+ const result = await g8.api.quotes.listStripeProducts();
1584
+ ```
1585
+
1586
+ ---
1587
+
1588
+ <a id="op-markquoteaccepted"></a>
1589
+
1590
+ ### `g8.api.quotes.markQuoteAccepted(input)`
1591
+
1592
+ **Mark Quote Accepted**
1593
+
1594
+ - HTTP: `POST /api/v1/quotes/{quote_id}/mark-accepted`
1595
+ - operationId: `mark_quote_accepted_quotes__quote_id__mark_accepted_post` (also callable as `g8.api.call("mark_quote_accepted_quotes__quote_id__mark_accepted_post", input)`)
1596
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
1597
+ - API-key scope: `quotes:run`
1598
+
1599
+ Accept a quote on the customer's behalf. THIS RAISES AN INVOICE.
1600
+
1601
+ It runs the same provisioning path a signed envelope runs: the quote flips
1602
+ to accepted, the total rolls up to the linked deal, and
1603
+ `provision_from_accepted_quote` materialises the invoice or subscription
1604
+ with the org's configured billing provider. Use it when the customer paid
1605
+ or signed outside graph8, not to tidy up a stale quote.
1606
+
1607
+ `evidence_type` and `evidence_note` are REQUIRED and land on the audit row
1608
+ stamped `method="manual"`, so a manual accept stays distinguishable from a
1609
+ signed-envelope accept forever.
1610
+
1611
+ The app additionally requires the caller to be an Owner/Admin or the
1612
+ resolved quote/deal owner, and refuses a quote that is not in the
1613
+ sent/viewed transition set with a 409.
1614
+
1615
+ **Input**
1616
+
1617
+ | Field | Type | Required | Description |
1618
+ |---|---|---|---|
1619
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
1620
+ | `body` | `ManualAcceptRequest` | yes | Request body; fields below. |
1621
+
1622
+ Body fields (`ManualAcceptRequest`):
1623
+
1624
+ | Field | Type | Required | Description |
1625
+ |---|---|---|---|
1626
+ | `body.evidence_note` | `string` | yes | What happened, in the accepter's own words. Stored on the audit row. min length 3, max length 2000 |
1627
+ | `body.evidence_type` | `"offline_signature" \| "customer_email" \| "verbal_authorization" \| "payment_received"` | yes | How the customer accepted, outside the e-sign flow. |
1628
+
1629
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1630
+
1631
+ Other envelope fields: `pagination` (PaginationMeta).
1632
+
1633
+ **Example**
1634
+
1635
+ ```ts
1636
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
1637
+ const result = await g8.api.quotes.markQuoteAccepted({
1638
+ path: { quote_id: "id" },
1639
+ body: { evidence_note: "example", evidence_type: "offline_signature" },
1640
+ });
1641
+ ```
1642
+
1643
+ ---
1644
+
1645
+ <a id="op-previewpaymentschedule"></a>
1646
+
1647
+ ### `g8.api.quotes.previewPaymentSchedule(input)`
1648
+
1649
+ **Preview Payment Schedule**
1650
+
1651
+ - HTTP: `POST /api/v1/quotes/payment-schedule`
1652
+ - operationId: `preview_payment_schedule_quotes_payment_schedule_post` (also callable as `g8.api.call("preview_payment_schedule_quotes_payment_schedule_post", input)`)
1653
+ - Tier: `read`: reads data; safe to call and to retry
1654
+ - API-key scope: `quotes:read`
1655
+
1656
+ What a set of line items would bill, and when. Arithmetic over the body.
1657
+
1658
+ **Input**
1659
+
1660
+ | Field | Type | Required | Description |
1661
+ |---|---|---|---|
1662
+ | `body` | `PaymentSchedulePreviewRequest` | yes | Request body; fields below. |
1663
+
1664
+ Body fields (`PaymentSchedulePreviewRequest`):
1665
+
1666
+ | Field | Type | Required | Description |
1667
+ |---|---|---|---|
1668
+ | `body.contract_start_date` | `string` | yes | ISO date the contract starts. |
1669
+ | `body.line_items` | `Array<QuoteLineItem>` | yes | min items 1, max items 500 |
1670
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
1671
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
1672
+ | `body.contract_end_date` | `string \| null` | no | |
1673
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
1674
+ | `body.tax_amount` | `integer` | no | default `0`, min 0, max 1000000000 |
1675
+
1676
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1677
+
1678
+ Other envelope fields: `pagination` (PaginationMeta).
1679
+
1680
+ **Example**
1681
+
1682
+ ```ts
1683
+ const result = await g8.api.quotes.previewPaymentSchedule({
1684
+ body: {
1685
+ contract_start_date: "example",
1686
+ line_items: [{ product_name: "Example", unit_amount: 0 }],
1687
+ },
1688
+ });
1689
+ ```
1690
+
1691
+ ---
1692
+
1693
+ <a id="op-previewquotedraft"></a>
1694
+
1695
+ ### `g8.api.quotes.previewQuoteDraft(input)`
1696
+
1697
+ **Preview Quote Draft**
1698
+
1699
+ - HTTP: `POST /api/v1/quotes/preview-draft`
1700
+ - operationId: `preview_quote_draft_quotes_preview_draft_post` (also callable as `g8.api.call("preview_quote_draft_quotes_preview_draft_post", input)`)
1701
+ - Tier: `read`: reads data; safe to call and to retry
1702
+ - API-key scope: `quotes:read`
1703
+
1704
+ Render a quote that does not exist yet. Creates nothing.
1705
+
1706
+ **Input**
1707
+
1708
+ | Field | Type | Required | Description |
1709
+ |---|---|---|---|
1710
+ | `body` | `Record<string, unknown>` | yes | Request body; fields below. |
1711
+
1712
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1713
+
1714
+ Other envelope fields: `pagination` (PaginationMeta).
1715
+
1716
+ **Example**
1717
+
1718
+ ```ts
1719
+ const result = await g8.api.quotes.previewQuoteDraft({ body: {} });
1720
+ ```
1721
+
1722
+ ---
1723
+
1724
+ <a id="op-previewquotesend"></a>
1725
+
1726
+ ### `g8.api.quotes.previewQuoteSend(input)`
1727
+
1728
+ **Preview Quote Send**
1729
+
1730
+ - HTTP: `POST /api/v1/quotes/{quote_id}/send-preview`
1731
+ - operationId: `preview_quote_send_quotes__quote_id__send_preview_post` (also callable as `g8.api.call("preview_quote_send_quotes__quote_id__send_preview_post", input)`)
1732
+ - Tier: `read`: reads data; safe to call and to retry
1733
+ - API-key scope: `quotes:read`
1734
+
1735
+ Render the exact email and document `/send` would produce. SENDS NOTHING.
1736
+
1737
+ Takes the identical body to `/send` on purpose - a preview rendered from a
1738
+ different body predicts nothing. `deliver` is accepted and inert.
1739
+
1740
+ Tiered as a READ: it renders and returns, and nothing in the handler
1741
+ reaches a mail transport.
1742
+
1743
+ **Input**
1744
+
1745
+ | Field | Type | Required | Description |
1746
+ |---|---|---|---|
1747
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
1748
+ | `body` | `QuoteSendPreviewRequest` | yes | Request body; fields below. |
1749
+
1750
+ Body fields (`QuoteSendPreviewRequest`):
1751
+
1752
+ | Field | Type | Required | Description |
1753
+ |---|---|---|---|
1754
+ | `body.cc_emails` | `Array<string> \| null` | no | |
1755
+ | `body.deliver` | `boolean` | no | default `true` |
1756
+ | `body.email_body` | `string \| null` | no | |
1757
+ | `body.message` | `string \| null` | no | |
1758
+ | `body.notification_mode` | `"after_each" \| "after_all"` | no | default `"after_each"` |
1759
+ | `body.preview_recipient_email` | `string \| null` | no | |
1760
+ | `body.recipient_email` | `string \| null` | no | |
1761
+ | `body.recipient_name` | `string \| null` | no | |
1762
+ | `body.recipients` | `Array<QuoteSendRecipient> \| null` | no | |
1763
+ | `body.subject` | `string \| null` | no | |
1764
+
1765
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1766
+
1767
+ Other envelope fields: `pagination` (PaginationMeta).
1768
+
1769
+ **Example**
1770
+
1771
+ ```ts
1772
+ const result = await g8.api.quotes.previewQuoteSend({ path: { quote_id: "id" }, body: {} });
1773
+ ```
1774
+
1775
+ ---
1776
+
1777
+ <a id="op-revokequote"></a>
1778
+
1779
+ ### `g8.api.quotes.revokeQuote(input)`
1780
+
1781
+ **Revoke Quote**
1782
+
1783
+ - HTTP: `POST /api/v1/quotes/{quote_id}/revoke`
1784
+ - operationId: `revoke_quote_quotes__quote_id__revoke_post` (also callable as `g8.api.call("revoke_quote_quotes__quote_id__revoke_post", input)`)
1785
+ - Tier: `destructive`: deletes or archives data; confirm with a human before calling
1786
+ - API-key scope: `quotes:delete`
1787
+
1788
+ Withdraw a quote the customer has already been sent. TERMINAL.
1789
+
1790
+ Revoke rather than expire when the offer itself was wrong: it pulls the
1791
+ document back rather than letting it lapse.
1792
+
1793
+ **Input**
1794
+
1795
+ | Field | Type | Required | Description |
1796
+ |---|---|---|---|
1797
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
1798
+
1799
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1800
+
1801
+ Other envelope fields: `pagination` (PaginationMeta).
1802
+
1803
+ **Example**
1804
+
1805
+ ```ts
1806
+ // destructive: deletes or archives data; confirm with a human before calling.
1807
+ const result = await g8.api.quotes.revokeQuote({ path: { quote_id: "id" } });
1808
+ ```
1809
+
1810
+ ---
1811
+
1812
+ <a id="op-searchquotecontacts"></a>
1813
+
1814
+ ### `g8.api.quotes.searchQuoteContacts(input?)`
1815
+
1816
+ **Search Quote Contacts**
1817
+
1818
+ - HTTP: `GET /api/v1/quote-contacts`
1819
+ - operationId: `search_quote_contacts_quote_contacts_get` (also callable as `g8.api.call("search_quote_contacts_quote_contacts_get", input)`)
1820
+ - Tier: `read`: reads data; safe to call and to retry
1821
+ - API-key scope: `quotes:read`
1822
+
1823
+ Find a contact to put on a quote as signer or billing contact.
1824
+
1825
+ **Input**
1826
+
1827
+ | Field | Type | Required | Description |
1828
+ |---|---|---|---|
1829
+ | `query.q` | `string` | no | Name or email fragment. Empty returns the default page. default `""` |
1830
+ | `query.limit` | `integer` | no | The app's default is 100 and deliberately not smaller: the signer picker has to show every plausible match, and a short page reads as 'this contact does not exist'. default `100` |
1831
+ | `query.company_id` | `integer \| null` | no | Scope to contacts at this company. |
1832
+ | `query.deal_id` | `string \| null` | no | Scope to contacts linked to this deal. Combined with `company_id` the two scopes are a UNION - on the deal OR at the company - and each row comes back with an `on_deal` flag. Given `deal_id` alone, the company is derived from the deal. |
1833
+
1834
+ **Returns** `ApiResponse_QuoteListPayload_`: the envelope `{ data: QuoteListPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1835
+
1836
+ Other envelope fields: `pagination` (PaginationMeta).
1837
+
1838
+ `QuoteListPayload` fields:
1839
+
1840
+ | Field | Type | Required | Description |
1841
+ |---|---|---|---|
1842
+ | `items` | `Array<unknown>` | no | |
1843
+
1844
+ **Example**
1845
+
1846
+ ```ts
1847
+ const result = await g8.api.quotes.searchQuoteContacts();
1848
+ ```
1849
+
1850
+ ---
1851
+
1852
+ <a id="op-sendquote"></a>
1853
+
1854
+ ### `g8.api.quotes.sendQuote(input)`
1855
+
1856
+ **Send Quote**
1857
+
1858
+ - HTTP: `POST /api/v1/quotes/{quote_id}/send`
1859
+ - operationId: `send_quote_quotes__quote_id__send_post` (also callable as `g8.api.call("send_quote_quotes__quote_id__send_post", input)`)
1860
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
1861
+ - API-key scope: `quotes:run`
1862
+ - ★ Hand-written: [`g8.quotes.send()`](../sdk-clients.md#g8-quotes-send)
1863
+
1864
+ Send the quote for e-signature (or resend if it's already in flight).
1865
+
1866
+ Side effects: creates / reuses a signing envelope, sends the
1867
+ customer-facing email via SES, logs to the universal inbox, rolls
1868
+ quote status forward to ``sent``. Recipient is resolved from
1869
+ ``signer_contact_id`` or ``signer_email`` (one must be set).
1870
+
1871
+ Idempotent for resend: when the quote already has an envelope in
1872
+ ``sent`` or ``viewed`` state, the existing envelope is re-emailed
1873
+ and the recipient keeps the original signing link.
1874
+
1875
+ **Input**
1876
+
1877
+ | Field | Type | Required | Description |
1878
+ |---|---|---|---|
1879
+ | `path.quote_id` | `string` | yes | Quote UUID (must be in draft or sent status) |
1880
+ | `body` | `QuoteSendRequest` | no | Request body; fields below. |
1881
+
1882
+ Body fields (`QuoteSendRequest`):
1883
+
1884
+ | Field | Type | Required | Description |
1885
+ |---|---|---|---|
1886
+ | `body.message` | `string \| null` | no | |
1887
+ | `body.subject` | `string \| null` | no | |
1888
+
1889
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1890
+
1891
+ Other envelope fields: `pagination` (PaginationMeta).
1892
+
1893
+ `QuoteDetail` fields:
1894
+
1895
+ | Field | Type | Required | Description |
1896
+ |---|---|---|---|
1897
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
1898
+ | `envelope` | `Record<string, unknown> \| null` | no | |
1899
+ | `id` | `string \| null` | no | |
1900
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
1901
+ | `quote_number` | `string \| null` | no | |
1902
+ | `status` | `string \| null` | no | |
1903
+ | `title` | `string \| null` | no | |
1904
+
1905
+ **Example**
1906
+
1907
+ ```ts
1908
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
1909
+ const result = await g8.api.quotes.sendQuote({ path: { quote_id: "id" } });
1910
+ ```
1911
+
1912
+ ---
1913
+
1914
+ <a id="op-triggerstripesync"></a>
1915
+
1916
+ ### `g8.api.quotes.triggerStripeSync(input?)`
1917
+
1918
+ **Trigger Stripe Sync**
1919
+
1920
+ - HTTP: `POST /api/v1/stripe/sync`
1921
+ - operationId: `trigger_stripe_sync_stripe_sync_post` (also callable as `g8.api.call("trigger_stripe_sync_stripe_sync_post", input)`)
1922
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
1923
+ - API-key scope: `quotes:run`
1924
+
1925
+ Sync the org's Stripe catalogue now instead of waiting for the schedule.
1926
+
1927
+ 404 when Stripe is not connected. For a large catalogue, poll
1928
+ `GET /stripe/integration-status` and watch `total_products` grow.
1929
+
1930
+ **Input**: none.
1931
+
1932
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1933
+
1934
+ Other envelope fields: `pagination` (PaginationMeta).
1935
+
1936
+ **Example**
1937
+
1938
+ ```ts
1939
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
1940
+ const result = await g8.api.quotes.triggerStripeSync();
1941
+ ```
1942
+
1943
+ ---
1944
+
1945
+ <a id="op-unarchivequote"></a>
1946
+
1947
+ ### `g8.api.quotes.unarchiveQuote(input)`
1948
+
1949
+ **Unarchive Quote**
1950
+
1951
+ - HTTP: `POST /api/v1/quotes/{quote_id}/unarchive`
1952
+ - operationId: `unarchive_quote_quotes__quote_id__unarchive_post` (also callable as `g8.api.call("unarchive_quote_quotes__quote_id__unarchive_post", input)`)
1953
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
1954
+ - API-key scope: `quotes:run`
1955
+
1956
+ Restore an archived quote to the active list.
1957
+
1958
+ A quote that is not archived comes back unchanged - unarchiving an already
1959
+ active quote is a no-op and announces nothing. Stated because the sibling
1960
+ sequence unarchive raises 403 unconditionally and had to be withdrawn from
1961
+ the contract; this one is genuinely callable.
1962
+
1963
+ **Input**
1964
+
1965
+ | Field | Type | Required | Description |
1966
+ |---|---|---|---|
1967
+ | `path.quote_id` | `string` | yes | Quote id (UUID). |
1968
+
1969
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
1970
+
1971
+ Other envelope fields: `pagination` (PaginationMeta).
1972
+
1973
+ **Example**
1974
+
1975
+ ```ts
1976
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
1977
+ const result = await g8.api.quotes.unarchiveQuote({ path: { quote_id: "id" } });
1978
+ ```
1979
+
1980
+ ---
1981
+
1982
+ <a id="op-updatemanualproduct"></a>
1983
+
1984
+ ### `g8.api.quotes.updateManualProduct(input)`
1985
+
1986
+ **Update Manual Product**
1987
+
1988
+ - HTTP: `PATCH /api/v1/manual-products/{product_id}`
1989
+ - operationId: `update_manual_product_manual_products__product_id__patch` (also callable as `g8.api.call("update_manual_product_manual_products__product_id__patch", input)`)
1990
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
1991
+ - API-key scope: `quotes:write`
1992
+
1993
+ Change some fields of a manual product. Only the fields you send change.
1994
+
1995
+ **Input**
1996
+
1997
+ | Field | Type | Required | Description |
1998
+ |---|---|---|---|
1999
+ | `path.product_id` | `string (uuid)` | yes | Manual product id. |
2000
+ | `body` | `ManualProductUpdateRequest` | yes | Request body; fields below. |
2001
+
2002
+ Body fields (`ManualProductUpdateRequest`):
2003
+
2004
+ | Field | Type | Required | Description |
2005
+ |---|---|---|---|
2006
+ | `body.active` | `boolean \| null` | no | |
2007
+ | `body.billing_frequency` | `"one_time" \| "month" \| "year" \| "quarter" \| null` | no | |
2008
+ | `body.category` | `string \| null` | no | max length 100 |
2009
+ | `body.currency` | `string \| null` | no | min length 3, max length 3 |
2010
+ | `body.default_unit_amount` | `integer \| null` | no | min 0, max 1000000000 |
2011
+ | `body.description` | `string \| null` | no | max length 5000 |
2012
+ | `body.name` | `string \| null` | no | min length 1, max length 500 |
2013
+ | `body.quotable` | `boolean \| null` | no | |
2014
+ | `body.sort_order` | `integer \| null` | no | min 0, max 10000 |
2015
+
2016
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2017
+
2018
+ Other envelope fields: `pagination` (PaginationMeta).
2019
+
2020
+ **Example**
2021
+
2022
+ ```ts
2023
+ const result = await g8.api.quotes.updateManualProduct({
2024
+ path: { product_id: "00000000-0000-0000-0000-000000000000" },
2025
+ body: {},
2026
+ });
2027
+ ```
2028
+
2029
+ ---
2030
+
2031
+ <a id="op-updatequotepatch"></a>
2032
+
2033
+ ### `g8.api.quotes.updateQuotePatch(input)`
2034
+
2035
+ **Update Quote**
2036
+
2037
+ - HTTP: `PATCH /api/v1/quotes/{quote_id}`
2038
+ - operationId: `update_quote_quotes__quote_id__patch` (also callable as `g8.api.call("update_quote_quotes__quote_id__patch", input)`)
2039
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
2040
+ - API-key scope: `quotes:run`
2041
+
2042
+ Update a quote in place (``PUT`` or ``PATCH`` — both accepted).
2043
+
2044
+ All fields are optional; only the ones you send change. Draft quotes edit
2045
+ directly. A ``sent`` / ``viewed`` quote is recalled to draft first (voiding
2046
+ its live signing link) while keeping the same row + quote number; terminal
2047
+ quotes (accepted/declined/voided/expired) reject the update.
2048
+
2049
+ ``owner_id`` reassigns the quote's AE (a blank value is ignored — it never
2050
+ nulls an existing owner). ``billing_legal_name`` / ``billing_email`` /
2051
+ ``billing_primary_email`` / ``billing_address`` set the customer's billing
2052
+ identity. Passing ``line_items`` replaces the entire line-item set (and
2053
+ re-runs quotable-product authorization). Totals recalculate automatically.
2054
+
2055
+ **Input**
2056
+
2057
+ | Field | Type | Required | Description |
2058
+ |---|---|---|---|
2059
+ | `path.quote_id` | `string` | yes | Quote UUID |
2060
+ | `body` | `QuoteUpdateRequest` | yes | Request body; fields below. |
2061
+
2062
+ Body fields (`QuoteUpdateRequest`):
2063
+
2064
+ | Field | Type | Required | Description |
2065
+ |---|---|---|---|
2066
+ | `body.accepted_payment_methods` | `Array<"ach" \| "credit_card" \| "wire"> \| null` | no | |
2067
+ | `body.billing_address` | `string \| null` | no | max length 2000 |
2068
+ | `body.billing_contact_id` | `integer \| null` | no | |
2069
+ | `body.billing_email` | `string \| null` | no | max length 255 |
2070
+ | `body.billing_legal_name` | `string \| null` | no | max length 255 |
2071
+ | `body.billing_primary_email` | `string \| null` | no | max length 255 |
2072
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
2073
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
2074
+ | `body.contract_end_date` | `string \| null` | no | |
2075
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
2076
+ | `body.contract_start_date` | `string \| null` | no | |
2077
+ | `body.currency` | `string \| null` | no | min length 3, max length 3 |
2078
+ | `body.deal_id` | `string \| null` | no | |
2079
+ | `body.line_items` | `Array<QuoteLineItemRequest> \| null` | no | min items 1 |
2080
+ | `body.marketing_rights` | `Array<"logo" \| "quote" \| "case_study"> \| null` | no | |
2081
+ | `body.mashup_company_id` | `integer \| null` | no | |
2082
+ | `body.notes` | `string \| null` | no | max length 10000 |
2083
+ | `body.owner_id` | `string \| null` | no | max length 255 |
2084
+ | `body.payment_terms` | `"due_on_receipt" \| "net_15" \| "net_30" \| "net_45" \| "net_60" \| "net_90" \| null` | no | |
2085
+ | `body.privacy_content` | `string \| null` | no | max length 50000 |
2086
+ | `body.public_notes` | `string \| null` | no | max length 50000 |
2087
+ | `body.signer_contact_id` | `integer \| null` | no | |
2088
+ | `body.signer_email` | `string \| null` | no | max length 255 |
2089
+ | `body.signer_name` | `string \| null` | no | max length 255 |
2090
+ | `body.tax_amount` | `integer \| null` | no | min 0, max 1000000000 |
2091
+ | `body.terms_content` | `string \| null` | no | max length 50000 |
2092
+ | `body.title` | `string \| null` | no | min length 1, max length 500 |
2093
+ | `body.valid_until` | `string \| null` | no | |
2094
+
2095
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2096
+
2097
+ Other envelope fields: `pagination` (PaginationMeta).
2098
+
2099
+ `QuoteDetail` fields:
2100
+
2101
+ | Field | Type | Required | Description |
2102
+ |---|---|---|---|
2103
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
2104
+ | `envelope` | `Record<string, unknown> \| null` | no | |
2105
+ | `id` | `string \| null` | no | |
2106
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
2107
+ | `quote_number` | `string \| null` | no | |
2108
+ | `status` | `string \| null` | no | |
2109
+ | `title` | `string \| null` | no | |
2110
+
2111
+ **Example**
2112
+
2113
+ ```ts
2114
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
2115
+ const result = await g8.api.quotes.updateQuotePatch({ path: { quote_id: "id" }, body: {} });
2116
+ ```
2117
+
2118
+ ---
2119
+
2120
+ <a id="op-updatequoteput"></a>
2121
+
2122
+ ### `g8.api.quotes.updateQuotePut(input)`
2123
+
2124
+ **Update Quote**
2125
+
2126
+ - HTTP: `PUT /api/v1/quotes/{quote_id}`
2127
+ - operationId: `update_quote_quotes__quote_id__put` (also callable as `g8.api.call("update_quote_quotes__quote_id__put", input)`)
2128
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
2129
+ - API-key scope: `quotes:run`
2130
+ - ★ Hand-written: [`g8.quotes.update()`](../sdk-clients.md#g8-quotes-update)
2131
+
2132
+ Update a quote in place (``PUT`` or ``PATCH`` — both accepted).
2133
+
2134
+ All fields are optional; only the ones you send change. Draft quotes edit
2135
+ directly. A ``sent`` / ``viewed`` quote is recalled to draft first (voiding
2136
+ its live signing link) while keeping the same row + quote number; terminal
2137
+ quotes (accepted/declined/voided/expired) reject the update.
2138
+
2139
+ ``owner_id`` reassigns the quote's AE (a blank value is ignored — it never
2140
+ nulls an existing owner). ``billing_legal_name`` / ``billing_email`` /
2141
+ ``billing_primary_email`` / ``billing_address`` set the customer's billing
2142
+ identity. Passing ``line_items`` replaces the entire line-item set (and
2143
+ re-runs quotable-product authorization). Totals recalculate automatically.
2144
+
2145
+ **Input**
2146
+
2147
+ | Field | Type | Required | Description |
2148
+ |---|---|---|---|
2149
+ | `path.quote_id` | `string` | yes | Quote UUID |
2150
+ | `body` | `QuoteUpdateRequest` | yes | Request body; fields below. |
2151
+
2152
+ Body fields (`QuoteUpdateRequest`):
2153
+
2154
+ | Field | Type | Required | Description |
2155
+ |---|---|---|---|
2156
+ | `body.accepted_payment_methods` | `Array<"ach" \| "credit_card" \| "wire"> \| null` | no | |
2157
+ | `body.billing_address` | `string \| null` | no | max length 2000 |
2158
+ | `body.billing_contact_id` | `integer \| null` | no | |
2159
+ | `body.billing_email` | `string \| null` | no | max length 255 |
2160
+ | `body.billing_legal_name` | `string \| null` | no | max length 255 |
2161
+ | `body.billing_primary_email` | `string \| null` | no | max length 255 |
2162
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
2163
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
2164
+ | `body.contract_end_date` | `string \| null` | no | |
2165
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
2166
+ | `body.contract_start_date` | `string \| null` | no | |
2167
+ | `body.currency` | `string \| null` | no | min length 3, max length 3 |
2168
+ | `body.deal_id` | `string \| null` | no | |
2169
+ | `body.line_items` | `Array<QuoteLineItemRequest> \| null` | no | min items 1 |
2170
+ | `body.marketing_rights` | `Array<"logo" \| "quote" \| "case_study"> \| null` | no | |
2171
+ | `body.mashup_company_id` | `integer \| null` | no | |
2172
+ | `body.notes` | `string \| null` | no | max length 10000 |
2173
+ | `body.owner_id` | `string \| null` | no | max length 255 |
2174
+ | `body.payment_terms` | `"due_on_receipt" \| "net_15" \| "net_30" \| "net_45" \| "net_60" \| "net_90" \| null` | no | |
2175
+ | `body.privacy_content` | `string \| null` | no | max length 50000 |
2176
+ | `body.public_notes` | `string \| null` | no | max length 50000 |
2177
+ | `body.signer_contact_id` | `integer \| null` | no | |
2178
+ | `body.signer_email` | `string \| null` | no | max length 255 |
2179
+ | `body.signer_name` | `string \| null` | no | max length 255 |
2180
+ | `body.tax_amount` | `integer \| null` | no | min 0, max 1000000000 |
2181
+ | `body.terms_content` | `string \| null` | no | max length 50000 |
2182
+ | `body.title` | `string \| null` | no | min length 1, max length 500 |
2183
+ | `body.valid_until` | `string \| null` | no | |
2184
+
2185
+ **Returns** `ApiResponse_QuoteDetail_`: the envelope `{ data: QuoteDetail, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2186
+
2187
+ Other envelope fields: `pagination` (PaginationMeta).
2188
+
2189
+ `QuoteDetail` fields:
2190
+
2191
+ | Field | Type | Required | Description |
2192
+ |---|---|---|---|
2193
+ | `activity` | `Array<Record<string, unknown>> \| null` | no | |
2194
+ | `envelope` | `Record<string, unknown> \| null` | no | |
2195
+ | `id` | `string \| null` | no | |
2196
+ | `line_items` | `Array<Record<string, unknown>> \| null` | no | |
2197
+ | `quote_number` | `string \| null` | no | |
2198
+ | `status` | `string \| null` | no | |
2199
+ | `title` | `string \| null` | no | |
2200
+
2201
+ **Example**
2202
+
2203
+ ```ts
2204
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
2205
+ const result = await g8.api.quotes.updateQuotePut({ path: { quote_id: "id" }, body: {} });
2206
+ ```
2207
+
2208
+ ---
2209
+
2210
+ <a id="op-updatequotesettings"></a>
2211
+
2212
+ ### `g8.api.quotes.updateQuoteSettings(input)`
2213
+
2214
+ **Update Quote Settings**
2215
+
2216
+ - HTTP: `PUT /api/v1/quote-settings`
2217
+ - operationId: `update_quote_settings_quote_settings_put` (also callable as `g8.api.call("update_quote_settings_quote_settings_put", input)`)
2218
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
2219
+ - API-key scope: `quotes:run`
2220
+
2221
+ Org-wide quote branding, terms and sender identity. ORG ADMIN.
2222
+
2223
+ `GET /quote-settings` was already published; this is its write half. Admin
2224
+ because `sender_email` decides whose name every quote goes out under.
2225
+
2226
+ **Input**
2227
+
2228
+ | Field | Type | Required | Description |
2229
+ |---|---|---|---|
2230
+ | `body` | `QuoteSettingsUpdateRequest` | yes | Request body; fields below. |
2231
+
2232
+ Body fields (`QuoteSettingsUpdateRequest`):
2233
+
2234
+ | Field | Type | Required | Description |
2235
+ |---|---|---|---|
2236
+ | `body.accent_color` | `string \| null` | no | |
2237
+ | `body.auto_advance_deal_on_quote_send` | `boolean \| null` | no | |
2238
+ | `body.auto_close_deal_on_acceptance` | `boolean \| null` | no | Close the linked DEAL when a quote is accepted. Org-wide, and it changes what every future acceptance does to the pipeline. |
2239
+ | `body.company_address` | `string \| null` | no | |
2240
+ | `body.company_email` | `string \| null` | no | |
2241
+ | `body.company_logo_url` | `string \| null` | no | |
2242
+ | `body.company_name` | `string \| null` | no | |
2243
+ | `body.company_phone` | `string \| null` | no | |
2244
+ | `body.default_billing_provider` | `string \| null` | no | |
2245
+ | `body.default_payment_terms` | `string \| null` | no | |
2246
+ | `body.default_privacy` | `string \| null` | no | |
2247
+ | `body.default_terms` | `string \| null` | no | |
2248
+ | `body.default_valid_days` | `integer \| null` | no | |
2249
+ | `body.footer_text` | `string \| null` | no | |
2250
+ | `body.privacy_url` | `string \| null` | no | |
2251
+ | `body.quote_acceptance_roam_channel_id` | `string \| null` | no | |
2252
+ | `body.quote_acceptance_roam_channel_name` | `string \| null` | no | |
2253
+ | `body.quote_acceptance_roam_notifications_enabled` | `boolean \| null` | no | |
2254
+ | `body.quote_number_prefix` | `string \| null` | no | |
2255
+ | `body.required_billing_fields` | `Array<string> \| null` | no | |
2256
+ | `body.sender_email` | `string \| null` | no | Whose name every quote goes out under. Admin-only for that reason. |
2257
+ | `body.sender_mode` | `string \| null` | no | `fixed` to always use `sender_email`, or `creator`. |
2258
+ | `body.sender_name` | `string \| null` | no | |
2259
+ | `body.terms_library` | `Array<Record<string, unknown>> \| null` | no | |
2260
+ | `body.terms_url` | `string \| null` | no | |
2261
+
2262
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2263
+
2264
+ Other envelope fields: `pagination` (PaginationMeta).
2265
+
2266
+ **Example**
2267
+
2268
+ ```ts
2269
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
2270
+ const result = await g8.api.quotes.updateQuoteSettings({ body: {} });
2271
+ ```
2272
+
2273
+ ---
2274
+
2275
+ <a id="op-updatequotetemplate"></a>
2276
+
2277
+ ### `g8.api.quotes.updateQuoteTemplate(input)`
2278
+
2279
+ **Update Quote Template**
2280
+
2281
+ - HTTP: `PUT /api/v1/quote-templates/{template_id}`
2282
+ - operationId: `update_quote_template_quote_templates__template_id__put` (also callable as `g8.api.call("update_quote_template_quote_templates__template_id__put", input)`)
2283
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
2284
+ - API-key scope: `quotes:run`
2285
+
2286
+ Replace a template. ORG ADMIN.
2287
+
2288
+ A PUT, matching the app: the body is the template's new state, not a patch,
2289
+ so an omitted field is CLEARED rather than left alone.
2290
+
2291
+ **Input**
2292
+
2293
+ | Field | Type | Required | Description |
2294
+ |---|---|---|---|
2295
+ | `path.template_id` | `string` | yes | Template id. |
2296
+ | `body` | `QuoteTemplateRequest` | yes | Request body; fields below. |
2297
+
2298
+ Body fields (`QuoteTemplateRequest`):
2299
+
2300
+ | Field | Type | Required | Description |
2301
+ |---|---|---|---|
2302
+ | `body.name` | `string` | yes | min length 1, max length 255 |
2303
+ | `body.contract_duration_unit` | `"months" \| "weeks" \| "days" \| null` | no | |
2304
+ | `body.contract_duration_value` | `number \| null` | no | min 0.1, max 3650 |
2305
+ | `body.contract_months` | `number \| null` | no | min 0.1, max 120 |
2306
+ | `body.default_line_items` | `Array<Record<string, unknown>> \| null` | no | |
2307
+ | `body.default_payment_terms` | `string \| null` | no | |
2308
+ | `body.default_valid_days` | `integer \| null` | no | min 1, max 365 |
2309
+ | `body.description` | `string \| null` | no | |
2310
+ | `body.document_ids` | `Array<string> \| null` | no | Legal documents to attach to every quote built from this template. Ids come from `GET /quote-settings/documents`. |
2311
+ | `body.is_default` | `boolean` | no | default `false` |
2312
+ | `body.terms_override` | `string \| null` | no | |
2313
+
2314
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2315
+
2316
+ Other envelope fields: `pagination` (PaginationMeta).
2317
+
2318
+ **Example**
2319
+
2320
+ ```ts
2321
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
2322
+ const result = await g8.api.quotes.updateQuoteTemplate({ path: { template_id: "id" }, body: { name: "Example" } });
2323
+ ```
2324
+
2325
+ ---
2326
+
2327
+ <a id="op-updatestripecustomermapping"></a>
2328
+
2329
+ ### `g8.api.quotes.updateStripeCustomerMapping(input)`
2330
+
2331
+ **Update Stripe Customer Mapping**
2332
+
2333
+ - HTTP: `PATCH /api/v1/stripe/customers/{customer_id}/mapping`
2334
+ - operationId: `update_stripe_customer_mapping_stripe_customers__customer_id__mapping_patch` (also callable as `g8.api.call("update_stripe_customer_mapping_stripe_customers__customer_id__mapping_patch", input)`)
2335
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2336
+ - API-key scope: `quotes:write`
2337
+
2338
+ Map a Stripe customer to a graph8 company by hand, or unmap it with null.
2339
+
2340
+ A manual mapping is recorded as such, so the automatic matcher leaves it alone.
2341
+
2342
+ **Input**
2343
+
2344
+ | Field | Type | Required | Description |
2345
+ |---|---|---|---|
2346
+ | `path.customer_id` | `integer` | yes | The synced customer row id (not the `cus_` id). |
2347
+ | `body` | `CustomerMappingRequest` | yes | Request body; fields below. |
2348
+
2349
+ Body fields (`CustomerMappingRequest`):
2350
+
2351
+ | Field | Type | Required | Description |
2352
+ |---|---|---|---|
2353
+ | `body.mashup_company_id` | `integer \| null` | yes | graph8 company id. Null removes the mapping. |
2354
+
2355
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2356
+
2357
+ Other envelope fields: `pagination` (PaginationMeta).
2358
+
2359
+ **Example**
2360
+
2361
+ ```ts
2362
+ const result = await g8.api.quotes.updateStripeCustomerMapping({ path: { customer_id: 123 }, body: { mashup_company_id: 123 } });
2363
+ ```
2364
+
2365
+ ---
2366
+
2367
+ <a id="op-uploadquotedocument"></a>
2368
+
2369
+ ### `g8.api.quotes.uploadQuoteDocument(input?)`
2370
+
2371
+ **Upload Quote Document**
2372
+
2373
+ - HTTP: `POST /api/v1/quote-settings/documents`
2374
+ - operationId: `upload_quote_document_quote_settings_documents_post` (also callable as `g8.api.call("upload_quote_document_quote_settings_documents_post", input)`)
2375
+ - Tier: `external`: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first
2376
+ - API-key scope: `quotes:run`
2377
+
2378
+ Upload a legal document to the org's library. ORG ADMIN.
2379
+
2380
+ Multipart, like the app. The PDF-only and 10 MB rules are the app's and are
2381
+ enforced there; they are documented here so a caller sees them before
2382
+ spending the upload.
2383
+
2384
+ **Input**: none.
2385
+
2386
+ **Returns** `ApiResponse_QuotePayload_`: the envelope `{ data: QuotePayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2387
+
2388
+ Other envelope fields: `pagination` (PaginationMeta).
2389
+
2390
+ **Example**
2391
+
2392
+ ```ts
2393
+ // external: reaches real people (sends email/SMS, places a call, launches a send); the SDK never blindly retries it; confirm with a human first.
2394
+ const result = await g8.api.quotes.uploadQuoteDocument();
2395
+ ```
2396
+
2397
+ ---
2398
+
2399
+ <a id="op-uploadquoteevidence"></a>
2400
+
2401
+ ### `g8.api.quotes.uploadQuoteEvidence(input)`
2402
+
2403
+ **Upload Quote Evidence**
2404
+
2405
+ - HTTP: `POST /api/v1/quotes/{quote_id}/evidence`
2406
+ - operationId: `upload_quote_evidence_quotes__quote_id__evidence_post` (also callable as `g8.api.call("upload_quote_evidence_quotes__quote_id__evidence_post", input)`)
2407
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2408
+ - API-key scope: `quotes:write`
2409
+
2410
+ Attach an internal PDF to a quote - for example a copy signed outside
2411
+ graph8. Internal: it never enters the template or signing pipeline.
2412
+
2413
+ Needs WRITE access to the quote. 400 for anything that is not a complete
2414
+ PDF, 413 above 10 MB.
2415
+
2416
+ **Input**
2417
+
2418
+ | Field | Type | Required | Description |
2419
+ |---|---|---|---|
2420
+ | `path.quote_id` | `string (uuid)` | yes | Quote id. |
2421
+
2422
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2423
+
2424
+ Other envelope fields: `pagination` (PaginationMeta).
2425
+
2426
+ **Example**
2427
+
2428
+ ```ts
2429
+ const result = await g8.api.quotes.uploadQuoteEvidence({ path: { quote_id: "00000000-0000-0000-0000-000000000000" } });
2430
+ ```
2431
+
2432
+ ---
2433
+
2434
+ <a id="op-upsertstripeproductsettings"></a>
2435
+
2436
+ ### `g8.api.quotes.upsertStripeProductSettings(input)`
2437
+
2438
+ **Upsert Stripe Product Settings**
2439
+
2440
+ - HTTP: `PUT /api/v1/stripe/product-settings/{stripe_product_id}`
2441
+ - operationId: `upsert_stripe_product_settings_stripe_product_settings__stripe_product_id__put` (also callable as `g8.api.call("upsert_stripe_product_settings_stripe_product_settings__stripe_product_id__put", input)`)
2442
+ - Tier: `write`: creates or changes records; the SDK sends an Idempotency-Key and retries transient failures
2443
+ - API-key scope: `quotes:write`
2444
+
2445
+ Set one product's quote-builder settings. Omitted fields are left
2446
+ unchanged. Org Admin or Owner key only.
2447
+
2448
+ **Input**
2449
+
2450
+ | Field | Type | Required | Description |
2451
+ |---|---|---|---|
2452
+ | `path.stripe_product_id` | `string` | yes | Stripe product id. |
2453
+ | `body` | `ProductSettingsUpdateRequest` | yes | Request body; fields below. |
2454
+
2455
+ Body fields (`ProductSettingsUpdateRequest`):
2456
+
2457
+ | Field | Type | Required | Description |
2458
+ |---|---|---|---|
2459
+ | `body.category` | `string \| null` | no | |
2460
+ | `body.friendly_description` | `string \| null` | no | |
2461
+ | `body.friendly_name` | `string \| null` | no | |
2462
+ | `body.quotable` | `boolean \| null` | no | |
2463
+ | `body.sort_order` | `integer \| null` | no | |
2464
+
2465
+ **Returns** `ApiResponse_BillingPayload_`: the envelope `{ data: BillingPayload, ... }`. `g8.api` returns the envelope as-is, so read `result.data`.
2466
+
2467
+ Other envelope fields: `pagination` (PaginationMeta).
2468
+
2469
+ **Example**
2470
+
2471
+ ```ts
2472
+ const result = await g8.api.quotes.upsertStripeProductSettings({ path: { stripe_product_id: "id" }, body: {} });
2473
+ ```
2474
+
2475
+ ---
2476
+
2477
+ ## Referenced types
2478
+
2479
+ Named types that appear in the tables above. Full TypeScript definitions: `G8Contract.<Name>` (`import type { G8Contract } from "@graph8/sdk"`).
2480
+
2481
+ <a id="type-quotelineitem"></a>
2482
+
2483
+ ### `QuoteLineItem`
2484
+
2485
+ One priced line, mirroring the app's `LineItemDTO`. The two REQUIRED fields are required here too, and that is the point: the app model is built inside the handler, so a missing `product_name` or `unit_amount` would raise a bare `pydantic.ValidationError` there - not the `RequestValidationError` `error_handlers.py` registers - and escape as a 500 instead of a 422. `unit_amount` is in CENTS, like the app. An API that took dollars here while the app took cents would be wrong by a factor of a hundred on every quote, silently. CLOSED (`extra="forbid"`), which makes this stricter than the app on p…
2486
+
2487
+ | Field | Type | Required | Description |
2488
+ |---|---|---|---|
2489
+ | `product_name` | `string` | yes | min length 1, max length 255 |
2490
+ | `unit_amount` | `integer` | yes | CENTS, not dollars. min 0, max 1000000000 |
2491
+ | `billing_frequency` | `string \| null` | no | |
2492
+ | `billing_start_date` | `string \| null` | no | |
2493
+ | `description` | `string \| null` | no | max length 2000 |
2494
+ | `discount_pct` | `number` | no | default `0`, min 0, max 100 |
2495
+ | `manual_product_id` | `string \| null` | no | |
2496
+ | `quantity` | `integer` | no | default `1`, min 1, max 10000 |
2497
+ | `sort_order` | `integer` | no | default `0` |
2498
+ | `start_month` | `integer` | no | default `1`, min 1, max 120 |
2499
+ | `stripe_price_id` | `string \| null` | no | |
2500
+ | `stripe_product_id` | `string \| null` | no | |
2501
+
2502
+ <a id="type-quotelineitemrequest"></a>
2503
+
2504
+ ### `QuoteLineItemRequest`
2505
+
2506
+ One line item on a quote request body. Shape mirrors ``integrations_v4.interfaces.fastapi.quote_router.LineItemDTO`` exactly. Pass either ``stripe_product_id`` + ``stripe_price_id`` (for a Stripe-catalogue product) or ``manual_product_id`` (for an org-owned manual catalogue entry), or neither (for a custom one-off line). Authorization is enforced server-side — non-quotable products are rejected with 400.
2507
+
2508
+ | Field | Type | Required | Description |
2509
+ |---|---|---|---|
2510
+ | `product_name` | `string` | yes | min length 1, max length 255 |
2511
+ | `unit_amount` | `integer` | yes | In cents min 0, max 1000000000 |
2512
+ | `billing_frequency` | `"one_time" \| "month" \| "year" \| "quarter" \| null` | no | |
2513
+ | `billing_start_date` | `string (date) \| null` | no | Exact recurring billing start date within the contract; start_month must remain 1 when supplied. |
2514
+ | `description` | `string \| null` | no | max length 2000 |
2515
+ | `discount_pct` | `number` | no | default `0`, min 0, max 100 |
2516
+ | `manual_product_id` | `string \| null` | no | |
2517
+ | `quantity` | `integer` | no | default `1`, min 1, max 10000 |
2518
+ | `sort_order` | `integer` | no | default `0` |
2519
+ | `start_month` | `integer` | no | Contract month when recurring billing begins; 1 means at contract start. Use billing_start_date instead for an exact date. default `1`, min 1, max 120 |
2520
+ | `stripe_price_id` | `string \| null` | no | |
2521
+ | `stripe_product_id` | `string \| null` | no | |
2522
+
2523
+ <a id="type-quotesendrecipient"></a>
2524
+
2525
+ ### `QuoteSendRecipient`
2526
+
2527
+ One recipient of a quote preview.
2528
+
2529
+ | Field | Type | Required | Description |
2530
+ |---|---|---|---|
2531
+ | `email` | `string` | yes | max length 255 |
2532
+ | `email_body` | `string \| null` | no | max length 10000 |
2533
+ | `name` | `string \| null` | no | max length 255 |
2534
+ | `role` | `"signer" \| "viewer"` | no | default `"signer"` |
2535
+ | `subject` | `string \| null` | no | max length 500 |
2536
+
2537
+ <a id="type-quotesummary"></a>
2538
+
2539
+ ### `QuoteSummary`
2540
+
2541
+ List-view row from ``GET /quotes``. ``extra="allow"`` keeps every backend column flowing through without us re-declaring CBQuote.
2542
+
2543
+ | Field | Type | Required | Description |
2544
+ |---|---|---|---|
2545
+ | `accepted_at` | `string \| null` | no | |
2546
+ | `created_at` | `string \| null` | no | |
2547
+ | `currency` | `string \| null` | no | |
2548
+ | `id` | `string \| null` | no | |
2549
+ | `quote_number` | `string \| null` | no | |
2550
+ | `sent_at` | `string \| null` | no | |
2551
+ | `status` | `string \| null` | no | |
2552
+ | `title` | `string \| null` | no | |
2553
+ | `total` | `integer \| null` | no | |