dub 0.29.2__py3-none-any.whl → 0.31.0__py3-none-any.whl

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.
@@ -401,6 +401,7 @@ class CreatePartnerStatus(str, Enum):
401
401
  REJECTED = "rejected"
402
402
  INVITED = "invited"
403
403
  DECLINED = "declined"
404
+ DEACTIVATED = "deactivated"
404
405
  BANNED = "banned"
405
406
  ARCHIVED = "archived"
406
407
 
@@ -420,6 +421,8 @@ class CreatePartnerLinkTypedDict(TypedDict):
420
421
  r"""The number of clicks on the short link."""
421
422
  leads: NotRequired[float]
422
423
  r"""The number of leads the short link has generated."""
424
+ conversions: NotRequired[float]
425
+ r"""The number of leads that converted to paying customers."""
423
426
  sales: NotRequired[float]
424
427
  r"""The total number of sales (includes recurring sales) generated by the short link."""
425
428
  sale_amount: NotRequired[float]
@@ -448,6 +451,9 @@ class CreatePartnerLink(BaseModel):
448
451
  leads: Optional[float] = 0
449
452
  r"""The number of leads the short link has generated."""
450
453
 
454
+ conversions: Optional[float] = 0
455
+ r"""The number of leads that converted to paying customers."""
456
+
451
457
  sales: Optional[float] = 0
452
458
  r"""The total number of sales (includes recurring sales) generated by the short link."""
453
459
 
@@ -467,12 +473,14 @@ class BannedReason(str, Enum):
467
473
 
468
474
 
469
475
  class CreatePartnerResponseBodyTypedDict(TypedDict):
470
- r"""The created partner"""
476
+ r"""The created or updated partner"""
471
477
 
472
478
  id: str
473
479
  r"""The partner's unique ID on Dub."""
474
480
  name: str
475
481
  r"""The partner's full legal name."""
482
+ company_name: Nullable[str]
483
+ r"""If the partner profile type is a company, this is the partner's legal company name."""
476
484
  email: Nullable[str]
477
485
  r"""The partner's email address. Should be a unique value across Dub."""
478
486
  image: Nullable[str]
@@ -526,29 +534,20 @@ class CreatePartnerResponseBodyTypedDict(TypedDict):
526
534
  r"""The total net revenue generated by the partner. Defaults to 0 if `includeExpandedFields` is false."""
527
535
  website: NotRequired[Nullable[str]]
528
536
  r"""The partner's website URL (including the https protocol)."""
529
- website_txt_record: NotRequired[Nullable[str]]
530
- website_verified_at: NotRequired[Nullable[str]]
531
537
  youtube: NotRequired[Nullable[str]]
532
538
  r"""The partner's YouTube channel username (e.g. `johndoe`)."""
533
- youtube_verified_at: NotRequired[Nullable[str]]
534
- youtube_subscriber_count: NotRequired[Nullable[float]]
535
- youtube_view_count: NotRequired[Nullable[float]]
536
539
  twitter: NotRequired[Nullable[str]]
537
540
  r"""The partner's Twitter username (e.g. `johndoe`)."""
538
- twitter_verified_at: NotRequired[Nullable[str]]
539
541
  linkedin: NotRequired[Nullable[str]]
540
542
  r"""The partner's LinkedIn username (e.g. `johndoe`)."""
541
- linkedin_verified_at: NotRequired[Nullable[str]]
542
543
  instagram: NotRequired[Nullable[str]]
543
544
  r"""The partner's Instagram username (e.g. `johndoe`)."""
544
- instagram_verified_at: NotRequired[Nullable[str]]
545
545
  tiktok: NotRequired[Nullable[str]]
546
546
  r"""The partner's TikTok username (e.g. `johndoe`)."""
547
- tiktok_verified_at: NotRequired[Nullable[str]]
548
547
 
549
548
 
550
549
  class CreatePartnerResponseBody(BaseModel):
551
- r"""The created partner"""
550
+ r"""The created or updated partner"""
552
551
 
553
552
  id: str
554
553
  r"""The partner's unique ID on Dub."""
@@ -556,6 +555,9 @@ class CreatePartnerResponseBody(BaseModel):
556
555
  name: str
557
556
  r"""The partner's full legal name."""
558
557
 
558
+ company_name: Annotated[Nullable[str], pydantic.Field(alias="companyName")]
559
+ r"""If the partner profile type is a company, this is the partner's legal company name."""
560
+
559
561
  email: Nullable[str]
560
562
  r"""The partner's email address. Should be a unique value across Dub."""
561
563
 
@@ -656,57 +658,21 @@ class CreatePartnerResponseBody(BaseModel):
656
658
  website: OptionalNullable[str] = UNSET
657
659
  r"""The partner's website URL (including the https protocol)."""
658
660
 
659
- website_txt_record: Annotated[
660
- OptionalNullable[str], pydantic.Field(alias="websiteTxtRecord")
661
- ] = UNSET
662
-
663
- website_verified_at: Annotated[
664
- OptionalNullable[str], pydantic.Field(alias="websiteVerifiedAt")
665
- ] = UNSET
666
-
667
661
  youtube: OptionalNullable[str] = UNSET
668
662
  r"""The partner's YouTube channel username (e.g. `johndoe`)."""
669
663
 
670
- youtube_verified_at: Annotated[
671
- OptionalNullable[str], pydantic.Field(alias="youtubeVerifiedAt")
672
- ] = UNSET
673
-
674
- youtube_subscriber_count: Annotated[
675
- OptionalNullable[float], pydantic.Field(alias="youtubeSubscriberCount")
676
- ] = UNSET
677
-
678
- youtube_view_count: Annotated[
679
- OptionalNullable[float], pydantic.Field(alias="youtubeViewCount")
680
- ] = UNSET
681
-
682
664
  twitter: OptionalNullable[str] = UNSET
683
665
  r"""The partner's Twitter username (e.g. `johndoe`)."""
684
666
 
685
- twitter_verified_at: Annotated[
686
- OptionalNullable[str], pydantic.Field(alias="twitterVerifiedAt")
687
- ] = UNSET
688
-
689
667
  linkedin: OptionalNullable[str] = UNSET
690
668
  r"""The partner's LinkedIn username (e.g. `johndoe`)."""
691
669
 
692
- linkedin_verified_at: Annotated[
693
- OptionalNullable[str], pydantic.Field(alias="linkedinVerifiedAt")
694
- ] = UNSET
695
-
696
670
  instagram: OptionalNullable[str] = UNSET
697
671
  r"""The partner's Instagram username (e.g. `johndoe`)."""
698
672
 
699
- instagram_verified_at: Annotated[
700
- OptionalNullable[str], pydantic.Field(alias="instagramVerifiedAt")
701
- ] = UNSET
702
-
703
673
  tiktok: OptionalNullable[str] = UNSET
704
674
  r"""The partner's TikTok username (e.g. `johndoe`)."""
705
675
 
706
- tiktok_verified_at: Annotated[
707
- OptionalNullable[str], pydantic.Field(alias="tiktokVerifiedAt")
708
- ] = UNSET
709
-
710
676
  @model_serializer(mode="wrap")
711
677
  def serialize_model(self, handler):
712
678
  optional_fields = [
@@ -727,22 +693,14 @@ class CreatePartnerResponseBody(BaseModel):
727
693
  "saleAmount",
728
694
  "netRevenue",
729
695
  "website",
730
- "websiteTxtRecord",
731
- "websiteVerifiedAt",
732
696
  "youtube",
733
- "youtubeVerifiedAt",
734
- "youtubeSubscriberCount",
735
- "youtubeViewCount",
736
697
  "twitter",
737
- "twitterVerifiedAt",
738
698
  "linkedin",
739
- "linkedinVerifiedAt",
740
699
  "instagram",
741
- "instagramVerifiedAt",
742
700
  "tiktok",
743
- "tiktokVerifiedAt",
744
701
  ]
745
702
  nullable_fields = [
703
+ "companyName",
746
704
  "email",
747
705
  "image",
748
706
  "description",
@@ -761,20 +719,11 @@ class CreatePartnerResponseBody(BaseModel):
761
719
  "bannedAt",
762
720
  "bannedReason",
763
721
  "website",
764
- "websiteTxtRecord",
765
- "websiteVerifiedAt",
766
722
  "youtube",
767
- "youtubeVerifiedAt",
768
- "youtubeSubscriberCount",
769
- "youtubeViewCount",
770
723
  "twitter",
771
- "twitterVerifiedAt",
772
724
  "linkedin",
773
- "linkedinVerifiedAt",
774
725
  "instagram",
775
- "instagramVerifiedAt",
776
726
  "tiktok",
777
- "tiktokVerifiedAt",
778
727
  ]
779
728
  null_default_fields = []
780
729
 
@@ -191,9 +191,9 @@ class GetCustomerDiscount(BaseModel):
191
191
  optional_fields = ["description", "partnersCount"]
192
192
  nullable_fields = [
193
193
  "maxDuration",
194
- "description",
195
194
  "couponId",
196
195
  "couponTestId",
196
+ "description",
197
197
  "partnersCount",
198
198
  ]
199
199
  null_default_fields = []
@@ -275,9 +275,9 @@ class Discount(BaseModel):
275
275
  optional_fields = ["description", "partnersCount"]
276
276
  nullable_fields = [
277
277
  "maxDuration",
278
- "description",
279
278
  "couponId",
280
279
  "couponTestId",
280
+ "description",
281
281
  "partnersCount",
282
282
  ]
283
283
  null_default_fields = []
@@ -64,7 +64,9 @@ class ListCommissionsRequestTypedDict(TypedDict):
64
64
  payout_id: NotRequired[str]
65
65
  r"""Filter the list of commissions by the associated payout."""
66
66
  partner_id: NotRequired[str]
67
- r"""Filter the list of commissions by the associated partner."""
67
+ r"""Filter the list of commissions by the associated partner. When specified, takes precedence over `tenantId`."""
68
+ tenant_id: NotRequired[str]
69
+ r"""Filter the list of commissions by the associated partner's `tenantId` (their unique ID within your database)."""
68
70
  group_id: NotRequired[str]
69
71
  r"""Filter the list of commissions by the associated partner group."""
70
72
  invoice_id: NotRequired[str]
@@ -112,7 +114,14 @@ class ListCommissionsRequest(BaseModel):
112
114
  pydantic.Field(alias="partnerId"),
113
115
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
114
116
  ] = None
115
- r"""Filter the list of commissions by the associated partner."""
117
+ r"""Filter the list of commissions by the associated partner. When specified, takes precedence over `tenantId`."""
118
+
119
+ tenant_id: Annotated[
120
+ Optional[str],
121
+ pydantic.Field(alias="tenantId"),
122
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
123
+ ] = None
124
+ r"""Filter the list of commissions by the associated partner's `tenantId` (their unique ID within your database)."""
116
125
 
117
126
  group_id: Annotated[
118
127
  Optional[str],
@@ -168,6 +168,8 @@ class ListEventsRequestTypedDict(TypedDict):
168
168
  r"""The UTM term of the short link."""
169
169
  utm_content: NotRequired[Nullable[str]]
170
170
  r"""The UTM content of the short link."""
171
+ ref: NotRequired[Nullable[str]]
172
+ r"""The ref of the short link."""
171
173
  page: NotRequired[float]
172
174
  limit: NotRequired[float]
173
175
  sort_order: NotRequired[QueryParamSortOrder]
@@ -406,6 +408,12 @@ class ListEventsRequest(BaseModel):
406
408
  ] = UNSET
407
409
  r"""The UTM content of the short link."""
408
410
 
411
+ ref: Annotated[
412
+ OptionalNullable[str],
413
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
414
+ ] = UNSET
415
+ r"""The ref of the short link."""
416
+
409
417
  page: Annotated[
410
418
  Optional[float],
411
419
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
@@ -475,6 +483,7 @@ class ListEventsRequest(BaseModel):
475
483
  "utm_campaign",
476
484
  "utm_term",
477
485
  "utm_content",
486
+ "ref",
478
487
  "page",
479
488
  "limit",
480
489
  "sortOrder",
@@ -487,6 +496,7 @@ class ListEventsRequest(BaseModel):
487
496
  "utm_campaign",
488
497
  "utm_term",
489
498
  "utm_content",
499
+ "ref",
490
500
  ]
491
501
  null_default_fields = []
492
502
 
@@ -18,6 +18,7 @@ class ListPartnersQueryParamStatus(str, Enum):
18
18
  REJECTED = "rejected"
19
19
  INVITED = "invited"
20
20
  DECLINED = "declined"
21
+ DEACTIVATED = "deactivated"
21
22
  BANNED = "banned"
22
23
  ARCHIVED = "archived"
23
24
 
@@ -31,7 +32,7 @@ class ListPartnersQueryParamSortBy(str, Enum):
31
32
  CONVERSIONS = "conversions"
32
33
  SALES = "sales"
33
34
  SALE_AMOUNT = "saleAmount"
34
- COMMISSIONS = "commissions"
35
+ TOTAL_COMMISSIONS = "totalCommissions"
35
36
  NET_REVENUE = "netRevenue"
36
37
 
37
38
 
@@ -51,12 +52,14 @@ class ListPartnersRequestTypedDict(TypedDict):
51
52
  r"""The field to sort the partners by. The default is `saleAmount`."""
52
53
  sort_order: NotRequired[ListPartnersQueryParamSortOrder]
53
54
  r"""The sort order. The default is `desc`."""
55
+ email: NotRequired[str]
56
+ r"""Filter the partner list based on the partner's `email`. The value must be a string. Takes precedence over `search`."""
54
57
  tenant_id: NotRequired[str]
55
- r"""A case-sensitive filter on the list based on the partner's `tenantId` field. The value must be a string. Takes precedence over `search`."""
58
+ r"""Filter the partner list based on the partner's `tenantId`. The value must be a string. Takes precedence over `email` and `search`."""
59
+ search: NotRequired[str]
60
+ r"""A search query to filter partners by ID, name, email, or link."""
56
61
  include_expanded_fields: NotRequired[bool]
57
62
  r"""Whether to include stats fields on the partner (`clicks`, `leads`, `conversions`, `sales`, `saleAmount`, `commissions`, `netRevenue`). If false, those fields will be returned as 0."""
58
- search: NotRequired[str]
59
- r"""A search query to filter partners by name, email, or tenantId."""
60
63
  page: NotRequired[float]
61
64
  r"""The page number for pagination."""
62
65
  page_size: NotRequired[float]
@@ -90,12 +93,24 @@ class ListPartnersRequest(BaseModel):
90
93
  ] = ListPartnersQueryParamSortOrder.DESC
91
94
  r"""The sort order. The default is `desc`."""
92
95
 
96
+ email: Annotated[
97
+ Optional[str],
98
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
99
+ ] = None
100
+ r"""Filter the partner list based on the partner's `email`. The value must be a string. Takes precedence over `search`."""
101
+
93
102
  tenant_id: Annotated[
94
103
  Optional[str],
95
104
  pydantic.Field(alias="tenantId"),
96
105
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
97
106
  ] = None
98
- r"""A case-sensitive filter on the list based on the partner's `tenantId` field. The value must be a string. Takes precedence over `search`."""
107
+ r"""Filter the partner list based on the partner's `tenantId`. The value must be a string. Takes precedence over `email` and `search`."""
108
+
109
+ search: Annotated[
110
+ Optional[str],
111
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
112
+ ] = None
113
+ r"""A search query to filter partners by ID, name, email, or link."""
99
114
 
100
115
  include_expanded_fields: Annotated[
101
116
  Optional[bool],
@@ -104,12 +119,6 @@ class ListPartnersRequest(BaseModel):
104
119
  ] = None
105
120
  r"""Whether to include stats fields on the partner (`clicks`, `leads`, `conversions`, `sales`, `saleAmount`, `commissions`, `netRevenue`). If false, those fields will be returned as 0."""
106
121
 
107
- search: Annotated[
108
- Optional[str],
109
- FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
110
- ] = None
111
- r"""A search query to filter partners by name, email, or tenantId."""
112
-
113
122
  page: Annotated[
114
123
  Optional[float],
115
124
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
@@ -132,6 +141,7 @@ class ListPartnersStatus(str, Enum):
132
141
  REJECTED = "rejected"
133
142
  INVITED = "invited"
134
143
  DECLINED = "declined"
144
+ DEACTIVATED = "deactivated"
135
145
  BANNED = "banned"
136
146
  ARCHIVED = "archived"
137
147
 
@@ -151,6 +161,8 @@ class ListPartnersLinkTypedDict(TypedDict):
151
161
  r"""The number of clicks on the short link."""
152
162
  leads: NotRequired[float]
153
163
  r"""The number of leads the short link has generated."""
164
+ conversions: NotRequired[float]
165
+ r"""The number of leads that converted to paying customers."""
154
166
  sales: NotRequired[float]
155
167
  r"""The total number of sales (includes recurring sales) generated by the short link."""
156
168
  sale_amount: NotRequired[float]
@@ -179,6 +191,9 @@ class ListPartnersLink(BaseModel):
179
191
  leads: Optional[float] = 0
180
192
  r"""The number of leads the short link has generated."""
181
193
 
194
+ conversions: Optional[float] = 0
195
+ r"""The number of leads that converted to paying customers."""
196
+
182
197
  sales: Optional[float] = 0
183
198
  r"""The total number of sales (includes recurring sales) generated by the short link."""
184
199
 
@@ -202,6 +217,8 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
202
217
  r"""The partner's unique ID on Dub."""
203
218
  name: str
204
219
  r"""The partner's full legal name."""
220
+ company_name: Nullable[str]
221
+ r"""If the partner profile type is a company, this is the partner's legal company name."""
205
222
  email: Nullable[str]
206
223
  r"""The partner's email address. Should be a unique value across Dub."""
207
224
  image: Nullable[str]
@@ -255,25 +272,16 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
255
272
  r"""The total net revenue generated by the partner. Defaults to 0 if `includeExpandedFields` is false."""
256
273
  website: NotRequired[Nullable[str]]
257
274
  r"""The partner's website URL (including the https protocol)."""
258
- website_txt_record: NotRequired[Nullable[str]]
259
- website_verified_at: NotRequired[Nullable[str]]
260
275
  youtube: NotRequired[Nullable[str]]
261
276
  r"""The partner's YouTube channel username (e.g. `johndoe`)."""
262
- youtube_verified_at: NotRequired[Nullable[str]]
263
- youtube_subscriber_count: NotRequired[Nullable[float]]
264
- youtube_view_count: NotRequired[Nullable[float]]
265
277
  twitter: NotRequired[Nullable[str]]
266
278
  r"""The partner's Twitter username (e.g. `johndoe`)."""
267
- twitter_verified_at: NotRequired[Nullable[str]]
268
279
  linkedin: NotRequired[Nullable[str]]
269
280
  r"""The partner's LinkedIn username (e.g. `johndoe`)."""
270
- linkedin_verified_at: NotRequired[Nullable[str]]
271
281
  instagram: NotRequired[Nullable[str]]
272
282
  r"""The partner's Instagram username (e.g. `johndoe`)."""
273
- instagram_verified_at: NotRequired[Nullable[str]]
274
283
  tiktok: NotRequired[Nullable[str]]
275
284
  r"""The partner's TikTok username (e.g. `johndoe`)."""
276
- tiktok_verified_at: NotRequired[Nullable[str]]
277
285
 
278
286
 
279
287
  class ListPartnersResponseBody(BaseModel):
@@ -283,6 +291,9 @@ class ListPartnersResponseBody(BaseModel):
283
291
  name: str
284
292
  r"""The partner's full legal name."""
285
293
 
294
+ company_name: Annotated[Nullable[str], pydantic.Field(alias="companyName")]
295
+ r"""If the partner profile type is a company, this is the partner's legal company name."""
296
+
286
297
  email: Nullable[str]
287
298
  r"""The partner's email address. Should be a unique value across Dub."""
288
299
 
@@ -383,57 +394,21 @@ class ListPartnersResponseBody(BaseModel):
383
394
  website: OptionalNullable[str] = UNSET
384
395
  r"""The partner's website URL (including the https protocol)."""
385
396
 
386
- website_txt_record: Annotated[
387
- OptionalNullable[str], pydantic.Field(alias="websiteTxtRecord")
388
- ] = UNSET
389
-
390
- website_verified_at: Annotated[
391
- OptionalNullable[str], pydantic.Field(alias="websiteVerifiedAt")
392
- ] = UNSET
393
-
394
397
  youtube: OptionalNullable[str] = UNSET
395
398
  r"""The partner's YouTube channel username (e.g. `johndoe`)."""
396
399
 
397
- youtube_verified_at: Annotated[
398
- OptionalNullable[str], pydantic.Field(alias="youtubeVerifiedAt")
399
- ] = UNSET
400
-
401
- youtube_subscriber_count: Annotated[
402
- OptionalNullable[float], pydantic.Field(alias="youtubeSubscriberCount")
403
- ] = UNSET
404
-
405
- youtube_view_count: Annotated[
406
- OptionalNullable[float], pydantic.Field(alias="youtubeViewCount")
407
- ] = UNSET
408
-
409
400
  twitter: OptionalNullable[str] = UNSET
410
401
  r"""The partner's Twitter username (e.g. `johndoe`)."""
411
402
 
412
- twitter_verified_at: Annotated[
413
- OptionalNullable[str], pydantic.Field(alias="twitterVerifiedAt")
414
- ] = UNSET
415
-
416
403
  linkedin: OptionalNullable[str] = UNSET
417
404
  r"""The partner's LinkedIn username (e.g. `johndoe`)."""
418
405
 
419
- linkedin_verified_at: Annotated[
420
- OptionalNullable[str], pydantic.Field(alias="linkedinVerifiedAt")
421
- ] = UNSET
422
-
423
406
  instagram: OptionalNullable[str] = UNSET
424
407
  r"""The partner's Instagram username (e.g. `johndoe`)."""
425
408
 
426
- instagram_verified_at: Annotated[
427
- OptionalNullable[str], pydantic.Field(alias="instagramVerifiedAt")
428
- ] = UNSET
429
-
430
409
  tiktok: OptionalNullable[str] = UNSET
431
410
  r"""The partner's TikTok username (e.g. `johndoe`)."""
432
411
 
433
- tiktok_verified_at: Annotated[
434
- OptionalNullable[str], pydantic.Field(alias="tiktokVerifiedAt")
435
- ] = UNSET
436
-
437
412
  @model_serializer(mode="wrap")
438
413
  def serialize_model(self, handler):
439
414
  optional_fields = [
@@ -454,22 +429,14 @@ class ListPartnersResponseBody(BaseModel):
454
429
  "saleAmount",
455
430
  "netRevenue",
456
431
  "website",
457
- "websiteTxtRecord",
458
- "websiteVerifiedAt",
459
432
  "youtube",
460
- "youtubeVerifiedAt",
461
- "youtubeSubscriberCount",
462
- "youtubeViewCount",
463
433
  "twitter",
464
- "twitterVerifiedAt",
465
434
  "linkedin",
466
- "linkedinVerifiedAt",
467
435
  "instagram",
468
- "instagramVerifiedAt",
469
436
  "tiktok",
470
- "tiktokVerifiedAt",
471
437
  ]
472
438
  nullable_fields = [
439
+ "companyName",
473
440
  "email",
474
441
  "image",
475
442
  "description",
@@ -488,20 +455,11 @@ class ListPartnersResponseBody(BaseModel):
488
455
  "bannedAt",
489
456
  "bannedReason",
490
457
  "website",
491
- "websiteTxtRecord",
492
- "websiteVerifiedAt",
493
458
  "youtube",
494
- "youtubeVerifiedAt",
495
- "youtubeSubscriberCount",
496
- "youtubeViewCount",
497
459
  "twitter",
498
- "twitterVerifiedAt",
499
460
  "linkedin",
500
- "linkedinVerifiedAt",
501
461
  "instagram",
502
- "instagramVerifiedAt",
503
462
  "tiktok",
504
- "tiktokVerifiedAt",
505
463
  ]
506
464
  null_default_fields = []
507
465
 
@@ -179,6 +179,8 @@ class RetrieveAnalyticsRequestTypedDict(TypedDict):
179
179
  r"""The UTM term of the short link."""
180
180
  utm_content: NotRequired[Nullable[str]]
181
181
  r"""The UTM content of the short link."""
182
+ ref: NotRequired[Nullable[str]]
183
+ r"""The ref of the short link."""
182
184
 
183
185
 
184
186
  class RetrieveAnalyticsRequest(BaseModel):
@@ -416,6 +418,12 @@ class RetrieveAnalyticsRequest(BaseModel):
416
418
  ] = UNSET
417
419
  r"""The UTM content of the short link."""
418
420
 
421
+ ref: Annotated[
422
+ OptionalNullable[str],
423
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
424
+ ] = UNSET
425
+ r"""The ref of the short link."""
426
+
419
427
  @model_serializer(mode="wrap")
420
428
  def serialize_model(self, handler):
421
429
  optional_fields = [
@@ -456,6 +464,7 @@ class RetrieveAnalyticsRequest(BaseModel):
456
464
  "utm_campaign",
457
465
  "utm_term",
458
466
  "utm_content",
467
+ "ref",
459
468
  ]
460
469
  nullable_fields = [
461
470
  "utm_source",
@@ -463,6 +472,7 @@ class RetrieveAnalyticsRequest(BaseModel):
463
472
  "utm_campaign",
464
473
  "utm_term",
465
474
  "utm_content",
475
+ "ref",
466
476
  ]
467
477
  null_default_fields = []
468
478
 
@@ -42,6 +42,8 @@ class LinkTypedDict(TypedDict):
42
42
  r"""The number of clicks on the short link."""
43
43
  leads: NotRequired[float]
44
44
  r"""The number of leads the short link has generated."""
45
+ conversions: NotRequired[float]
46
+ r"""The number of leads that converted to paying customers."""
45
47
  sales: NotRequired[float]
46
48
  r"""The total number of sales (includes recurring sales) generated by the short link."""
47
49
  sale_amount: NotRequired[float]
@@ -70,6 +72,9 @@ class Link(BaseModel):
70
72
  leads: Optional[float] = 0
71
73
  r"""The number of leads the short link has generated."""
72
74
 
75
+ conversions: Optional[float] = 0
76
+ r"""The number of leads that converted to paying customers."""
77
+
73
78
  sales: Optional[float] = 0
74
79
  r"""The total number of sales (includes recurring sales) generated by the short link."""
75
80
 
@@ -24,6 +24,8 @@ class UpdateCustomerRequestBodyTypedDict(TypedDict):
24
24
  r"""Avatar URL of the customer in the client's app."""
25
25
  external_id: NotRequired[str]
26
26
  r"""Unique identifier for the customer in the client's app."""
27
+ stripe_customer_id: NotRequired[Nullable[str]]
28
+ r"""The customer's Stripe customer ID. Useful for attribution recurring sale events to the partner who referred the customer."""
27
29
 
28
30
 
29
31
  class UpdateCustomerRequestBody(BaseModel):
@@ -39,10 +41,15 @@ class UpdateCustomerRequestBody(BaseModel):
39
41
  external_id: Annotated[Optional[str], pydantic.Field(alias="externalId")] = None
40
42
  r"""Unique identifier for the customer in the client's app."""
41
43
 
44
+ stripe_customer_id: Annotated[
45
+ OptionalNullable[str], pydantic.Field(alias="stripeCustomerId")
46
+ ] = UNSET
47
+ r"""The customer's Stripe customer ID. Useful for attribution recurring sale events to the partner who referred the customer."""
48
+
42
49
  @model_serializer(mode="wrap")
43
50
  def serialize_model(self, handler):
44
- optional_fields = ["email", "name", "avatar", "externalId"]
45
- nullable_fields = ["email", "name", "avatar"]
51
+ optional_fields = ["email", "name", "avatar", "externalId", "stripeCustomerId"]
52
+ nullable_fields = ["email", "name", "avatar", "stripeCustomerId"]
46
53
  null_default_fields = []
47
54
 
48
55
  serialized = handler(self)
@@ -257,9 +264,9 @@ class UpdateCustomerDiscount(BaseModel):
257
264
  optional_fields = ["description", "partnersCount"]
258
265
  nullable_fields = [
259
266
  "maxDuration",
260
- "description",
261
267
  "couponId",
262
268
  "couponTestId",
269
+ "description",
263
270
  "partnersCount",
264
271
  ]
265
272
  null_default_fields = []
dub/partners.py CHANGED
@@ -24,9 +24,9 @@ class Partners(BaseSDK):
24
24
  timeout_ms: Optional[int] = None,
25
25
  http_headers: Optional[Mapping[str, str]] = None,
26
26
  ) -> Optional[operations.CreatePartnerResponseBody]:
27
- r"""Create a partner
27
+ r"""Create or update a partner
28
28
 
29
- Create a partner for a program. If partner exists, automatically enrolls them.
29
+ Creates or updates a partner record (upsert behavior). If a partner with the same email already exists, their program enrollment will be updated with the provided tenantId. If no existing partner is found, a new partner will be created using the supplied information.
30
30
 
31
31
  :param request: The request object to send.
32
32
  :param retries: Override the default retry configuration for this method
@@ -167,9 +167,9 @@ class Partners(BaseSDK):
167
167
  timeout_ms: Optional[int] = None,
168
168
  http_headers: Optional[Mapping[str, str]] = None,
169
169
  ) -> Optional[operations.CreatePartnerResponseBody]:
170
- r"""Create a partner
170
+ r"""Create or update a partner
171
171
 
172
- Create a partner for a program. If partner exists, automatically enrolls them.
172
+ Creates or updates a partner record (upsert behavior). If a partner with the same email already exists, their program enrollment will be updated with the provided tenantId. If no existing partner is found, a new partner will be created using the supplied information.
173
173
 
174
174
  :param request: The request object to send.
175
175
  :param retries: Override the default retry configuration for this method
dub/sdk.py CHANGED
@@ -88,7 +88,7 @@ class Dub(BaseSDK):
88
88
  """
89
89
  client_supplied = True
90
90
  if client is None:
91
- client = httpx.Client()
91
+ client = httpx.Client(follow_redirects=True)
92
92
  client_supplied = False
93
93
 
94
94
  assert issubclass(
@@ -97,7 +97,7 @@ class Dub(BaseSDK):
97
97
 
98
98
  async_client_supplied = True
99
99
  if async_client is None:
100
- async_client = httpx.AsyncClient()
100
+ async_client = httpx.AsyncClient(follow_redirects=True)
101
101
  async_client_supplied = False
102
102
 
103
103
  if debug_logger is None: