dub 0.31.0__py3-none-any.whl → 0.33.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.
- dub/_version.py +3 -3
- dub/analytics.py +6 -6
- dub/commissions.py +12 -12
- dub/customers.py +24 -321
- dub/domains.py +34 -38
- dub/embed_tokens.py +6 -6
- dub/events.py +6 -6
- dub/folders.py +24 -28
- dub/links.py +58 -74
- dub/models/components/__init__.py +38 -6
- dub/models/components/analyticstopurls.py +2 -2
- dub/models/components/clickevent.py +10 -9
- dub/models/components/commissioncreatedevent.py +5 -2
- dub/models/components/folderschema.py +6 -1
- dub/models/components/leadcreatedevent.py +15 -11
- dub/models/components/leadevent.py +10 -9
- dub/models/components/linkclickedevent.py +10 -9
- dub/models/components/linkschema.py +9 -3
- dub/models/components/{tagschema.py → linktagschema.py} +2 -2
- dub/models/components/linkwebhookevent.py +10 -9
- dub/models/components/partnerapplicationsubmittedevent.py +269 -0
- dub/models/components/partnerenrolledevent.py +93 -29
- dub/models/components/salecreatedevent.py +15 -11
- dub/models/components/saleevent.py +10 -9
- dub/models/components/webhookevent.py +6 -0
- dub/models/components/workspaceschema.py +11 -0
- dub/models/errors/badrequest.py +1 -1
- dub/models/errors/conflict.py +1 -1
- dub/models/errors/duberror.py +1 -1
- dub/models/errors/forbidden.py +1 -1
- dub/models/errors/internalservererror.py +1 -1
- dub/models/errors/inviteexpired.py +1 -1
- dub/models/errors/no_response_error.py +1 -1
- dub/models/errors/notfound.py +1 -1
- dub/models/errors/ratelimitexceeded.py +1 -1
- dub/models/errors/responsevalidationerror.py +1 -1
- dub/models/errors/sdkerror.py +1 -1
- dub/models/errors/unauthorized.py +1 -1
- dub/models/errors/unprocessableentity.py +1 -1
- dub/models/operations/__init__.py +17 -35
- dub/models/operations/banpartner.py +83 -0
- dub/models/operations/bulkcreatelinks.py +2 -2
- dub/models/operations/createfolder.py +8 -3
- dub/models/operations/createlink.py +2 -2
- dub/models/operations/createpartner.py +93 -29
- dub/models/operations/listcommissions.py +13 -2
- dub/models/operations/listevents.py +10 -0
- dub/models/operations/listpartners.py +107 -47
- dub/models/operations/retrieveanalytics.py +16 -1
- dub/models/operations/retrievelinks.py +42 -7
- dub/models/operations/retrievepartneranalytics.py +51 -11
- dub/models/operations/tracklead.py +2 -2
- dub/models/operations/updatecommission.py +7 -2
- dub/models/operations/updatefolder.py +8 -3
- dub/models/operations/updatelink.py +2 -2
- dub/models/operations/upsertlink.py +2 -2
- dub/partners.py +310 -36
- dub/qr_codes.py +4 -4
- dub/tags.py +24 -32
- dub/track.py +12 -20
- dub/utils/retries.py +69 -5
- dub/utils/unmarshal_json_response.py +15 -1
- dub/workspaces.py +12 -20
- {dub-0.31.0.dist-info → dub-0.33.0.dist-info}/METADATA +2 -21
- {dub-0.31.0.dist-info → dub-0.33.0.dist-info}/RECORD +67 -66
- dub/models/operations/createcustomer.py +0 -382
- {dub-0.31.0.dist-info → dub-0.33.0.dist-info}/WHEEL +0 -0
- {dub-0.31.0.dist-info → dub-0.33.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
|
|
5
|
+
from enum import Enum
|
|
6
|
+
import pydantic
|
|
7
|
+
from pydantic import model_serializer
|
|
8
|
+
from typing import List
|
|
9
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PartnerApplicationSubmittedEventEvent(str, Enum):
|
|
13
|
+
PARTNER_APPLICATION_SUBMITTED = "partner.application_submitted"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PartnerApplicationSubmittedEventStatus(str, Enum):
|
|
17
|
+
r"""The status of the partner's enrollment in the program."""
|
|
18
|
+
|
|
19
|
+
PENDING = "pending"
|
|
20
|
+
APPROVED = "approved"
|
|
21
|
+
REJECTED = "rejected"
|
|
22
|
+
INVITED = "invited"
|
|
23
|
+
DECLINED = "declined"
|
|
24
|
+
DEACTIVATED = "deactivated"
|
|
25
|
+
BANNED = "banned"
|
|
26
|
+
ARCHIVED = "archived"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PartnerApplicationSubmittedEventPartnerTypedDict(TypedDict):
|
|
30
|
+
id: str
|
|
31
|
+
r"""The partner's unique ID on Dub."""
|
|
32
|
+
name: str
|
|
33
|
+
r"""The partner's full legal name."""
|
|
34
|
+
company_name: Nullable[str]
|
|
35
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
36
|
+
email: Nullable[str]
|
|
37
|
+
r"""The partner's email address. Should be a unique value across Dub."""
|
|
38
|
+
image: Nullable[str]
|
|
39
|
+
r"""The partner's avatar image."""
|
|
40
|
+
country: Nullable[str]
|
|
41
|
+
r"""The partner's country (required for tax purposes)."""
|
|
42
|
+
status: PartnerApplicationSubmittedEventStatus
|
|
43
|
+
r"""The status of the partner's enrollment in the program."""
|
|
44
|
+
description: NotRequired[Nullable[str]]
|
|
45
|
+
r"""A brief description of the partner and their background."""
|
|
46
|
+
group_id: NotRequired[Nullable[str]]
|
|
47
|
+
r"""The partner's group ID on Dub."""
|
|
48
|
+
website: NotRequired[Nullable[str]]
|
|
49
|
+
r"""The partner's website URL (including the https protocol)."""
|
|
50
|
+
youtube: NotRequired[Nullable[str]]
|
|
51
|
+
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
52
|
+
twitter: NotRequired[Nullable[str]]
|
|
53
|
+
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
54
|
+
linkedin: NotRequired[Nullable[str]]
|
|
55
|
+
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
56
|
+
instagram: NotRequired[Nullable[str]]
|
|
57
|
+
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
58
|
+
tiktok: NotRequired[Nullable[str]]
|
|
59
|
+
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class PartnerApplicationSubmittedEventPartner(BaseModel):
|
|
63
|
+
id: str
|
|
64
|
+
r"""The partner's unique ID on Dub."""
|
|
65
|
+
|
|
66
|
+
name: str
|
|
67
|
+
r"""The partner's full legal name."""
|
|
68
|
+
|
|
69
|
+
company_name: Annotated[Nullable[str], pydantic.Field(alias="companyName")]
|
|
70
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
71
|
+
|
|
72
|
+
email: Nullable[str]
|
|
73
|
+
r"""The partner's email address. Should be a unique value across Dub."""
|
|
74
|
+
|
|
75
|
+
image: Nullable[str]
|
|
76
|
+
r"""The partner's avatar image."""
|
|
77
|
+
|
|
78
|
+
country: Nullable[str]
|
|
79
|
+
r"""The partner's country (required for tax purposes)."""
|
|
80
|
+
|
|
81
|
+
status: PartnerApplicationSubmittedEventStatus
|
|
82
|
+
r"""The status of the partner's enrollment in the program."""
|
|
83
|
+
|
|
84
|
+
description: OptionalNullable[str] = UNSET
|
|
85
|
+
r"""A brief description of the partner and their background."""
|
|
86
|
+
|
|
87
|
+
group_id: Annotated[OptionalNullable[str], pydantic.Field(alias="groupId")] = UNSET
|
|
88
|
+
r"""The partner's group ID on Dub."""
|
|
89
|
+
|
|
90
|
+
website: OptionalNullable[str] = UNSET
|
|
91
|
+
r"""The partner's website URL (including the https protocol)."""
|
|
92
|
+
|
|
93
|
+
youtube: OptionalNullable[str] = UNSET
|
|
94
|
+
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
95
|
+
|
|
96
|
+
twitter: OptionalNullable[str] = UNSET
|
|
97
|
+
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
98
|
+
|
|
99
|
+
linkedin: OptionalNullable[str] = UNSET
|
|
100
|
+
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
101
|
+
|
|
102
|
+
instagram: OptionalNullable[str] = UNSET
|
|
103
|
+
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
104
|
+
|
|
105
|
+
tiktok: OptionalNullable[str] = UNSET
|
|
106
|
+
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
107
|
+
|
|
108
|
+
@model_serializer(mode="wrap")
|
|
109
|
+
def serialize_model(self, handler):
|
|
110
|
+
optional_fields = [
|
|
111
|
+
"description",
|
|
112
|
+
"groupId",
|
|
113
|
+
"website",
|
|
114
|
+
"youtube",
|
|
115
|
+
"twitter",
|
|
116
|
+
"linkedin",
|
|
117
|
+
"instagram",
|
|
118
|
+
"tiktok",
|
|
119
|
+
]
|
|
120
|
+
nullable_fields = [
|
|
121
|
+
"companyName",
|
|
122
|
+
"email",
|
|
123
|
+
"image",
|
|
124
|
+
"description",
|
|
125
|
+
"country",
|
|
126
|
+
"groupId",
|
|
127
|
+
"website",
|
|
128
|
+
"youtube",
|
|
129
|
+
"twitter",
|
|
130
|
+
"linkedin",
|
|
131
|
+
"instagram",
|
|
132
|
+
"tiktok",
|
|
133
|
+
]
|
|
134
|
+
null_default_fields = []
|
|
135
|
+
|
|
136
|
+
serialized = handler(self)
|
|
137
|
+
|
|
138
|
+
m = {}
|
|
139
|
+
|
|
140
|
+
for n, f in type(self).model_fields.items():
|
|
141
|
+
k = f.alias or n
|
|
142
|
+
val = serialized.get(k)
|
|
143
|
+
serialized.pop(k, None)
|
|
144
|
+
|
|
145
|
+
optional_nullable = k in optional_fields and k in nullable_fields
|
|
146
|
+
is_set = (
|
|
147
|
+
self.__pydantic_fields_set__.intersection({n})
|
|
148
|
+
or k in null_default_fields
|
|
149
|
+
) # pylint: disable=no-member
|
|
150
|
+
|
|
151
|
+
if val is not None and val != UNSET_SENTINEL:
|
|
152
|
+
m[k] = val
|
|
153
|
+
elif val != UNSET_SENTINEL and (
|
|
154
|
+
not k in optional_fields or (optional_nullable and is_set)
|
|
155
|
+
):
|
|
156
|
+
m[k] = val
|
|
157
|
+
|
|
158
|
+
return m
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ApplicationFormDataTypedDict(TypedDict):
|
|
162
|
+
label: str
|
|
163
|
+
value: Nullable[str]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class ApplicationFormData(BaseModel):
|
|
167
|
+
label: str
|
|
168
|
+
|
|
169
|
+
value: Nullable[str]
|
|
170
|
+
|
|
171
|
+
@model_serializer(mode="wrap")
|
|
172
|
+
def serialize_model(self, handler):
|
|
173
|
+
optional_fields = []
|
|
174
|
+
nullable_fields = ["value"]
|
|
175
|
+
null_default_fields = []
|
|
176
|
+
|
|
177
|
+
serialized = handler(self)
|
|
178
|
+
|
|
179
|
+
m = {}
|
|
180
|
+
|
|
181
|
+
for n, f in type(self).model_fields.items():
|
|
182
|
+
k = f.alias or n
|
|
183
|
+
val = serialized.get(k)
|
|
184
|
+
serialized.pop(k, None)
|
|
185
|
+
|
|
186
|
+
optional_nullable = k in optional_fields and k in nullable_fields
|
|
187
|
+
is_set = (
|
|
188
|
+
self.__pydantic_fields_set__.intersection({n})
|
|
189
|
+
or k in null_default_fields
|
|
190
|
+
) # pylint: disable=no-member
|
|
191
|
+
|
|
192
|
+
if val is not None and val != UNSET_SENTINEL:
|
|
193
|
+
m[k] = val
|
|
194
|
+
elif val != UNSET_SENTINEL and (
|
|
195
|
+
not k in optional_fields or (optional_nullable and is_set)
|
|
196
|
+
):
|
|
197
|
+
m[k] = val
|
|
198
|
+
|
|
199
|
+
return m
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class PartnerApplicationSubmittedEventDataTypedDict(TypedDict):
|
|
203
|
+
id: str
|
|
204
|
+
created_at: str
|
|
205
|
+
partner: PartnerApplicationSubmittedEventPartnerTypedDict
|
|
206
|
+
application_form_data: Nullable[List[ApplicationFormDataTypedDict]]
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class PartnerApplicationSubmittedEventData(BaseModel):
|
|
210
|
+
id: str
|
|
211
|
+
|
|
212
|
+
created_at: Annotated[str, pydantic.Field(alias="createdAt")]
|
|
213
|
+
|
|
214
|
+
partner: PartnerApplicationSubmittedEventPartner
|
|
215
|
+
|
|
216
|
+
application_form_data: Annotated[
|
|
217
|
+
Nullable[List[ApplicationFormData]], pydantic.Field(alias="applicationFormData")
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
@model_serializer(mode="wrap")
|
|
221
|
+
def serialize_model(self, handler):
|
|
222
|
+
optional_fields = []
|
|
223
|
+
nullable_fields = ["applicationFormData"]
|
|
224
|
+
null_default_fields = []
|
|
225
|
+
|
|
226
|
+
serialized = handler(self)
|
|
227
|
+
|
|
228
|
+
m = {}
|
|
229
|
+
|
|
230
|
+
for n, f in type(self).model_fields.items():
|
|
231
|
+
k = f.alias or n
|
|
232
|
+
val = serialized.get(k)
|
|
233
|
+
serialized.pop(k, None)
|
|
234
|
+
|
|
235
|
+
optional_nullable = k in optional_fields and k in nullable_fields
|
|
236
|
+
is_set = (
|
|
237
|
+
self.__pydantic_fields_set__.intersection({n})
|
|
238
|
+
or k in null_default_fields
|
|
239
|
+
) # pylint: disable=no-member
|
|
240
|
+
|
|
241
|
+
if val is not None and val != UNSET_SENTINEL:
|
|
242
|
+
m[k] = val
|
|
243
|
+
elif val != UNSET_SENTINEL and (
|
|
244
|
+
not k in optional_fields or (optional_nullable and is_set)
|
|
245
|
+
):
|
|
246
|
+
m[k] = val
|
|
247
|
+
|
|
248
|
+
return m
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class PartnerApplicationSubmittedEventTypedDict(TypedDict):
|
|
252
|
+
r"""Triggered when a partner submits an application to join a program."""
|
|
253
|
+
|
|
254
|
+
id: str
|
|
255
|
+
event: PartnerApplicationSubmittedEventEvent
|
|
256
|
+
created_at: str
|
|
257
|
+
data: PartnerApplicationSubmittedEventDataTypedDict
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class PartnerApplicationSubmittedEvent(BaseModel):
|
|
261
|
+
r"""Triggered when a partner submits an application to join a program."""
|
|
262
|
+
|
|
263
|
+
id: str
|
|
264
|
+
|
|
265
|
+
event: PartnerApplicationSubmittedEventEvent
|
|
266
|
+
|
|
267
|
+
created_at: Annotated[str, pydantic.Field(alias="createdAt")]
|
|
268
|
+
|
|
269
|
+
data: PartnerApplicationSubmittedEventData
|
|
@@ -111,6 +111,8 @@ class PartnerEnrolledEventDataTypedDict(TypedDict):
|
|
|
111
111
|
r"""The partner's Stripe Connect ID (for receiving payouts via Stripe)."""
|
|
112
112
|
payouts_enabled_at: Nullable[str]
|
|
113
113
|
r"""The date when the partner enabled payouts."""
|
|
114
|
+
trusted_at: Nullable[str]
|
|
115
|
+
r"""The date when the partner received the trusted badge in the partner network."""
|
|
114
116
|
program_id: str
|
|
115
117
|
r"""The program's unique ID on Dub."""
|
|
116
118
|
partner_id: str
|
|
@@ -127,7 +129,7 @@ class PartnerEnrolledEventDataTypedDict(TypedDict):
|
|
|
127
129
|
group_id: NotRequired[Nullable[str]]
|
|
128
130
|
r"""The partner's group ID on Dub."""
|
|
129
131
|
total_commissions: NotRequired[float]
|
|
130
|
-
r"""The total commissions paid to the partner for their referrals
|
|
132
|
+
r"""The total commissions paid to the partner for their referrals"""
|
|
131
133
|
click_reward_id: NotRequired[Nullable[str]]
|
|
132
134
|
lead_reward_id: NotRequired[Nullable[str]]
|
|
133
135
|
sale_reward_id: NotRequired[Nullable[str]]
|
|
@@ -138,18 +140,30 @@ class PartnerEnrolledEventDataTypedDict(TypedDict):
|
|
|
138
140
|
r"""If the partner was banned from the program, this is the date of the ban."""
|
|
139
141
|
banned_reason: NotRequired[Nullable[BannedReason]]
|
|
140
142
|
r"""If the partner was banned from the program, this is the reason for the ban."""
|
|
141
|
-
|
|
142
|
-
r"""The total number of clicks on the partner's links
|
|
143
|
-
|
|
144
|
-
r"""The total number of leads generated by the partner's links
|
|
145
|
-
|
|
146
|
-
r"""The total number of leads that converted to paying customers
|
|
147
|
-
|
|
148
|
-
r"""The total number of sales generated by the partner's links (includes recurring sales)
|
|
149
|
-
|
|
150
|
-
r"""
|
|
143
|
+
total_clicks: NotRequired[float]
|
|
144
|
+
r"""The total number of clicks on the partner's links"""
|
|
145
|
+
total_leads: NotRequired[float]
|
|
146
|
+
r"""The total number of leads generated by the partner's links"""
|
|
147
|
+
total_conversions: NotRequired[float]
|
|
148
|
+
r"""The total number of leads that converted to paying customers"""
|
|
149
|
+
total_sales: NotRequired[float]
|
|
150
|
+
r"""The total number of sales generated by the partner's links (includes recurring sales)"""
|
|
151
|
+
total_sale_amount: NotRequired[float]
|
|
152
|
+
r"""Total revenue generated by the partner's links"""
|
|
151
153
|
net_revenue: NotRequired[float]
|
|
152
|
-
r"""
|
|
154
|
+
r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
|
|
155
|
+
earnings_per_click: NotRequired[Nullable[float]]
|
|
156
|
+
r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
|
|
157
|
+
average_lifetime_value: NotRequired[Nullable[float]]
|
|
158
|
+
r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
|
|
159
|
+
click_to_lead_rate: NotRequired[Nullable[float]]
|
|
160
|
+
r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
|
|
161
|
+
click_to_conversion_rate: NotRequired[Nullable[float]]
|
|
162
|
+
r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
|
|
163
|
+
lead_to_conversion_rate: NotRequired[Nullable[float]]
|
|
164
|
+
r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
|
|
165
|
+
return_on_ad_spend: NotRequired[Nullable[float]]
|
|
166
|
+
r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
|
|
153
167
|
website: NotRequired[Nullable[str]]
|
|
154
168
|
r"""The partner's website URL (including the https protocol)."""
|
|
155
169
|
youtube: NotRequired[Nullable[str]]
|
|
@@ -194,6 +208,9 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
194
208
|
]
|
|
195
209
|
r"""The date when the partner enabled payouts."""
|
|
196
210
|
|
|
211
|
+
trusted_at: Annotated[Nullable[str], pydantic.Field(alias="trustedAt")]
|
|
212
|
+
r"""The date when the partner received the trusted badge in the partner network."""
|
|
213
|
+
|
|
197
214
|
program_id: Annotated[str, pydantic.Field(alias="programId")]
|
|
198
215
|
r"""The program's unique ID on Dub."""
|
|
199
216
|
|
|
@@ -220,7 +237,7 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
220
237
|
total_commissions: Annotated[
|
|
221
238
|
Optional[float], pydantic.Field(alias="totalCommissions")
|
|
222
239
|
] = 0
|
|
223
|
-
r"""The total commissions paid to the partner for their referrals
|
|
240
|
+
r"""The total commissions paid to the partner for their referrals"""
|
|
224
241
|
|
|
225
242
|
click_reward_id: Annotated[
|
|
226
243
|
OptionalNullable[str], pydantic.Field(alias="clickRewardId")
|
|
@@ -253,23 +270,57 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
253
270
|
] = UNSET
|
|
254
271
|
r"""If the partner was banned from the program, this is the reason for the ban."""
|
|
255
272
|
|
|
256
|
-
|
|
257
|
-
r"""The total number of clicks on the partner's links
|
|
273
|
+
total_clicks: Annotated[Optional[float], pydantic.Field(alias="totalClicks")] = 0
|
|
274
|
+
r"""The total number of clicks on the partner's links"""
|
|
258
275
|
|
|
259
|
-
|
|
260
|
-
r"""The total number of leads generated by the partner's links
|
|
276
|
+
total_leads: Annotated[Optional[float], pydantic.Field(alias="totalLeads")] = 0
|
|
277
|
+
r"""The total number of leads generated by the partner's links"""
|
|
261
278
|
|
|
262
|
-
|
|
263
|
-
|
|
279
|
+
total_conversions: Annotated[
|
|
280
|
+
Optional[float], pydantic.Field(alias="totalConversions")
|
|
281
|
+
] = 0
|
|
282
|
+
r"""The total number of leads that converted to paying customers"""
|
|
264
283
|
|
|
265
|
-
|
|
266
|
-
r"""The total number of sales generated by the partner's links (includes recurring sales)
|
|
284
|
+
total_sales: Annotated[Optional[float], pydantic.Field(alias="totalSales")] = 0
|
|
285
|
+
r"""The total number of sales generated by the partner's links (includes recurring sales)"""
|
|
267
286
|
|
|
268
|
-
|
|
269
|
-
|
|
287
|
+
total_sale_amount: Annotated[
|
|
288
|
+
Optional[float], pydantic.Field(alias="totalSaleAmount")
|
|
289
|
+
] = 0
|
|
290
|
+
r"""Total revenue generated by the partner's links"""
|
|
270
291
|
|
|
271
292
|
net_revenue: Annotated[Optional[float], pydantic.Field(alias="netRevenue")] = 0
|
|
272
|
-
r"""
|
|
293
|
+
r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
|
|
294
|
+
|
|
295
|
+
earnings_per_click: Annotated[
|
|
296
|
+
OptionalNullable[float], pydantic.Field(alias="earningsPerClick")
|
|
297
|
+
] = UNSET
|
|
298
|
+
r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
|
|
299
|
+
|
|
300
|
+
average_lifetime_value: Annotated[
|
|
301
|
+
OptionalNullable[float], pydantic.Field(alias="averageLifetimeValue")
|
|
302
|
+
] = UNSET
|
|
303
|
+
r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
|
|
304
|
+
|
|
305
|
+
click_to_lead_rate: Annotated[
|
|
306
|
+
OptionalNullable[float], pydantic.Field(alias="clickToLeadRate")
|
|
307
|
+
] = UNSET
|
|
308
|
+
r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
|
|
309
|
+
|
|
310
|
+
click_to_conversion_rate: Annotated[
|
|
311
|
+
OptionalNullable[float], pydantic.Field(alias="clickToConversionRate")
|
|
312
|
+
] = UNSET
|
|
313
|
+
r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
|
|
314
|
+
|
|
315
|
+
lead_to_conversion_rate: Annotated[
|
|
316
|
+
OptionalNullable[float], pydantic.Field(alias="leadToConversionRate")
|
|
317
|
+
] = UNSET
|
|
318
|
+
r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
|
|
319
|
+
|
|
320
|
+
return_on_ad_spend: Annotated[
|
|
321
|
+
OptionalNullable[float], pydantic.Field(alias="returnOnAdSpend")
|
|
322
|
+
] = UNSET
|
|
323
|
+
r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
|
|
273
324
|
|
|
274
325
|
website: OptionalNullable[str] = UNSET
|
|
275
326
|
r"""The partner's website URL (including the https protocol)."""
|
|
@@ -302,12 +353,18 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
302
353
|
"applicationId",
|
|
303
354
|
"bannedAt",
|
|
304
355
|
"bannedReason",
|
|
305
|
-
"
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"
|
|
356
|
+
"totalClicks",
|
|
357
|
+
"totalLeads",
|
|
358
|
+
"totalConversions",
|
|
359
|
+
"totalSales",
|
|
360
|
+
"totalSaleAmount",
|
|
310
361
|
"netRevenue",
|
|
362
|
+
"earningsPerClick",
|
|
363
|
+
"averageLifetimeValue",
|
|
364
|
+
"clickToLeadRate",
|
|
365
|
+
"clickToConversionRate",
|
|
366
|
+
"leadToConversionRate",
|
|
367
|
+
"returnOnAdSpend",
|
|
311
368
|
"website",
|
|
312
369
|
"youtube",
|
|
313
370
|
"twitter",
|
|
@@ -324,6 +381,7 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
324
381
|
"paypalEmail",
|
|
325
382
|
"stripeConnectId",
|
|
326
383
|
"payoutsEnabledAt",
|
|
384
|
+
"trustedAt",
|
|
327
385
|
"groupId",
|
|
328
386
|
"tenantId",
|
|
329
387
|
"links",
|
|
@@ -334,6 +392,12 @@ class PartnerEnrolledEventData(BaseModel):
|
|
|
334
392
|
"applicationId",
|
|
335
393
|
"bannedAt",
|
|
336
394
|
"bannedReason",
|
|
395
|
+
"earningsPerClick",
|
|
396
|
+
"averageLifetimeValue",
|
|
397
|
+
"clickToLeadRate",
|
|
398
|
+
"clickToConversionRate",
|
|
399
|
+
"leadToConversionRate",
|
|
400
|
+
"returnOnAdSpend",
|
|
337
401
|
"website",
|
|
338
402
|
"youtube",
|
|
339
403
|
"twitter",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from .
|
|
4
|
+
from .linktagschema import LinkTagSchema, LinkTagSchemaTypedDict
|
|
5
5
|
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
|
|
6
6
|
from enum import Enum
|
|
7
7
|
import pydantic
|
|
@@ -207,6 +207,7 @@ class SaleCreatedEventLinkTypedDict(TypedDict):
|
|
|
207
207
|
archived: bool
|
|
208
208
|
expires_at: str
|
|
209
209
|
expired_url: Nullable[str]
|
|
210
|
+
disabled_at: str
|
|
210
211
|
password: Nullable[str]
|
|
211
212
|
r"""The password required to access the destination URL of the short link."""
|
|
212
213
|
proxy: bool
|
|
@@ -227,7 +228,7 @@ class SaleCreatedEventLinkTypedDict(TypedDict):
|
|
|
227
228
|
geo: Nullable[Dict[str, str]]
|
|
228
229
|
r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
|
|
229
230
|
public_stats: bool
|
|
230
|
-
tags: Nullable[List[
|
|
231
|
+
tags: Nullable[List[LinkTagSchemaTypedDict]]
|
|
231
232
|
r"""The tags assigned to the short link."""
|
|
232
233
|
folder_id: Nullable[str]
|
|
233
234
|
r"""The unique ID of the folder assigned to the short link."""
|
|
@@ -249,8 +250,8 @@ class SaleCreatedEventLinkTypedDict(TypedDict):
|
|
|
249
250
|
r"""The UTM term of the short link."""
|
|
250
251
|
utm_content: Nullable[str]
|
|
251
252
|
r"""The UTM content of the short link."""
|
|
252
|
-
test_started_at:
|
|
253
|
-
test_completed_at:
|
|
253
|
+
test_started_at: str
|
|
254
|
+
test_completed_at: str
|
|
254
255
|
user_id: Nullable[str]
|
|
255
256
|
workspace_id: str
|
|
256
257
|
r"""The workspace ID of the short link."""
|
|
@@ -307,6 +308,8 @@ class SaleCreatedEventLink(BaseModel):
|
|
|
307
308
|
|
|
308
309
|
expired_url: Annotated[Nullable[str], pydantic.Field(alias="expiredUrl")]
|
|
309
310
|
|
|
311
|
+
disabled_at: Annotated[str, pydantic.Field(alias="disabledAt")]
|
|
312
|
+
|
|
310
313
|
password: Nullable[str]
|
|
311
314
|
r"""The password required to access the destination URL of the short link."""
|
|
312
315
|
|
|
@@ -339,7 +342,7 @@ class SaleCreatedEventLink(BaseModel):
|
|
|
339
342
|
|
|
340
343
|
public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
|
|
341
344
|
|
|
342
|
-
tags: Nullable[List[
|
|
345
|
+
tags: Nullable[List[LinkTagSchema]]
|
|
343
346
|
r"""The tags assigned to the short link."""
|
|
344
347
|
|
|
345
348
|
folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]
|
|
@@ -372,9 +375,9 @@ class SaleCreatedEventLink(BaseModel):
|
|
|
372
375
|
utm_content: Nullable[str]
|
|
373
376
|
r"""The UTM content of the short link."""
|
|
374
377
|
|
|
375
|
-
test_started_at: Annotated[
|
|
378
|
+
test_started_at: Annotated[str, pydantic.Field(alias="testStartedAt")]
|
|
376
379
|
|
|
377
|
-
test_completed_at: Annotated[
|
|
380
|
+
test_completed_at: Annotated[str, pydantic.Field(alias="testCompletedAt")]
|
|
378
381
|
|
|
379
382
|
user_id: Annotated[Nullable[str], pydantic.Field(alias="userId")]
|
|
380
383
|
|
|
@@ -459,8 +462,6 @@ class SaleCreatedEventLink(BaseModel):
|
|
|
459
462
|
"utm_term",
|
|
460
463
|
"utm_content",
|
|
461
464
|
"testVariants",
|
|
462
|
-
"testStartedAt",
|
|
463
|
-
"testCompletedAt",
|
|
464
465
|
"userId",
|
|
465
466
|
"tagId",
|
|
466
467
|
]
|
|
@@ -557,6 +558,7 @@ class SaleCreatedEventPartnerTypedDict(TypedDict):
|
|
|
557
558
|
total_sales: float
|
|
558
559
|
total_sale_amount: float
|
|
559
560
|
total_commissions: float
|
|
561
|
+
group_id: NotRequired[Nullable[str]]
|
|
560
562
|
|
|
561
563
|
|
|
562
564
|
class SaleCreatedEventPartner(BaseModel):
|
|
@@ -592,10 +594,12 @@ class SaleCreatedEventPartner(BaseModel):
|
|
|
592
594
|
|
|
593
595
|
total_commissions: Annotated[float, pydantic.Field(alias="totalCommissions")]
|
|
594
596
|
|
|
597
|
+
group_id: Annotated[OptionalNullable[str], pydantic.Field(alias="groupId")] = UNSET
|
|
598
|
+
|
|
595
599
|
@model_serializer(mode="wrap")
|
|
596
600
|
def serialize_model(self, handler):
|
|
597
|
-
optional_fields = []
|
|
598
|
-
nullable_fields = ["email", "image", "payoutsEnabledAt", "country"]
|
|
601
|
+
optional_fields = ["groupId"]
|
|
602
|
+
nullable_fields = ["email", "image", "payoutsEnabledAt", "country", "groupId"]
|
|
599
603
|
null_default_fields = []
|
|
600
604
|
|
|
601
605
|
serialized = handler(self)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from .
|
|
4
|
+
from .linktagschema import LinkTagSchema, LinkTagSchemaTypedDict
|
|
5
5
|
from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
|
|
6
6
|
from enum import Enum
|
|
7
7
|
import pydantic
|
|
@@ -110,6 +110,7 @@ class SaleEventLinkTypedDict(TypedDict):
|
|
|
110
110
|
archived: bool
|
|
111
111
|
expires_at: str
|
|
112
112
|
expired_url: Nullable[str]
|
|
113
|
+
disabled_at: str
|
|
113
114
|
password: Nullable[str]
|
|
114
115
|
r"""The password required to access the destination URL of the short link."""
|
|
115
116
|
proxy: bool
|
|
@@ -130,7 +131,7 @@ class SaleEventLinkTypedDict(TypedDict):
|
|
|
130
131
|
geo: Nullable[Dict[str, str]]
|
|
131
132
|
r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
|
|
132
133
|
public_stats: bool
|
|
133
|
-
tags: Nullable[List[
|
|
134
|
+
tags: Nullable[List[LinkTagSchemaTypedDict]]
|
|
134
135
|
r"""The tags assigned to the short link."""
|
|
135
136
|
folder_id: Nullable[str]
|
|
136
137
|
r"""The unique ID of the folder assigned to the short link."""
|
|
@@ -152,8 +153,8 @@ class SaleEventLinkTypedDict(TypedDict):
|
|
|
152
153
|
r"""The UTM term of the short link."""
|
|
153
154
|
utm_content: Nullable[str]
|
|
154
155
|
r"""The UTM content of the short link."""
|
|
155
|
-
test_started_at:
|
|
156
|
-
test_completed_at:
|
|
156
|
+
test_started_at: str
|
|
157
|
+
test_completed_at: str
|
|
157
158
|
user_id: Nullable[str]
|
|
158
159
|
workspace_id: str
|
|
159
160
|
r"""The workspace ID of the short link."""
|
|
@@ -210,6 +211,8 @@ class SaleEventLink(BaseModel):
|
|
|
210
211
|
|
|
211
212
|
expired_url: Annotated[Nullable[str], pydantic.Field(alias="expiredUrl")]
|
|
212
213
|
|
|
214
|
+
disabled_at: Annotated[str, pydantic.Field(alias="disabledAt")]
|
|
215
|
+
|
|
213
216
|
password: Nullable[str]
|
|
214
217
|
r"""The password required to access the destination URL of the short link."""
|
|
215
218
|
|
|
@@ -242,7 +245,7 @@ class SaleEventLink(BaseModel):
|
|
|
242
245
|
|
|
243
246
|
public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
|
|
244
247
|
|
|
245
|
-
tags: Nullable[List[
|
|
248
|
+
tags: Nullable[List[LinkTagSchema]]
|
|
246
249
|
r"""The tags assigned to the short link."""
|
|
247
250
|
|
|
248
251
|
folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]
|
|
@@ -275,9 +278,9 @@ class SaleEventLink(BaseModel):
|
|
|
275
278
|
utm_content: Nullable[str]
|
|
276
279
|
r"""The UTM content of the short link."""
|
|
277
280
|
|
|
278
|
-
test_started_at: Annotated[
|
|
281
|
+
test_started_at: Annotated[str, pydantic.Field(alias="testStartedAt")]
|
|
279
282
|
|
|
280
|
-
test_completed_at: Annotated[
|
|
283
|
+
test_completed_at: Annotated[str, pydantic.Field(alias="testCompletedAt")]
|
|
281
284
|
|
|
282
285
|
user_id: Annotated[Nullable[str], pydantic.Field(alias="userId")]
|
|
283
286
|
|
|
@@ -362,8 +365,6 @@ class SaleEventLink(BaseModel):
|
|
|
362
365
|
"utm_term",
|
|
363
366
|
"utm_content",
|
|
364
367
|
"testVariants",
|
|
365
|
-
"testStartedAt",
|
|
366
|
-
"testCompletedAt",
|
|
367
368
|
"userId",
|
|
368
369
|
"tagId",
|
|
369
370
|
]
|
|
@@ -8,6 +8,10 @@ from .commissioncreatedevent import (
|
|
|
8
8
|
from .leadcreatedevent import LeadCreatedEvent, LeadCreatedEventTypedDict
|
|
9
9
|
from .linkclickedevent import LinkClickedEvent, LinkClickedEventTypedDict
|
|
10
10
|
from .linkwebhookevent import LinkWebhookEvent, LinkWebhookEventTypedDict
|
|
11
|
+
from .partnerapplicationsubmittedevent import (
|
|
12
|
+
PartnerApplicationSubmittedEvent,
|
|
13
|
+
PartnerApplicationSubmittedEventTypedDict,
|
|
14
|
+
)
|
|
11
15
|
from .partnerenrolledevent import PartnerEnrolledEvent, PartnerEnrolledEventTypedDict
|
|
12
16
|
from .salecreatedevent import SaleCreatedEvent, SaleCreatedEventTypedDict
|
|
13
17
|
from typing import Union
|
|
@@ -22,6 +26,7 @@ WebhookEventTypedDict = TypeAliasType(
|
|
|
22
26
|
LeadCreatedEventTypedDict,
|
|
23
27
|
SaleCreatedEventTypedDict,
|
|
24
28
|
PartnerEnrolledEventTypedDict,
|
|
29
|
+
PartnerApplicationSubmittedEventTypedDict,
|
|
25
30
|
CommissionCreatedEventTypedDict,
|
|
26
31
|
],
|
|
27
32
|
)
|
|
@@ -36,6 +41,7 @@ WebhookEvent = TypeAliasType(
|
|
|
36
41
|
LeadCreatedEvent,
|
|
37
42
|
SaleCreatedEvent,
|
|
38
43
|
PartnerEnrolledEvent,
|
|
44
|
+
PartnerApplicationSubmittedEvent,
|
|
39
45
|
CommissionCreatedEvent,
|
|
40
46
|
],
|
|
41
47
|
)
|