Skip to main content

ghl_models/v3/
opportunities.rs

1//! `opportunities` data models for GoHighLevel API V3 (26 types).
2//!
3//! Generated from HighLevel's official OpenAPI spec for the
4//! **Opportunities** module. Every endpoint that uses these types, with its
5//! parameters, required scopes and enum values, is documented in the
6//! [`opportunities` API reference](https://github.com/Shahroz/ghl-rs/blob/main/docs/api/opportunities.md).
7//!
8//! Enable with `features = ["opportunities"]`.
9// @generated by xtask/generate_models.py — do not edit by hand.
10// Source: https://github.com/GoHighLevel/highlevel-api-docs
11// Doc comments are HighLevel's own field descriptions, reflowed verbatim, so
12// they aren't held to rustdoc's markdown conventions.
13#![allow(
14    missing_docs,
15    clippy::doc_lazy_continuation,
16    clippy::doc_overindented_list_items
17)]
18
19use serde::{Deserialize, Serialize};
20
21/// `AdditionalDetailsDTO` from the GoHighLevel OpenAPI spec.
22#[derive(Debug, Clone, Default, Serialize, Deserialize)]
23pub struct AdditionalDetailsDTO {
24    /// Include notes in the response
25    /// Required by the API.
26    pub notes: bool,
27    /// Include tasks in the response
28    /// Required by the API.
29    pub tasks: bool,
30    /// Include calendar events in the response
31    /// Required by the API.
32    #[serde(rename = "calendarEvents")]
33    pub calendar_events: bool,
34    /// Include unread conversations count in the response
35    /// Required by the API.
36    #[serde(rename = "unReadConversations")]
37    pub un_read_conversations: bool,
38}
39
40/// `CreateAddFollowersSuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
41#[derive(Debug, Clone, Default, Serialize, Deserialize)]
42pub struct CreateAddFollowersSuccessfulResponseDto {
43    /// Current list of all follower user IDs after the operation
44    #[serde(default, skip_serializing_if = "Vec::is_empty")]
45    pub followers: Vec<String>,
46    /// User IDs that were successfully added as followers
47    #[serde(
48        rename = "followersAdded",
49        default,
50        skip_serializing_if = "Vec::is_empty"
51    )]
52    pub followers_added: Vec<String>,
53}
54
55/// `CreateDtoV3` from the GoHighLevel OpenAPI spec.
56#[derive(Debug, Clone, Default, Serialize, Deserialize)]
57pub struct CreateDtoV3 {
58    /// pipeline Id
59    /// Required by the API.
60    #[serde(rename = "pipelineId")]
61    pub pipeline_id: String,
62    /// Identifier of the location (sub-account)
63    /// Required by the API.
64    #[serde(rename = "locationId")]
65    pub location_id: String,
66    /// Name of the opportunity
67    /// Required by the API.
68    pub name: String,
69    /// Identifier of the pipeline stage
70    #[serde(
71        rename = "pipelineStageId",
72        default,
73        skip_serializing_if = "Option::is_none"
74    )]
75    pub pipeline_stage_id: Option<String>,
76    /// Current status of the opportunity
77    /// Allowed values: `open`, `won`, `lost`, `abandoned`, `all`.
78    /// Required by the API.
79    pub status: String,
80    /// Identifier of the contact linked to the opportunity
81    /// Required by the API.
82    #[serde(rename = "contactId")]
83    pub contact_id: String,
84    /// Monetary value of the opportunity
85    #[serde(
86        rename = "monetaryValue",
87        default,
88        skip_serializing_if = "Option::is_none"
89    )]
90    pub monetary_value: Option<f64>,
91    /// Expected close date. Supported formats: YYYY/MM/DD, MM/DD/YYYY, YYYY-MM-DD, MM-DD-YYYY,
92    /// YYYY.MM.DD, MM.DD.YYYY, or ISO 8601
93    #[serde(
94        rename = "forecastExpectedCloseDate",
95        default,
96        skip_serializing_if = "Option::is_none"
97    )]
98    pub forecast_expected_close_date: Option<String>,
99    /// Forecast probability
100    #[serde(
101        rename = "forecastProbability",
102        default,
103        skip_serializing_if = "Option::is_none"
104    )]
105    pub forecast_probability: Option<f64>,
106    /// Identifier of the user the opportunity is assigned to
107    #[serde(
108        rename = "assignedTo",
109        default,
110        skip_serializing_if = "Option::is_none"
111    )]
112    pub assigned_to: Option<String>,
113    /// Add custom fields to opportunities.
114    /// Multiple possible shapes in the spec; raw JSON.
115    #[serde(
116        rename = "customFields",
117        default,
118        skip_serializing_if = "Vec::is_empty"
119    )]
120    pub custom_fields: Vec<serde_json::Value>,
121}
122
123/// `CustomFieldResponseSchema` from the GoHighLevel OpenAPI spec.
124#[derive(Debug, Clone, Default, Serialize, Deserialize)]
125pub struct CustomFieldResponseSchema {
126    /// Unique identifier of the custom field
127    /// Required by the API.
128    /// (Optional here so responses that omit it still parse.)
129    #[serde(default, skip_serializing_if = "Option::is_none")]
130    pub id: Option<String>,
131    /// The value of the custom field
132    /// Multiple possible shapes in the spec; raw JSON.
133    /// Required by the API.
134    /// (Optional here so responses that omit it still parse.)
135    #[serde(
136        rename = "fieldValue",
137        default,
138        skip_serializing_if = "Option::is_none"
139    )]
140    pub field_value: Option<serde_json::Value>,
141}
142
143/// `DeleteFollowersSuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
144#[derive(Debug, Clone, Default, Serialize, Deserialize)]
145pub struct DeleteFollowersSuccessfulResponseDto {
146    /// Current list of all follower user IDs after the operation
147    #[serde(default, skip_serializing_if = "Vec::is_empty")]
148    pub followers: Vec<String>,
149    /// User IDs that were successfully removed as followers
150    #[serde(
151        rename = "followersRemoved",
152        default,
153        skip_serializing_if = "Vec::is_empty"
154    )]
155    pub followers_removed: Vec<String>,
156}
157
158/// `DeleteUpdateOpportunitySuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
159#[derive(Debug, Clone, Default, Serialize, Deserialize)]
160pub struct DeleteUpdateOpportunitySuccessfulResponseDto {
161    /// Indicates whether the operation was successful. Deprecated — use `success` instead.
162    #[serde(default, skip_serializing_if = "Option::is_none")]
163    pub succeded: Option<bool>,
164    /// Indicates whether the operation was successful
165    #[serde(default, skip_serializing_if = "Option::is_none")]
166    pub success: Option<bool>,
167}
168
169/// `FollowersDTO` from the GoHighLevel OpenAPI spec.
170#[derive(Debug, Clone, Default, Serialize, Deserialize)]
171pub struct FollowersDTO {
172    /// Array of user IDs to add or remove as followers (max 10)
173    /// Required by the API.
174    #[serde(default, skip_serializing_if = "Vec::is_empty")]
175    pub followers: Vec<String>,
176}
177
178/// `GetPipelinesSuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
179#[derive(Debug, Clone, Default, Serialize, Deserialize)]
180pub struct GetPipelinesSuccessfulResponseDto {
181    /// List of pipelines for the location
182    #[serde(default, skip_serializing_if = "Vec::is_empty")]
183    pub pipelines: Vec<PipelinesResponseSchema>,
184}
185
186/// `GetPostOpportunitySuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
187#[derive(Debug, Clone, Default, Serialize, Deserialize)]
188pub struct GetPostOpportunitySuccessfulResponseDto {
189    /// The created or retrieved opportunity object
190    #[serde(default, skip_serializing_if = "Option::is_none")]
191    pub opportunity: Option<SearchOpportunitiesResponseSchema>,
192}
193
194/// `LostReasonResponseSchema` from the GoHighLevel OpenAPI spec.
195#[derive(Debug, Clone, Default, Serialize, Deserialize)]
196pub struct LostReasonResponseSchema {
197    /// lost reason id
198    #[serde(default, skip_serializing_if = "Option::is_none")]
199    pub id: Option<String>,
200    /// lost reason name
201    #[serde(default, skip_serializing_if = "Option::is_none")]
202    pub name: Option<String>,
203    /// location id
204    #[serde(
205        rename = "locationId",
206        default,
207        skip_serializing_if = "Option::is_none"
208    )]
209    pub location_id: Option<String>,
210    /// updated at
211    /// Format: date-time (ISO-8601 string).
212    #[serde(rename = "updatedAt", default, skip_serializing_if = "Option::is_none")]
213    pub updated_at: Option<String>,
214    /// created at
215    /// Format: date-time (ISO-8601 string).
216    #[serde(rename = "createdAt", default, skip_serializing_if = "Option::is_none")]
217    pub created_at: Option<String>,
218}
219
220/// `LostReasonsResponseSchema` from the GoHighLevel OpenAPI spec.
221#[derive(Debug, Clone, Default, Serialize, Deserialize)]
222pub struct LostReasonsResponseSchema {
223    /// List of lost reasons for the location
224    #[serde(rename = "lostReasons", default, skip_serializing_if = "Vec::is_empty")]
225    pub lost_reasons: Vec<LostReasonResponseSchema>,
226    /// Total number of lost reasons matching the query
227    #[serde(default, skip_serializing_if = "Option::is_none")]
228    pub total: Option<f64>,
229}
230
231/// `OpportunitySearchBodyDTO` from the GoHighLevel OpenAPI spec.
232#[derive(Debug, Clone, Default, Serialize, Deserialize)]
233pub struct OpportunitySearchBodyDTO {
234    /// Location Id
235    /// Required by the API.
236    #[serde(rename = "locationId")]
237    pub location_id: String,
238    /// Full-text search query string (max 75 characters)
239    /// Required by the API.
240    pub query: String,
241    /// Maximum number of results to return per page
242    /// Required by the API.
243    pub limit: f64,
244    /// Page number (0-indexed)
245    /// Required by the API.
246    pub page: f64,
247    /// Search-after cursor values for deep pagination
248    /// Required by the API.
249    #[serde(rename = "searchAfter", default, skip_serializing_if = "Vec::is_empty")]
250    pub search_after: Vec<String>,
251    /// Flags to include additional related entities in the response
252    /// Required by the API.
253    #[serde(rename = "additionalDetails")]
254    pub additional_details: AdditionalDetailsDTO,
255}
256
257/// `PipelinesResponseSchema` from the GoHighLevel OpenAPI spec.
258#[derive(Debug, Clone, Default, Serialize, Deserialize)]
259pub struct PipelinesResponseSchema {
260    /// Unique identifier of the pipeline
261    #[serde(default, skip_serializing_if = "Option::is_none")]
262    pub id: Option<String>,
263    /// Name of the pipeline
264    #[serde(default, skip_serializing_if = "Option::is_none")]
265    pub name: Option<String>,
266    /// Stages belonging to this pipeline
267    #[serde(default, skip_serializing_if = "Vec::is_empty")]
268    pub stages: Vec<Vec<serde_json::Value>>,
269    /// Whether the pipeline is shown in the funnel view
270    #[serde(
271        rename = "showInFunnel",
272        default,
273        skip_serializing_if = "Option::is_none"
274    )]
275    pub show_in_funnel: Option<bool>,
276    /// Whether the pipeline is shown in the pie chart view
277    #[serde(
278        rename = "showInPieChart",
279        default,
280        skip_serializing_if = "Option::is_none"
281    )]
282    pub show_in_pie_chart: Option<bool>,
283    /// Identifier of the location (sub-account) this pipeline belongs to
284    #[serde(
285        rename = "locationId",
286        default,
287        skip_serializing_if = "Option::is_none"
288    )]
289    pub location_id: Option<String>,
290    /// Whether stage-level win probability is enabled for this pipeline
291    #[serde(
292        rename = "useOpportunityProbability",
293        default,
294        skip_serializing_if = "Option::is_none"
295    )]
296    pub use_opportunity_probability: Option<bool>,
297    /// How pipeline/stage colors are rendered
298    /// Allowed values: `dot`, `bg-tint`, `none`.
299    #[serde(
300        rename = "colorRenderMode",
301        default,
302        skip_serializing_if = "Option::is_none"
303    )]
304    pub color_render_mode: Option<String>,
305}
306
307/// `PostSearchSuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
308#[derive(Debug, Clone, Default, Serialize, Deserialize)]
309pub struct PostSearchSuccessfulResponseDto {
310    /// List of opportunities matching the search criteria
311    #[serde(default, skip_serializing_if = "Vec::is_empty")]
312    pub opportunities: Vec<SearchOpportunitiesResponseSchema>,
313    /// Total number of opportunities matching the query
314    /// Required by the API.
315    /// (Optional here so responses that omit it still parse.)
316    #[serde(default, skip_serializing_if = "Option::is_none")]
317    pub total: Option<f64>,
318    /// Per-stage totals when pipeline filter is present
319    #[serde(
320        rename = "stageAggregations",
321        default,
322        skip_serializing_if = "Vec::is_empty"
323    )]
324    pub stage_aggregations: Vec<StageAggregationResponseDto>,
325    /// Aggregation results keyed by aggregation name
326    #[serde(default, skip_serializing_if = "Option::is_none")]
327    pub aggregations: Option<serde_json::Value>,
328}
329
330/// `SearchMetaResponseSchema` from the GoHighLevel OpenAPI spec.
331#[derive(Debug, Clone, Default, Serialize, Deserialize)]
332pub struct SearchMetaResponseSchema {
333    /// Total number of opportunities matching the query
334    #[serde(default, skip_serializing_if = "Option::is_none")]
335    pub total: Option<f64>,
336    /// URL to retrieve the next page of results
337    #[serde(
338        rename = "nextPageUrl",
339        default,
340        skip_serializing_if = "Option::is_none"
341    )]
342    pub next_page_url: Option<String>,
343    /// Cursor id to use for pagination (startAfterId param)
344    #[serde(
345        rename = "startAfterId",
346        default,
347        skip_serializing_if = "Option::is_none"
348    )]
349    pub start_after_id: Option<String>,
350    /// Cursor timestamp to use for pagination (startAfter param)
351    #[serde(
352        rename = "startAfter",
353        default,
354        skip_serializing_if = "Option::is_none"
355    )]
356    pub start_after: Option<f64>,
357    /// Current page number
358    #[serde(
359        rename = "currentPage",
360        default,
361        skip_serializing_if = "Option::is_none"
362    )]
363    pub current_page: Option<f64>,
364    /// Next page number
365    #[serde(rename = "nextPage", default, skip_serializing_if = "Option::is_none")]
366    pub next_page: Option<f64>,
367    /// Previous page number
368    #[serde(rename = "prevPage", default, skip_serializing_if = "Option::is_none")]
369    pub prev_page: Option<f64>,
370}
371
372/// `SearchOpportunitiesContactResponseSchema` from the GoHighLevel OpenAPI spec.
373#[derive(Debug, Clone, Default, Serialize, Deserialize)]
374pub struct SearchOpportunitiesContactResponseSchema {
375    /// Unique identifier of the contact
376    #[serde(default, skip_serializing_if = "Option::is_none")]
377    pub id: Option<String>,
378    /// Full name of the contact
379    #[serde(default, skip_serializing_if = "Option::is_none")]
380    pub name: Option<String>,
381    /// Company name associated with the contact
382    #[serde(
383        rename = "companyName",
384        default,
385        skip_serializing_if = "Option::is_none"
386    )]
387    pub company_name: Option<String>,
388    /// Email address of the contact
389    #[serde(default, skip_serializing_if = "Option::is_none")]
390    pub email: Option<String>,
391    /// Phone number of the contact
392    #[serde(default, skip_serializing_if = "Option::is_none")]
393    pub phone: Option<String>,
394    /// Tags associated with the contact
395    #[serde(default, skip_serializing_if = "Vec::is_empty")]
396    pub tags: Vec<String>,
397}
398
399/// `SearchOpportunitiesResponseSchema` from the GoHighLevel OpenAPI spec.
400#[derive(Debug, Clone, Default, Serialize, Deserialize)]
401pub struct SearchOpportunitiesResponseSchema {
402    /// Unique identifier of the opportunity
403    #[serde(default, skip_serializing_if = "Option::is_none")]
404    pub id: Option<String>,
405    /// Name of the opportunity
406    #[serde(default, skip_serializing_if = "Option::is_none")]
407    pub name: Option<String>,
408    /// Monetary value of the opportunity
409    #[serde(
410        rename = "monetaryValue",
411        default,
412        skip_serializing_if = "Option::is_none"
413    )]
414    pub monetary_value: Option<f64>,
415    /// Identifier of the pipeline the opportunity belongs to
416    #[serde(
417        rename = "pipelineId",
418        default,
419        skip_serializing_if = "Option::is_none"
420    )]
421    pub pipeline_id: Option<String>,
422    /// Identifier of the pipeline stage the opportunity is in
423    #[serde(
424        rename = "pipelineStageId",
425        default,
426        skip_serializing_if = "Option::is_none"
427    )]
428    pub pipeline_stage_id: Option<String>,
429    /// Identifier of the user the opportunity is assigned to
430    #[serde(
431        rename = "assignedTo",
432        default,
433        skip_serializing_if = "Option::is_none"
434    )]
435    pub assigned_to: Option<String>,
436    /// Current status of the opportunity
437    #[serde(default, skip_serializing_if = "Option::is_none")]
438    pub status: Option<String>,
439    /// Source of the opportunity
440    #[serde(default, skip_serializing_if = "Option::is_none")]
441    pub source: Option<String>,
442    /// ISO 8601 timestamp of the last status change
443    #[serde(
444        rename = "lastStatusChangeAt",
445        default,
446        skip_serializing_if = "Option::is_none"
447    )]
448    pub last_status_change_at: Option<String>,
449    /// ISO 8601 timestamp of the last stage change
450    #[serde(
451        rename = "lastStageChangeAt",
452        default,
453        skip_serializing_if = "Option::is_none"
454    )]
455    pub last_stage_change_at: Option<String>,
456    /// ISO 8601 timestamp of the last action on the opportunity
457    #[serde(
458        rename = "lastActionDate",
459        default,
460        skip_serializing_if = "Option::is_none"
461    )]
462    pub last_action_date: Option<String>,
463    /// Index version of the opportunity record
464    #[serde(
465        rename = "indexVersion",
466        default,
467        skip_serializing_if = "Option::is_none"
468    )]
469    pub index_version: Option<String>,
470    /// ISO 8601 timestamp when the opportunity was created
471    #[serde(rename = "createdAt", default, skip_serializing_if = "Option::is_none")]
472    pub created_at: Option<String>,
473    /// ISO 8601 timestamp when the opportunity was last updated
474    #[serde(rename = "updatedAt", default, skip_serializing_if = "Option::is_none")]
475    pub updated_at: Option<String>,
476    /// Expected close date for the forecast (YYYY-MM-DD)
477    #[serde(
478        rename = "forecastExpectedCloseDate",
479        default,
480        skip_serializing_if = "Option::is_none"
481    )]
482    pub forecast_expected_close_date: Option<String>,
483    /// Original forecast close date before any slippage (YYYY-MM-DD)
484    #[serde(
485        rename = "forecastOriginalCloseDate",
486        default,
487        skip_serializing_if = "Option::is_none"
488    )]
489    pub forecast_original_close_date: Option<String>,
490    /// Number of times the close date has slipped
491    #[serde(
492        rename = "forecastSlippageCount",
493        default,
494        skip_serializing_if = "Option::is_none"
495    )]
496    pub forecast_slippage_count: Option<f64>,
497    /// Total days the close date has slipped
498    #[serde(
499        rename = "forecastDaysSlipped",
500        default,
501        skip_serializing_if = "Option::is_none"
502    )]
503    pub forecast_days_slipped: Option<f64>,
504    /// ISO 8601 timestamp of the last close-date slip
505    #[serde(
506        rename = "forecastLastSlippedAt",
507        default,
508        skip_serializing_if = "Option::is_none"
509    )]
510    pub forecast_last_slipped_at: Option<String>,
511    /// Forecast win probability percentage (0–100)
512    #[serde(
513        rename = "forecastProbability",
514        default,
515        skip_serializing_if = "Option::is_none"
516    )]
517    pub forecast_probability: Option<f64>,
518    /// Effective win probability after stage and forecast adjustments (0–100)
519    #[serde(
520        rename = "effectiveProbability",
521        default,
522        skip_serializing_if = "Option::is_none"
523    )]
524    pub effective_probability: Option<f64>,
525    /// Identifier of the contact linked to the opportunity
526    #[serde(rename = "contactId", default, skip_serializing_if = "Option::is_none")]
527    pub contact_id: Option<String>,
528    /// Identifier of the location (sub-account) the opportunity belongs to
529    #[serde(
530        rename = "locationId",
531        default,
532        skip_serializing_if = "Option::is_none"
533    )]
534    pub location_id: Option<String>,
535    /// Contact details associated with the opportunity
536    #[serde(default, skip_serializing_if = "Option::is_none")]
537    pub contact: Option<SearchOpportunitiesContactResponseSchema>,
538    /// Notes attached to the opportunity
539    #[serde(default, skip_serializing_if = "Vec::is_empty")]
540    pub notes: Vec<Vec<serde_json::Value>>,
541    /// Tasks attached to the opportunity
542    #[serde(default, skip_serializing_if = "Vec::is_empty")]
543    pub tasks: Vec<Vec<serde_json::Value>>,
544    /// Calendar events attached to the opportunity
545    #[serde(
546        rename = "calendarEvents",
547        default,
548        skip_serializing_if = "Vec::is_empty"
549    )]
550    pub calendar_events: Vec<Vec<serde_json::Value>>,
551    /// Identifier of the lost reason if the opportunity was marked lost
552    #[serde(
553        rename = "lostReasonId",
554        default,
555        skip_serializing_if = "Option::is_none"
556    )]
557    pub lost_reason_id: Option<String>,
558    /// Custom fields associated with the opportunity
559    #[serde(
560        rename = "customFields",
561        default,
562        skip_serializing_if = "Vec::is_empty"
563    )]
564    pub custom_fields: Vec<CustomFieldResponseSchema>,
565    /// User IDs following this opportunity
566    #[serde(default, skip_serializing_if = "Vec::is_empty")]
567    pub followers: Vec<Vec<serde_json::Value>>,
568    /// External object identifier for integrations
569    #[serde(
570        rename = "externalObjectId",
571        default,
572        skip_serializing_if = "Option::is_none"
573    )]
574    pub external_object_id: Option<String>,
575}
576
577/// `SearchSuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
578#[derive(Debug, Clone, Default, Serialize, Deserialize)]
579pub struct SearchSuccessfulResponseDto {
580    /// List of opportunities matching the search criteria
581    #[serde(default, skip_serializing_if = "Vec::is_empty")]
582    pub opportunities: Vec<SearchOpportunitiesResponseSchema>,
583    /// Pagination metadata for the result set
584    #[serde(default, skip_serializing_if = "Option::is_none")]
585    pub meta: Option<SearchMetaResponseSchema>,
586    /// Aggregation results keyed by aggregation name
587    #[serde(default, skip_serializing_if = "Option::is_none")]
588    pub aggregations: Option<serde_json::Value>,
589}
590
591/// `StageAggregationResponseDto` from the GoHighLevel OpenAPI spec.
592#[derive(Debug, Clone, Default, Serialize, Deserialize)]
593pub struct StageAggregationResponseDto {
594    /// Identifier of the pipeline stage being aggregated
595    /// Required by the API.
596    /// (Optional here so responses that omit it still parse.)
597    #[serde(
598        rename = "pipelineStageId",
599        default,
600        skip_serializing_if = "Option::is_none"
601    )]
602    pub pipeline_stage_id: Option<String>,
603    /// Total number of opportunities in this stage
604    /// Required by the API.
605    /// (Optional here so responses that omit it still parse.)
606    #[serde(
607        rename = "totalCount",
608        default,
609        skip_serializing_if = "Option::is_none"
610    )]
611    pub total_count: Option<f64>,
612    /// Total monetary value of all opportunities in this stage
613    /// Required by the API.
614    /// (Optional here so responses that omit it still parse.)
615    #[serde(
616        rename = "totalValue",
617        default,
618        skip_serializing_if = "Option::is_none"
619    )]
620    pub total_value: Option<f64>,
621    /// Probability-weighted total value of opportunities in this stage
622    /// Required by the API.
623    /// (Optional here so responses that omit it still parse.)
624    #[serde(
625        rename = "weightedValue",
626        default,
627        skip_serializing_if = "Option::is_none"
628    )]
629    pub weighted_value: Option<f64>,
630    /// Total value of open opportunities in this stage
631    /// Required by the API.
632    /// (Optional here so responses that omit it still parse.)
633    #[serde(rename = "openValue", default, skip_serializing_if = "Option::is_none")]
634    pub open_value: Option<f64>,
635    /// Probability-weighted value of open opportunities in this stage
636    /// Required by the API.
637    /// (Optional here so responses that omit it still parse.)
638    #[serde(
639        rename = "openWeightedValue",
640        default,
641        skip_serializing_if = "Option::is_none"
642    )]
643    pub open_weighted_value: Option<f64>,
644    /// Total value of won opportunities in this stage
645    /// Required by the API.
646    /// (Optional here so responses that omit it still parse.)
647    #[serde(rename = "wonValue", default, skip_serializing_if = "Option::is_none")]
648    pub won_value: Option<f64>,
649}
650
651/// `UpdateOpportunityDtoV3` from the GoHighLevel OpenAPI spec.
652#[derive(Debug, Clone, Default, Serialize, Deserialize)]
653pub struct UpdateOpportunityDtoV3 {
654    /// pipeline Id
655    #[serde(
656        rename = "pipelineId",
657        default,
658        skip_serializing_if = "Option::is_none"
659    )]
660    pub pipeline_id: Option<String>,
661    /// Name of the opportunity
662    #[serde(default, skip_serializing_if = "Option::is_none")]
663    pub name: Option<String>,
664    /// Identifier of the pipeline stage
665    #[serde(
666        rename = "pipelineStageId",
667        default,
668        skip_serializing_if = "Option::is_none"
669    )]
670    pub pipeline_stage_id: Option<String>,
671    /// Current status of the opportunity
672    /// Allowed values: `open`, `won`, `lost`, `abandoned`, `all`.
673    #[serde(default, skip_serializing_if = "Option::is_none")]
674    pub status: Option<String>,
675    /// Monetary value of the opportunity
676    #[serde(
677        rename = "monetaryValue",
678        default,
679        skip_serializing_if = "Option::is_none"
680    )]
681    pub monetary_value: Option<f64>,
682    /// Expected close date. Supported formats: YYYY/MM/DD, MM/DD/YYYY, YYYY-MM-DD, MM-DD-YYYY,
683    /// YYYY.MM.DD, MM.DD.YYYY, or ISO 8601
684    #[serde(
685        rename = "forecastExpectedCloseDate",
686        default,
687        skip_serializing_if = "Option::is_none"
688    )]
689    pub forecast_expected_close_date: Option<String>,
690    /// Forecast probability
691    #[serde(
692        rename = "forecastProbability",
693        default,
694        skip_serializing_if = "Option::is_none"
695    )]
696    pub forecast_probability: Option<f64>,
697    /// Identifier of the user the opportunity is assigned to
698    #[serde(
699        rename = "assignedTo",
700        default,
701        skip_serializing_if = "Option::is_none"
702    )]
703    pub assigned_to: Option<String>,
704    /// Update custom fields to opportunities.
705    /// Multiple possible shapes in the spec; raw JSON.
706    #[serde(
707        rename = "customFields",
708        default,
709        skip_serializing_if = "Vec::is_empty"
710    )]
711    pub custom_fields: Vec<serde_json::Value>,
712}
713
714/// `UpdateStatusDto` from the GoHighLevel OpenAPI spec.
715#[derive(Debug, Clone, Default, Serialize, Deserialize)]
716pub struct UpdateStatusDto {
717    /// New status for the opportunity
718    /// Allowed values: `open`, `won`, `lost`, `abandoned`, `all`.
719    /// Required by the API.
720    pub status: String,
721    /// lost reason Id
722    #[serde(
723        rename = "lostReasonId",
724        default,
725        skip_serializing_if = "Option::is_none"
726    )]
727    pub lost_reason_id: Option<String>,
728}
729
730/// `UpsertOpportunityDto` from the GoHighLevel OpenAPI spec.
731#[derive(Debug, Clone, Default, Serialize, Deserialize)]
732pub struct UpsertOpportunityDto {
733    /// opportunityId
734    #[serde(default, skip_serializing_if = "Option::is_none")]
735    pub id: Option<String>,
736    /// pipeline Id
737    /// Required by the API.
738    #[serde(rename = "pipelineId")]
739    pub pipeline_id: String,
740    /// locationId
741    /// Required by the API.
742    #[serde(rename = "locationId")]
743    pub location_id: String,
744    /// contactId
745    /// Required by the API.
746    #[serde(default, skip_serializing_if = "Vec::is_empty")]
747    pub followers: Vec<String>,
748    /// isRemoveAllFollowers
749    /// Required by the API.
750    #[serde(rename = "isRemoveAllFollowers")]
751    pub is_remove_all_followers: bool,
752    /// followers action type
753    /// Allowed values: `add`, `remove`.
754    /// Required by the API.
755    #[serde(rename = "followersActionType")]
756    pub followers_action_type: String,
757    /// name
758    #[serde(default, skip_serializing_if = "Option::is_none")]
759    pub name: Option<String>,
760    /// Current status of the opportunity
761    /// Allowed values: `open`, `won`, `lost`, `abandoned`, `all`.
762    #[serde(default, skip_serializing_if = "Option::is_none")]
763    pub status: Option<String>,
764    /// Identifier of the pipeline stage
765    #[serde(
766        rename = "pipelineStageId",
767        default,
768        skip_serializing_if = "Option::is_none"
769    )]
770    pub pipeline_stage_id: Option<String>,
771    /// Monetary value of the opportunity
772    #[serde(
773        rename = "monetaryValue",
774        default,
775        skip_serializing_if = "Option::is_none"
776    )]
777    pub monetary_value: Option<serde_json::Value>,
778    /// Expected close date. Supported formats: YYYY/MM/DD, MM/DD/YYYY, YYYY-MM-DD, MM-DD-YYYY,
779    /// YYYY.MM.DD, MM.DD.YYYY, or ISO 8601
780    #[serde(
781        rename = "forecastExpectedCloseDate",
782        default,
783        skip_serializing_if = "Option::is_none"
784    )]
785    pub forecast_expected_close_date: Option<String>,
786    /// Forecast probability
787    #[serde(
788        rename = "forecastProbability",
789        default,
790        skip_serializing_if = "Option::is_none"
791    )]
792    pub forecast_probability: Option<f64>,
793    /// Identifier of the user the opportunity is assigned to
794    #[serde(
795        rename = "assignedTo",
796        default,
797        skip_serializing_if = "Option::is_none"
798    )]
799    pub assigned_to: Option<String>,
800    /// lost reason Id
801    #[serde(
802        rename = "lostReasonId",
803        default,
804        skip_serializing_if = "Option::is_none"
805    )]
806    pub lost_reason_id: Option<String>,
807}
808
809/// `UpsertOpportunitySuccessfulResponseDto` from the GoHighLevel OpenAPI spec.
810#[derive(Debug, Clone, Default, Serialize, Deserialize)]
811pub struct UpsertOpportunitySuccessfulResponseDto {
812    /// Updated / New Opportunity
813    /// Required by the API.
814    /// (Optional here so responses that omit it still parse.)
815    #[serde(default, skip_serializing_if = "Option::is_none")]
816    pub opportunity: Option<serde_json::Value>,
817    /// Indicates whether the opportunity was newly created (true) or updated (false)
818    /// Required by the API.
819    /// (Optional here so responses that omit it still parse.)
820    #[serde(default, skip_serializing_if = "Option::is_none")]
821    pub new: Option<bool>,
822}
823
824/// `customFieldsInputArraySchemaV3` from the GoHighLevel OpenAPI spec.
825#[derive(Debug, Clone, Default, Serialize, Deserialize)]
826pub struct CustomFieldsInputArraySchemaV3 {
827    /// Pass either `id` or `key` of custom field
828    /// Required by the API.
829    pub id: String,
830    /// Pass either `id` or `key` of custom field
831    #[serde(default, skip_serializing_if = "Option::is_none")]
832    pub key: Option<String>,
833    /// Value of the custom field
834    #[serde(rename = "fieldValue", default, skip_serializing_if = "Vec::is_empty")]
835    pub field_value: Vec<String>,
836}
837
838/// `customFieldsInputObjectSchemaV3` from the GoHighLevel OpenAPI spec.
839#[derive(Debug, Clone, Default, Serialize, Deserialize)]
840pub struct CustomFieldsInputObjectSchemaV3 {
841    /// Pass either `id` or `key` of custom field
842    /// Required by the API.
843    pub id: String,
844    /// Pass either `id` or `key` of custom field
845    #[serde(default, skip_serializing_if = "Option::is_none")]
846    pub key: Option<String>,
847    /// Value of the custom field
848    #[serde(
849        rename = "fieldValue",
850        default,
851        skip_serializing_if = "Option::is_none"
852    )]
853    pub field_value: Option<serde_json::Value>,
854}
855
856/// `customFieldsInputStringSchemaV3` from the GoHighLevel OpenAPI spec.
857#[derive(Debug, Clone, Default, Serialize, Deserialize)]
858pub struct CustomFieldsInputStringSchemaV3 {
859    /// Pass either `id` or `key` of custom field
860    #[serde(default, skip_serializing_if = "Option::is_none")]
861    pub id: Option<String>,
862    /// Pass either `id` or `key` of custom field
863    #[serde(default, skip_serializing_if = "Option::is_none")]
864    pub key: Option<String>,
865    /// Value of the custom field
866    #[serde(
867        rename = "fieldValue",
868        default,
869        skip_serializing_if = "Option::is_none"
870    )]
871    pub field_value: Option<String>,
872}