dub 0.33.0__py3-none-any.whl → 0.34.1__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.
Files changed (65) hide show
  1. dub/_version.py +3 -3
  2. dub/analytics.py +2 -0
  3. dub/basesdk.py +6 -0
  4. dub/bounties.py +841 -0
  5. dub/commissions.py +4 -0
  6. dub/customers.py +8 -0
  7. dub/domains.py +12 -0
  8. dub/embed_tokens.py +2 -0
  9. dub/events.py +2 -0
  10. dub/folders.py +8 -0
  11. dub/links.py +20 -0
  12. dub/models/components/__init__.py +55 -149
  13. dub/models/components/commissioncreatedevent.py +29 -1
  14. dub/models/components/leadcreatedevent.py +8 -8
  15. dub/models/components/linkclickedevent.py +12 -12
  16. dub/models/components/linkerrorschema.py +12 -12
  17. dub/models/components/linkschema.py +3 -3
  18. dub/models/components/linktagschema.py +3 -3
  19. dub/models/components/linktagschemaoutput.py +38 -0
  20. dub/models/components/linkwebhookevent.py +8 -10
  21. dub/models/components/partnerenrolledevent.py +4 -4
  22. dub/models/components/salecreatedevent.py +8 -8
  23. dub/models/operations/__init__.py +223 -22
  24. dub/models/operations/approvebountysubmission.py +185 -0
  25. dub/models/operations/createpartner.py +4 -55
  26. dub/models/operations/createpartnerlink.py +0 -51
  27. dub/models/operations/createreferralsembedtoken.py +0 -51
  28. dub/models/operations/getcustomers.py +18 -0
  29. dub/models/operations/getlinkinfo.py +0 -2
  30. dub/models/operations/getlinks.py +2 -2
  31. dub/models/operations/getlinkscount.py +2 -2
  32. dub/models/operations/getqrcode.py +1 -1
  33. dub/models/operations/listbountysubmissions.py +212 -0
  34. dub/models/operations/listdomains.py +1 -1
  35. dub/models/operations/listevents.py +2016 -21
  36. dub/models/operations/listpartners.py +4 -4
  37. dub/models/operations/rejectbountysubmission.py +174 -0
  38. dub/models/operations/retrieveanalytics.py +16 -5
  39. dub/models/operations/retrievelinks.py +2 -2
  40. dub/models/operations/tracklead.py +4 -4
  41. dub/models/operations/updatecustomer.py +23 -11
  42. dub/models/operations/updatelink.py +0 -2
  43. dub/models/operations/updateworkspace.py +3 -3
  44. dub/models/operations/upsertpartnerlink.py +7 -65
  45. dub/partners.py +22 -4
  46. dub/qr_codes.py +2 -0
  47. dub/sdk.py +3 -0
  48. dub/tags.py +24 -12
  49. dub/track.py +4 -0
  50. dub/types/basemodel.py +41 -3
  51. dub/utils/__init__.py +0 -3
  52. dub/utils/enums.py +60 -0
  53. dub/utils/forms.py +21 -10
  54. dub/utils/queryparams.py +14 -2
  55. dub/utils/requestbodies.py +3 -3
  56. dub/utils/serializers.py +0 -20
  57. dub/workspaces.py +4 -0
  58. {dub-0.33.0.dist-info → dub-0.34.1.dist-info}/METADATA +20 -14
  59. {dub-0.33.0.dist-info → dub-0.34.1.dist-info}/RECORD +61 -60
  60. dub/models/components/clickevent.py +0 -557
  61. dub/models/components/continentcode.py +0 -16
  62. dub/models/components/leadevent.py +0 -681
  63. dub/models/components/saleevent.py +0 -780
  64. {dub-0.33.0.dist-info → dub-0.34.1.dist-info}/WHEEL +0 -0
  65. {dub-0.33.0.dist-info → dub-0.34.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,18 +1,13 @@
1
1
  """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
2
 
3
3
  from __future__ import annotations
4
- from dub.models.components import (
5
- clickevent as components_clickevent,
6
- continentcode as components_continentcode,
7
- leadevent as components_leadevent,
8
- saleevent as components_saleevent,
9
- )
4
+ from dub.models.components import linktagschemaoutput as components_linktagschemaoutput
10
5
  from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
11
6
  from dub.utils import FieldMetadata, QueryParamMetadata, get_discriminator
12
7
  from enum import Enum
13
8
  import pydantic
14
9
  from pydantic import Discriminator, Tag, model_serializer
15
- from typing import List, Optional, Union
10
+ from typing import Any, Dict, List, Optional, Union
16
11
  from typing_extensions import (
17
12
  Annotated,
18
13
  NotRequired,
@@ -44,6 +39,18 @@ class QueryParamInterval(str, Enum):
44
39
  ALL = "all"
45
40
 
46
41
 
42
+ class QueryParamContinent(str, Enum):
43
+ r"""The continent to retrieve analytics for."""
44
+
45
+ AF = "AF"
46
+ AN = "AN"
47
+ AS = "AS"
48
+ EU = "EU"
49
+ NA = "NA"
50
+ OC = "OC"
51
+ SA = "SA"
52
+
53
+
47
54
  class QueryParamTrigger(str, Enum):
48
55
  r"""The trigger to retrieve analytics for. If undefined, returns all trigger types."""
49
56
 
@@ -128,7 +135,7 @@ class ListEventsRequestTypedDict(TypedDict):
128
135
  r"""The city to retrieve analytics for."""
129
136
  region: NotRequired[str]
130
137
  r"""The ISO 3166-2 region code to retrieve analytics for."""
131
- continent: NotRequired[components_continentcode.ContinentCode]
138
+ continent: NotRequired[QueryParamContinent]
132
139
  r"""The continent to retrieve analytics for."""
133
140
  device: NotRequired[str]
134
141
  r"""The device to retrieve analytics for."""
@@ -139,7 +146,7 @@ class ListEventsRequestTypedDict(TypedDict):
139
146
  trigger: NotRequired[QueryParamTrigger]
140
147
  r"""The trigger to retrieve analytics for. If undefined, returns all trigger types."""
141
148
  referer: NotRequired[str]
142
- r"""The referer to retrieve analytics for."""
149
+ r"""The referer hostname to retrieve analytics for."""
143
150
  referer_url: NotRequired[str]
144
151
  r"""The full referer URL to retrieve analytics for."""
145
152
  url: NotRequired[str]
@@ -286,7 +293,7 @@ class ListEventsRequest(BaseModel):
286
293
  r"""The ISO 3166-2 region code to retrieve analytics for."""
287
294
 
288
295
  continent: Annotated[
289
- Optional[components_continentcode.ContinentCode],
296
+ Optional[QueryParamContinent],
290
297
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
291
298
  ] = None
292
299
  r"""The continent to retrieve analytics for."""
@@ -319,7 +326,7 @@ class ListEventsRequest(BaseModel):
319
326
  Optional[str],
320
327
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
321
328
  ] = None
322
- r"""The referer to retrieve analytics for."""
329
+ r"""The referer hostname to retrieve analytics for."""
323
330
 
324
331
  referer_url: Annotated[
325
332
  Optional[str],
@@ -535,21 +542,2009 @@ class ListEventsRequest(BaseModel):
535
542
  return m
536
543
 
537
544
 
538
- ListEventsResponseBodyTypedDict = TypeAliasType(
539
- "ListEventsResponseBodyTypedDict",
540
- Union[
541
- components_clickevent.ClickEventTypedDict,
542
- components_leadevent.LeadEventTypedDict,
543
- components_saleevent.SaleEventTypedDict,
544
- ],
545
+ class ListEventsResponseBodyEventsEvent(str, Enum):
546
+ SALE = "sale"
547
+
548
+
549
+ class ResponseBodyPaymentProcessor(str, Enum):
550
+ r"""The payment processor via which the sale was made."""
551
+
552
+ STRIPE = "stripe"
553
+ SHOPIFY = "shopify"
554
+ POLAR = "polar"
555
+ PADDLE = "paddle"
556
+ REVENUECAT = "revenuecat"
557
+ CUSTOM = "custom"
558
+
559
+
560
+ class ResponseBodySaleTypedDict(TypedDict):
561
+ amount: int
562
+ r"""The amount of the sale in cents (for all two-decimal currencies). If the sale is in a zero-decimal currency, pass the full integer value (e.g. `1437` JPY). Learn more: https://d.to/currency"""
563
+ invoice_id: NotRequired[Nullable[str]]
564
+ r"""The invoice ID of the sale. Can be used as a idempotency key – only one sale event can be recorded for a given invoice ID."""
565
+ payment_processor: NotRequired[ResponseBodyPaymentProcessor]
566
+ r"""The payment processor via which the sale was made."""
567
+
568
+
569
+ class ResponseBodySale(BaseModel):
570
+ amount: int
571
+ r"""The amount of the sale in cents (for all two-decimal currencies). If the sale is in a zero-decimal currency, pass the full integer value (e.g. `1437` JPY). Learn more: https://d.to/currency"""
572
+
573
+ invoice_id: Annotated[OptionalNullable[str], pydantic.Field(alias="invoiceId")] = (
574
+ None
575
+ )
576
+ r"""The invoice ID of the sale. Can be used as a idempotency key – only one sale event can be recorded for a given invoice ID."""
577
+
578
+ payment_processor: Annotated[
579
+ Optional[ResponseBodyPaymentProcessor], pydantic.Field(alias="paymentProcessor")
580
+ ] = ResponseBodyPaymentProcessor.CUSTOM
581
+ r"""The payment processor via which the sale was made."""
582
+
583
+ @model_serializer(mode="wrap")
584
+ def serialize_model(self, handler):
585
+ optional_fields = ["invoiceId", "paymentProcessor"]
586
+ nullable_fields = ["invoiceId"]
587
+ null_default_fields = ["invoiceId"]
588
+
589
+ serialized = handler(self)
590
+
591
+ m = {}
592
+
593
+ for n, f in type(self).model_fields.items():
594
+ k = f.alias or n
595
+ val = serialized.get(k)
596
+ serialized.pop(k, None)
597
+
598
+ optional_nullable = k in optional_fields and k in nullable_fields
599
+ is_set = (
600
+ self.__pydantic_fields_set__.intersection({n})
601
+ or k in null_default_fields
602
+ ) # pylint: disable=no-member
603
+
604
+ if val is not None and val != UNSET_SENTINEL:
605
+ m[k] = val
606
+ elif val != UNSET_SENTINEL and (
607
+ not k in optional_fields or (optional_nullable and is_set)
608
+ ):
609
+ m[k] = val
610
+
611
+ return m
612
+
613
+
614
+ class ListEventsResponseBodyEventsTestVariantsTypedDict(TypedDict):
615
+ url: str
616
+ percentage: float
617
+
618
+
619
+ class ListEventsResponseBodyEventsTestVariants(BaseModel):
620
+ url: str
621
+
622
+ percentage: float
623
+
624
+
625
+ class ListEventsResponseBodyLinkTypedDict(TypedDict):
626
+ id: str
627
+ r"""The unique ID of the short link."""
628
+ domain: str
629
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
630
+ key: str
631
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
632
+ url: str
633
+ track_conversion: bool
634
+ external_id: Nullable[str]
635
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
636
+ tenant_id: Nullable[str]
637
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
638
+ program_id: Nullable[str]
639
+ r"""The ID of the program the short link is associated with."""
640
+ partner_id: Nullable[str]
641
+ r"""The ID of the partner the short link is associated with."""
642
+ archived: bool
643
+ expires_at: str
644
+ expired_url: Nullable[str]
645
+ disabled_at: str
646
+ password: Nullable[str]
647
+ r"""The password required to access the destination URL of the short link."""
648
+ proxy: bool
649
+ title: Nullable[str]
650
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
651
+ description: Nullable[str]
652
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
653
+ image: Nullable[str]
654
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
655
+ video: Nullable[str]
656
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
657
+ rewrite: bool
658
+ do_index: bool
659
+ ios: Nullable[str]
660
+ r"""The iOS destination URL for the short link for iOS device targeting."""
661
+ android: Nullable[str]
662
+ r"""The Android destination URL for the short link for Android device targeting."""
663
+ geo: Nullable[Dict[str, str]]
664
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
665
+ public_stats: bool
666
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutputTypedDict]]
667
+ r"""The tags assigned to the short link."""
668
+ folder_id: Nullable[str]
669
+ r"""The unique ID of the folder assigned to the short link."""
670
+ webhook_ids: List[str]
671
+ r"""The IDs of the webhooks that the short link is associated with."""
672
+ comments: Nullable[str]
673
+ r"""The comments for the short link."""
674
+ short_link: str
675
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
676
+ qr_code: str
677
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
678
+ utm_source: Nullable[str]
679
+ r"""The UTM source of the short link."""
680
+ utm_medium: Nullable[str]
681
+ r"""The UTM medium of the short link."""
682
+ utm_campaign: Nullable[str]
683
+ r"""The UTM campaign of the short link."""
684
+ utm_term: Nullable[str]
685
+ r"""The UTM term of the short link."""
686
+ utm_content: Nullable[str]
687
+ r"""The UTM content of the short link."""
688
+ test_started_at: str
689
+ test_completed_at: str
690
+ user_id: Nullable[str]
691
+ workspace_id: str
692
+ r"""The workspace ID of the short link."""
693
+ last_clicked: str
694
+ created_at: str
695
+ updated_at: str
696
+ tag_id: Nullable[str]
697
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
698
+ project_id: str
699
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
700
+ test_variants: NotRequired[
701
+ Nullable[List[ListEventsResponseBodyEventsTestVariantsTypedDict]]
702
+ ]
703
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
704
+ clicks: NotRequired[float]
705
+ r"""The number of clicks on the short link."""
706
+ leads: NotRequired[float]
707
+ r"""The number of leads the short link has generated."""
708
+ conversions: NotRequired[float]
709
+ r"""The number of leads that converted to paying customers."""
710
+ sales: NotRequired[float]
711
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
712
+ sale_amount: NotRequired[float]
713
+ r"""The total dollar value of sales (in cents) generated by the short link."""
714
+
715
+
716
+ class ListEventsResponseBodyLink(BaseModel):
717
+ id: str
718
+ r"""The unique ID of the short link."""
719
+
720
+ domain: str
721
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
722
+
723
+ key: str
724
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
725
+
726
+ url: str
727
+
728
+ track_conversion: Annotated[bool, pydantic.Field(alias="trackConversion")]
729
+
730
+ external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]
731
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
732
+
733
+ tenant_id: Annotated[Nullable[str], pydantic.Field(alias="tenantId")]
734
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
735
+
736
+ program_id: Annotated[Nullable[str], pydantic.Field(alias="programId")]
737
+ r"""The ID of the program the short link is associated with."""
738
+
739
+ partner_id: Annotated[Nullable[str], pydantic.Field(alias="partnerId")]
740
+ r"""The ID of the partner the short link is associated with."""
741
+
742
+ archived: bool
743
+
744
+ expires_at: Annotated[str, pydantic.Field(alias="expiresAt")]
745
+
746
+ expired_url: Annotated[Nullable[str], pydantic.Field(alias="expiredUrl")]
747
+
748
+ disabled_at: Annotated[str, pydantic.Field(alias="disabledAt")]
749
+
750
+ password: Nullable[str]
751
+ r"""The password required to access the destination URL of the short link."""
752
+
753
+ proxy: bool
754
+
755
+ title: Nullable[str]
756
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
757
+
758
+ description: Nullable[str]
759
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
760
+
761
+ image: Nullable[str]
762
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
763
+
764
+ video: Nullable[str]
765
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
766
+
767
+ rewrite: bool
768
+
769
+ do_index: Annotated[bool, pydantic.Field(alias="doIndex")]
770
+
771
+ ios: Nullable[str]
772
+ r"""The iOS destination URL for the short link for iOS device targeting."""
773
+
774
+ android: Nullable[str]
775
+ r"""The Android destination URL for the short link for Android device targeting."""
776
+
777
+ geo: Nullable[Dict[str, str]]
778
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
779
+
780
+ public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
781
+
782
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutput]]
783
+ r"""The tags assigned to the short link."""
784
+
785
+ folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]
786
+ r"""The unique ID of the folder assigned to the short link."""
787
+
788
+ webhook_ids: Annotated[List[str], pydantic.Field(alias="webhookIds")]
789
+ r"""The IDs of the webhooks that the short link is associated with."""
790
+
791
+ comments: Nullable[str]
792
+ r"""The comments for the short link."""
793
+
794
+ short_link: Annotated[str, pydantic.Field(alias="shortLink")]
795
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
796
+
797
+ qr_code: Annotated[str, pydantic.Field(alias="qrCode")]
798
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
799
+
800
+ utm_source: Nullable[str]
801
+ r"""The UTM source of the short link."""
802
+
803
+ utm_medium: Nullable[str]
804
+ r"""The UTM medium of the short link."""
805
+
806
+ utm_campaign: Nullable[str]
807
+ r"""The UTM campaign of the short link."""
808
+
809
+ utm_term: Nullable[str]
810
+ r"""The UTM term of the short link."""
811
+
812
+ utm_content: Nullable[str]
813
+ r"""The UTM content of the short link."""
814
+
815
+ test_started_at: Annotated[str, pydantic.Field(alias="testStartedAt")]
816
+
817
+ test_completed_at: Annotated[str, pydantic.Field(alias="testCompletedAt")]
818
+
819
+ user_id: Annotated[Nullable[str], pydantic.Field(alias="userId")]
820
+
821
+ workspace_id: Annotated[str, pydantic.Field(alias="workspaceId")]
822
+ r"""The workspace ID of the short link."""
823
+
824
+ last_clicked: Annotated[str, pydantic.Field(alias="lastClicked")]
825
+
826
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
827
+
828
+ updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]
829
+
830
+ tag_id: Annotated[
831
+ Nullable[str],
832
+ pydantic.Field(
833
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
834
+ alias="tagId",
835
+ ),
836
+ ]
837
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
838
+
839
+ project_id: Annotated[
840
+ str,
841
+ pydantic.Field(
842
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
843
+ alias="projectId",
844
+ ),
845
+ ]
846
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
847
+
848
+ test_variants: Annotated[
849
+ OptionalNullable[List[ListEventsResponseBodyEventsTestVariants]],
850
+ pydantic.Field(alias="testVariants"),
851
+ ] = UNSET
852
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
853
+
854
+ clicks: Optional[float] = 0
855
+ r"""The number of clicks on the short link."""
856
+
857
+ leads: Optional[float] = 0
858
+ r"""The number of leads the short link has generated."""
859
+
860
+ conversions: Optional[float] = 0
861
+ r"""The number of leads that converted to paying customers."""
862
+
863
+ sales: Optional[float] = 0
864
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
865
+
866
+ sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
867
+ r"""The total dollar value of sales (in cents) generated by the short link."""
868
+
869
+ @model_serializer(mode="wrap")
870
+ def serialize_model(self, handler):
871
+ optional_fields = [
872
+ "testVariants",
873
+ "clicks",
874
+ "leads",
875
+ "conversions",
876
+ "sales",
877
+ "saleAmount",
878
+ ]
879
+ nullable_fields = [
880
+ "externalId",
881
+ "tenantId",
882
+ "programId",
883
+ "partnerId",
884
+ "expiredUrl",
885
+ "password",
886
+ "title",
887
+ "description",
888
+ "image",
889
+ "video",
890
+ "ios",
891
+ "android",
892
+ "geo",
893
+ "tags",
894
+ "folderId",
895
+ "comments",
896
+ "utm_source",
897
+ "utm_medium",
898
+ "utm_campaign",
899
+ "utm_term",
900
+ "utm_content",
901
+ "testVariants",
902
+ "userId",
903
+ "tagId",
904
+ ]
905
+ null_default_fields = []
906
+
907
+ serialized = handler(self)
908
+
909
+ m = {}
910
+
911
+ for n, f in type(self).model_fields.items():
912
+ k = f.alias or n
913
+ val = serialized.get(k)
914
+ serialized.pop(k, None)
915
+
916
+ optional_nullable = k in optional_fields and k in nullable_fields
917
+ is_set = (
918
+ self.__pydantic_fields_set__.intersection({n})
919
+ or k in null_default_fields
920
+ ) # pylint: disable=no-member
921
+
922
+ if val is not None and val != UNSET_SENTINEL:
923
+ m[k] = val
924
+ elif val != UNSET_SENTINEL and (
925
+ not k in optional_fields or (optional_nullable and is_set)
926
+ ):
927
+ m[k] = val
928
+
929
+ return m
930
+
931
+
932
+ class ListEventsResponseBodyClickTypedDict(TypedDict):
933
+ id: str
934
+ timestamp: str
935
+ url: str
936
+ country: str
937
+ city: str
938
+ region: str
939
+ continent: str
940
+ device: str
941
+ browser: str
942
+ os: str
943
+ referer: str
944
+ referer_url: str
945
+ qr: bool
946
+ ip: str
947
+ trigger: NotRequired[Nullable[str]]
948
+
949
+
950
+ class ListEventsResponseBodyClick(BaseModel):
951
+ id: str
952
+
953
+ timestamp: str
954
+
955
+ url: str
956
+
957
+ country: str
958
+
959
+ city: str
960
+
961
+ region: str
962
+
963
+ continent: str
964
+
965
+ device: str
966
+
967
+ browser: str
968
+
969
+ os: str
970
+
971
+ referer: str
972
+
973
+ referer_url: Annotated[str, pydantic.Field(alias="refererUrl")]
974
+
975
+ qr: bool
976
+
977
+ ip: str
978
+
979
+ trigger: OptionalNullable[str] = UNSET
980
+
981
+ @model_serializer(mode="wrap")
982
+ def serialize_model(self, handler):
983
+ optional_fields = ["trigger"]
984
+ nullable_fields = ["trigger"]
985
+ null_default_fields = []
986
+
987
+ serialized = handler(self)
988
+
989
+ m = {}
990
+
991
+ for n, f in type(self).model_fields.items():
992
+ k = f.alias or n
993
+ val = serialized.get(k)
994
+ serialized.pop(k, None)
995
+
996
+ optional_nullable = k in optional_fields and k in nullable_fields
997
+ is_set = (
998
+ self.__pydantic_fields_set__.intersection({n})
999
+ or k in null_default_fields
1000
+ ) # pylint: disable=no-member
1001
+
1002
+ if val is not None and val != UNSET_SENTINEL:
1003
+ m[k] = val
1004
+ elif val != UNSET_SENTINEL and (
1005
+ not k in optional_fields or (optional_nullable and is_set)
1006
+ ):
1007
+ m[k] = val
1008
+
1009
+ return m
1010
+
1011
+
1012
+ class ResponseBodyCustomerTypedDict(TypedDict):
1013
+ id: str
1014
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
1015
+ external_id: str
1016
+ r"""Unique identifier for the customer in the client's app."""
1017
+ name: str
1018
+ r"""Name of the customer."""
1019
+ created_at: str
1020
+ r"""The date the customer was created."""
1021
+ email: NotRequired[Nullable[str]]
1022
+ r"""Email of the customer."""
1023
+ avatar: NotRequired[Nullable[str]]
1024
+ r"""Avatar URL of the customer."""
1025
+ country: NotRequired[Nullable[str]]
1026
+ r"""Country of the customer."""
1027
+ sales: NotRequired[Nullable[float]]
1028
+ r"""Total number of sales for the customer."""
1029
+ sale_amount: NotRequired[Nullable[float]]
1030
+ r"""Total amount of sales for the customer."""
1031
+
1032
+
1033
+ class ResponseBodyCustomer(BaseModel):
1034
+ id: str
1035
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
1036
+
1037
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
1038
+ r"""Unique identifier for the customer in the client's app."""
1039
+
1040
+ name: str
1041
+ r"""Name of the customer."""
1042
+
1043
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
1044
+ r"""The date the customer was created."""
1045
+
1046
+ email: OptionalNullable[str] = UNSET
1047
+ r"""Email of the customer."""
1048
+
1049
+ avatar: OptionalNullable[str] = UNSET
1050
+ r"""Avatar URL of the customer."""
1051
+
1052
+ country: OptionalNullable[str] = UNSET
1053
+ r"""Country of the customer."""
1054
+
1055
+ sales: OptionalNullable[float] = UNSET
1056
+ r"""Total number of sales for the customer."""
1057
+
1058
+ sale_amount: Annotated[
1059
+ OptionalNullable[float], pydantic.Field(alias="saleAmount")
1060
+ ] = UNSET
1061
+ r"""Total amount of sales for the customer."""
1062
+
1063
+ @model_serializer(mode="wrap")
1064
+ def serialize_model(self, handler):
1065
+ optional_fields = ["email", "avatar", "country", "sales", "saleAmount"]
1066
+ nullable_fields = ["email", "avatar", "country", "sales", "saleAmount"]
1067
+ null_default_fields = []
1068
+
1069
+ serialized = handler(self)
1070
+
1071
+ m = {}
1072
+
1073
+ for n, f in type(self).model_fields.items():
1074
+ k = f.alias or n
1075
+ val = serialized.get(k)
1076
+ serialized.pop(k, None)
1077
+
1078
+ optional_nullable = k in optional_fields and k in nullable_fields
1079
+ is_set = (
1080
+ self.__pydantic_fields_set__.intersection({n})
1081
+ or k in null_default_fields
1082
+ ) # pylint: disable=no-member
1083
+
1084
+ if val is not None and val != UNSET_SENTINEL:
1085
+ m[k] = val
1086
+ elif val != UNSET_SENTINEL and (
1087
+ not k in optional_fields or (optional_nullable and is_set)
1088
+ ):
1089
+ m[k] = val
1090
+
1091
+ return m
1092
+
1093
+
1094
+ class SaleEventTypedDict(TypedDict):
1095
+ event: ListEventsResponseBodyEventsEvent
1096
+ timestamp: str
1097
+ event_id: str
1098
+ event_name: str
1099
+ sale: ResponseBodySaleTypedDict
1100
+ link: ListEventsResponseBodyLinkTypedDict
1101
+ click: ListEventsResponseBodyClickTypedDict
1102
+ customer: ResponseBodyCustomerTypedDict
1103
+ sale_amount: float
1104
+ r"""Deprecated: Use `sale.amount` instead."""
1105
+ invoice_id: str
1106
+ r"""Deprecated: Use `sale.invoiceId` instead."""
1107
+ payment_processor: str
1108
+ r"""Deprecated: Use `sale.paymentProcessor` instead."""
1109
+ click_id: str
1110
+ r"""Deprecated: Use `click.id` instead."""
1111
+ link_id: str
1112
+ r"""Deprecated: Use `link.id` instead."""
1113
+ domain: str
1114
+ r"""Deprecated: Use `link.domain` instead."""
1115
+ key: str
1116
+ r"""Deprecated: Use `link.key` instead."""
1117
+ url: str
1118
+ r"""Deprecated: Use `click.url` instead."""
1119
+ continent: str
1120
+ r"""Deprecated: Use `click.continent` instead."""
1121
+ country: str
1122
+ r"""Deprecated: Use `click.country` instead."""
1123
+ city: str
1124
+ r"""Deprecated: Use `click.city` instead."""
1125
+ device: str
1126
+ r"""Deprecated: Use `click.device` instead."""
1127
+ browser: str
1128
+ r"""Deprecated: Use `click.browser` instead."""
1129
+ os: str
1130
+ r"""Deprecated: Use `click.os` instead."""
1131
+ qr: float
1132
+ r"""Deprecated: Use `click.qr` instead."""
1133
+ ip: str
1134
+ r"""Deprecated: Use `click.ip` instead."""
1135
+ metadata: NotRequired[Nullable[Any]]
1136
+
1137
+
1138
+ class SaleEvent(BaseModel):
1139
+ event: ListEventsResponseBodyEventsEvent
1140
+
1141
+ timestamp: str
1142
+
1143
+ event_id: Annotated[str, pydantic.Field(alias="eventId")]
1144
+
1145
+ event_name: Annotated[str, pydantic.Field(alias="eventName")]
1146
+
1147
+ sale: ResponseBodySale
1148
+
1149
+ link: ListEventsResponseBodyLink
1150
+
1151
+ click: ListEventsResponseBodyClick
1152
+
1153
+ customer: ResponseBodyCustomer
1154
+
1155
+ sale_amount: Annotated[
1156
+ float,
1157
+ pydantic.Field(
1158
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
1159
+ alias="saleAmount",
1160
+ ),
1161
+ ]
1162
+ r"""Deprecated: Use `sale.amount` instead."""
1163
+
1164
+ invoice_id: Annotated[
1165
+ str,
1166
+ pydantic.Field(
1167
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1168
+ ),
1169
+ ]
1170
+ r"""Deprecated: Use `sale.invoiceId` instead."""
1171
+
1172
+ payment_processor: Annotated[
1173
+ str,
1174
+ pydantic.Field(
1175
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1176
+ ),
1177
+ ]
1178
+ r"""Deprecated: Use `sale.paymentProcessor` instead."""
1179
+
1180
+ click_id: Annotated[
1181
+ str,
1182
+ pydantic.Field(
1183
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1184
+ ),
1185
+ ]
1186
+ r"""Deprecated: Use `click.id` instead."""
1187
+
1188
+ link_id: Annotated[
1189
+ str,
1190
+ pydantic.Field(
1191
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1192
+ ),
1193
+ ]
1194
+ r"""Deprecated: Use `link.id` instead."""
1195
+
1196
+ domain: Annotated[
1197
+ str,
1198
+ pydantic.Field(
1199
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1200
+ ),
1201
+ ]
1202
+ r"""Deprecated: Use `link.domain` instead."""
1203
+
1204
+ key: Annotated[
1205
+ str,
1206
+ pydantic.Field(
1207
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1208
+ ),
1209
+ ]
1210
+ r"""Deprecated: Use `link.key` instead."""
1211
+
1212
+ url: Annotated[
1213
+ str,
1214
+ pydantic.Field(
1215
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1216
+ ),
1217
+ ]
1218
+ r"""Deprecated: Use `click.url` instead."""
1219
+
1220
+ continent: Annotated[
1221
+ str,
1222
+ pydantic.Field(
1223
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1224
+ ),
1225
+ ]
1226
+ r"""Deprecated: Use `click.continent` instead."""
1227
+
1228
+ country: Annotated[
1229
+ str,
1230
+ pydantic.Field(
1231
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1232
+ ),
1233
+ ]
1234
+ r"""Deprecated: Use `click.country` instead."""
1235
+
1236
+ city: Annotated[
1237
+ str,
1238
+ pydantic.Field(
1239
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1240
+ ),
1241
+ ]
1242
+ r"""Deprecated: Use `click.city` instead."""
1243
+
1244
+ device: Annotated[
1245
+ str,
1246
+ pydantic.Field(
1247
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1248
+ ),
1249
+ ]
1250
+ r"""Deprecated: Use `click.device` instead."""
1251
+
1252
+ browser: Annotated[
1253
+ str,
1254
+ pydantic.Field(
1255
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1256
+ ),
1257
+ ]
1258
+ r"""Deprecated: Use `click.browser` instead."""
1259
+
1260
+ os: Annotated[
1261
+ str,
1262
+ pydantic.Field(
1263
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1264
+ ),
1265
+ ]
1266
+ r"""Deprecated: Use `click.os` instead."""
1267
+
1268
+ qr: Annotated[
1269
+ float,
1270
+ pydantic.Field(
1271
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1272
+ ),
1273
+ ]
1274
+ r"""Deprecated: Use `click.qr` instead."""
1275
+
1276
+ ip: Annotated[
1277
+ str,
1278
+ pydantic.Field(
1279
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1280
+ ),
1281
+ ]
1282
+ r"""Deprecated: Use `click.ip` instead."""
1283
+
1284
+ metadata: OptionalNullable[Any] = UNSET
1285
+
1286
+ @model_serializer(mode="wrap")
1287
+ def serialize_model(self, handler):
1288
+ optional_fields = ["metadata"]
1289
+ nullable_fields = ["metadata"]
1290
+ null_default_fields = []
1291
+
1292
+ serialized = handler(self)
1293
+
1294
+ m = {}
1295
+
1296
+ for n, f in type(self).model_fields.items():
1297
+ k = f.alias or n
1298
+ val = serialized.get(k)
1299
+ serialized.pop(k, None)
1300
+
1301
+ optional_nullable = k in optional_fields and k in nullable_fields
1302
+ is_set = (
1303
+ self.__pydantic_fields_set__.intersection({n})
1304
+ or k in null_default_fields
1305
+ ) # pylint: disable=no-member
1306
+
1307
+ if val is not None and val != UNSET_SENTINEL:
1308
+ m[k] = val
1309
+ elif val != UNSET_SENTINEL and (
1310
+ not k in optional_fields or (optional_nullable and is_set)
1311
+ ):
1312
+ m[k] = val
1313
+
1314
+ return m
1315
+
1316
+
1317
+ class ListEventsResponseBodyEvent(str, Enum):
1318
+ LEAD = "lead"
1319
+
1320
+
1321
+ class ResponseBodyClickTypedDict(TypedDict):
1322
+ id: str
1323
+ timestamp: str
1324
+ url: str
1325
+ country: str
1326
+ city: str
1327
+ region: str
1328
+ continent: str
1329
+ device: str
1330
+ browser: str
1331
+ os: str
1332
+ referer: str
1333
+ referer_url: str
1334
+ qr: bool
1335
+ ip: str
1336
+ trigger: NotRequired[Nullable[str]]
1337
+
1338
+
1339
+ class ResponseBodyClick(BaseModel):
1340
+ id: str
1341
+
1342
+ timestamp: str
1343
+
1344
+ url: str
1345
+
1346
+ country: str
1347
+
1348
+ city: str
1349
+
1350
+ region: str
1351
+
1352
+ continent: str
1353
+
1354
+ device: str
1355
+
1356
+ browser: str
1357
+
1358
+ os: str
1359
+
1360
+ referer: str
1361
+
1362
+ referer_url: Annotated[str, pydantic.Field(alias="refererUrl")]
1363
+
1364
+ qr: bool
1365
+
1366
+ ip: str
1367
+
1368
+ trigger: OptionalNullable[str] = UNSET
1369
+
1370
+ @model_serializer(mode="wrap")
1371
+ def serialize_model(self, handler):
1372
+ optional_fields = ["trigger"]
1373
+ nullable_fields = ["trigger"]
1374
+ null_default_fields = []
1375
+
1376
+ serialized = handler(self)
1377
+
1378
+ m = {}
1379
+
1380
+ for n, f in type(self).model_fields.items():
1381
+ k = f.alias or n
1382
+ val = serialized.get(k)
1383
+ serialized.pop(k, None)
1384
+
1385
+ optional_nullable = k in optional_fields and k in nullable_fields
1386
+ is_set = (
1387
+ self.__pydantic_fields_set__.intersection({n})
1388
+ or k in null_default_fields
1389
+ ) # pylint: disable=no-member
1390
+
1391
+ if val is not None and val != UNSET_SENTINEL:
1392
+ m[k] = val
1393
+ elif val != UNSET_SENTINEL and (
1394
+ not k in optional_fields or (optional_nullable and is_set)
1395
+ ):
1396
+ m[k] = val
1397
+
1398
+ return m
1399
+
1400
+
1401
+ class ListEventsResponseBodyTestVariantsTypedDict(TypedDict):
1402
+ url: str
1403
+ percentage: float
1404
+
1405
+
1406
+ class ListEventsResponseBodyTestVariants(BaseModel):
1407
+ url: str
1408
+
1409
+ percentage: float
1410
+
1411
+
1412
+ class ResponseBodyLinkTypedDict(TypedDict):
1413
+ id: str
1414
+ r"""The unique ID of the short link."""
1415
+ domain: str
1416
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
1417
+ key: str
1418
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
1419
+ url: str
1420
+ track_conversion: bool
1421
+ external_id: Nullable[str]
1422
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
1423
+ tenant_id: Nullable[str]
1424
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
1425
+ program_id: Nullable[str]
1426
+ r"""The ID of the program the short link is associated with."""
1427
+ partner_id: Nullable[str]
1428
+ r"""The ID of the partner the short link is associated with."""
1429
+ archived: bool
1430
+ expires_at: str
1431
+ expired_url: Nullable[str]
1432
+ disabled_at: str
1433
+ password: Nullable[str]
1434
+ r"""The password required to access the destination URL of the short link."""
1435
+ proxy: bool
1436
+ title: Nullable[str]
1437
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1438
+ description: Nullable[str]
1439
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1440
+ image: Nullable[str]
1441
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1442
+ video: Nullable[str]
1443
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
1444
+ rewrite: bool
1445
+ do_index: bool
1446
+ ios: Nullable[str]
1447
+ r"""The iOS destination URL for the short link for iOS device targeting."""
1448
+ android: Nullable[str]
1449
+ r"""The Android destination URL for the short link for Android device targeting."""
1450
+ geo: Nullable[Dict[str, str]]
1451
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
1452
+ public_stats: bool
1453
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutputTypedDict]]
1454
+ r"""The tags assigned to the short link."""
1455
+ folder_id: Nullable[str]
1456
+ r"""The unique ID of the folder assigned to the short link."""
1457
+ webhook_ids: List[str]
1458
+ r"""The IDs of the webhooks that the short link is associated with."""
1459
+ comments: Nullable[str]
1460
+ r"""The comments for the short link."""
1461
+ short_link: str
1462
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
1463
+ qr_code: str
1464
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
1465
+ utm_source: Nullable[str]
1466
+ r"""The UTM source of the short link."""
1467
+ utm_medium: Nullable[str]
1468
+ r"""The UTM medium of the short link."""
1469
+ utm_campaign: Nullable[str]
1470
+ r"""The UTM campaign of the short link."""
1471
+ utm_term: Nullable[str]
1472
+ r"""The UTM term of the short link."""
1473
+ utm_content: Nullable[str]
1474
+ r"""The UTM content of the short link."""
1475
+ test_started_at: str
1476
+ test_completed_at: str
1477
+ user_id: Nullable[str]
1478
+ workspace_id: str
1479
+ r"""The workspace ID of the short link."""
1480
+ last_clicked: str
1481
+ created_at: str
1482
+ updated_at: str
1483
+ tag_id: Nullable[str]
1484
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
1485
+ project_id: str
1486
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
1487
+ test_variants: NotRequired[
1488
+ Nullable[List[ListEventsResponseBodyTestVariantsTypedDict]]
1489
+ ]
1490
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
1491
+ clicks: NotRequired[float]
1492
+ r"""The number of clicks on the short link."""
1493
+ leads: NotRequired[float]
1494
+ r"""The number of leads the short link has generated."""
1495
+ conversions: NotRequired[float]
1496
+ r"""The number of leads that converted to paying customers."""
1497
+ sales: NotRequired[float]
1498
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
1499
+ sale_amount: NotRequired[float]
1500
+ r"""The total dollar value of sales (in cents) generated by the short link."""
1501
+
1502
+
1503
+ class ResponseBodyLink(BaseModel):
1504
+ id: str
1505
+ r"""The unique ID of the short link."""
1506
+
1507
+ domain: str
1508
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
1509
+
1510
+ key: str
1511
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
1512
+
1513
+ url: str
1514
+
1515
+ track_conversion: Annotated[bool, pydantic.Field(alias="trackConversion")]
1516
+
1517
+ external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]
1518
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
1519
+
1520
+ tenant_id: Annotated[Nullable[str], pydantic.Field(alias="tenantId")]
1521
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
1522
+
1523
+ program_id: Annotated[Nullable[str], pydantic.Field(alias="programId")]
1524
+ r"""The ID of the program the short link is associated with."""
1525
+
1526
+ partner_id: Annotated[Nullable[str], pydantic.Field(alias="partnerId")]
1527
+ r"""The ID of the partner the short link is associated with."""
1528
+
1529
+ archived: bool
1530
+
1531
+ expires_at: Annotated[str, pydantic.Field(alias="expiresAt")]
1532
+
1533
+ expired_url: Annotated[Nullable[str], pydantic.Field(alias="expiredUrl")]
1534
+
1535
+ disabled_at: Annotated[str, pydantic.Field(alias="disabledAt")]
1536
+
1537
+ password: Nullable[str]
1538
+ r"""The password required to access the destination URL of the short link."""
1539
+
1540
+ proxy: bool
1541
+
1542
+ title: Nullable[str]
1543
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1544
+
1545
+ description: Nullable[str]
1546
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1547
+
1548
+ image: Nullable[str]
1549
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
1550
+
1551
+ video: Nullable[str]
1552
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
1553
+
1554
+ rewrite: bool
1555
+
1556
+ do_index: Annotated[bool, pydantic.Field(alias="doIndex")]
1557
+
1558
+ ios: Nullable[str]
1559
+ r"""The iOS destination URL for the short link for iOS device targeting."""
1560
+
1561
+ android: Nullable[str]
1562
+ r"""The Android destination URL for the short link for Android device targeting."""
1563
+
1564
+ geo: Nullable[Dict[str, str]]
1565
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
1566
+
1567
+ public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
1568
+
1569
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutput]]
1570
+ r"""The tags assigned to the short link."""
1571
+
1572
+ folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]
1573
+ r"""The unique ID of the folder assigned to the short link."""
1574
+
1575
+ webhook_ids: Annotated[List[str], pydantic.Field(alias="webhookIds")]
1576
+ r"""The IDs of the webhooks that the short link is associated with."""
1577
+
1578
+ comments: Nullable[str]
1579
+ r"""The comments for the short link."""
1580
+
1581
+ short_link: Annotated[str, pydantic.Field(alias="shortLink")]
1582
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
1583
+
1584
+ qr_code: Annotated[str, pydantic.Field(alias="qrCode")]
1585
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
1586
+
1587
+ utm_source: Nullable[str]
1588
+ r"""The UTM source of the short link."""
1589
+
1590
+ utm_medium: Nullable[str]
1591
+ r"""The UTM medium of the short link."""
1592
+
1593
+ utm_campaign: Nullable[str]
1594
+ r"""The UTM campaign of the short link."""
1595
+
1596
+ utm_term: Nullable[str]
1597
+ r"""The UTM term of the short link."""
1598
+
1599
+ utm_content: Nullable[str]
1600
+ r"""The UTM content of the short link."""
1601
+
1602
+ test_started_at: Annotated[str, pydantic.Field(alias="testStartedAt")]
1603
+
1604
+ test_completed_at: Annotated[str, pydantic.Field(alias="testCompletedAt")]
1605
+
1606
+ user_id: Annotated[Nullable[str], pydantic.Field(alias="userId")]
1607
+
1608
+ workspace_id: Annotated[str, pydantic.Field(alias="workspaceId")]
1609
+ r"""The workspace ID of the short link."""
1610
+
1611
+ last_clicked: Annotated[str, pydantic.Field(alias="lastClicked")]
1612
+
1613
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
1614
+
1615
+ updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]
1616
+
1617
+ tag_id: Annotated[
1618
+ Nullable[str],
1619
+ pydantic.Field(
1620
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
1621
+ alias="tagId",
1622
+ ),
1623
+ ]
1624
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
1625
+
1626
+ project_id: Annotated[
1627
+ str,
1628
+ pydantic.Field(
1629
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
1630
+ alias="projectId",
1631
+ ),
1632
+ ]
1633
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
1634
+
1635
+ test_variants: Annotated[
1636
+ OptionalNullable[List[ListEventsResponseBodyTestVariants]],
1637
+ pydantic.Field(alias="testVariants"),
1638
+ ] = UNSET
1639
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
1640
+
1641
+ clicks: Optional[float] = 0
1642
+ r"""The number of clicks on the short link."""
1643
+
1644
+ leads: Optional[float] = 0
1645
+ r"""The number of leads the short link has generated."""
1646
+
1647
+ conversions: Optional[float] = 0
1648
+ r"""The number of leads that converted to paying customers."""
1649
+
1650
+ sales: Optional[float] = 0
1651
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
1652
+
1653
+ sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
1654
+ r"""The total dollar value of sales (in cents) generated by the short link."""
1655
+
1656
+ @model_serializer(mode="wrap")
1657
+ def serialize_model(self, handler):
1658
+ optional_fields = [
1659
+ "testVariants",
1660
+ "clicks",
1661
+ "leads",
1662
+ "conversions",
1663
+ "sales",
1664
+ "saleAmount",
1665
+ ]
1666
+ nullable_fields = [
1667
+ "externalId",
1668
+ "tenantId",
1669
+ "programId",
1670
+ "partnerId",
1671
+ "expiredUrl",
1672
+ "password",
1673
+ "title",
1674
+ "description",
1675
+ "image",
1676
+ "video",
1677
+ "ios",
1678
+ "android",
1679
+ "geo",
1680
+ "tags",
1681
+ "folderId",
1682
+ "comments",
1683
+ "utm_source",
1684
+ "utm_medium",
1685
+ "utm_campaign",
1686
+ "utm_term",
1687
+ "utm_content",
1688
+ "testVariants",
1689
+ "userId",
1690
+ "tagId",
1691
+ ]
1692
+ null_default_fields = []
1693
+
1694
+ serialized = handler(self)
1695
+
1696
+ m = {}
1697
+
1698
+ for n, f in type(self).model_fields.items():
1699
+ k = f.alias or n
1700
+ val = serialized.get(k)
1701
+ serialized.pop(k, None)
1702
+
1703
+ optional_nullable = k in optional_fields and k in nullable_fields
1704
+ is_set = (
1705
+ self.__pydantic_fields_set__.intersection({n})
1706
+ or k in null_default_fields
1707
+ ) # pylint: disable=no-member
1708
+
1709
+ if val is not None and val != UNSET_SENTINEL:
1710
+ m[k] = val
1711
+ elif val != UNSET_SENTINEL and (
1712
+ not k in optional_fields or (optional_nullable and is_set)
1713
+ ):
1714
+ m[k] = val
1715
+
1716
+ return m
1717
+
1718
+
1719
+ class ListEventsResponseBodyCustomerTypedDict(TypedDict):
1720
+ id: str
1721
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
1722
+ external_id: str
1723
+ r"""Unique identifier for the customer in the client's app."""
1724
+ name: str
1725
+ r"""Name of the customer."""
1726
+ created_at: str
1727
+ r"""The date the customer was created."""
1728
+ email: NotRequired[Nullable[str]]
1729
+ r"""Email of the customer."""
1730
+ avatar: NotRequired[Nullable[str]]
1731
+ r"""Avatar URL of the customer."""
1732
+ country: NotRequired[Nullable[str]]
1733
+ r"""Country of the customer."""
1734
+ sales: NotRequired[Nullable[float]]
1735
+ r"""Total number of sales for the customer."""
1736
+ sale_amount: NotRequired[Nullable[float]]
1737
+ r"""Total amount of sales for the customer."""
1738
+
1739
+
1740
+ class ListEventsResponseBodyCustomer(BaseModel):
1741
+ id: str
1742
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
1743
+
1744
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
1745
+ r"""Unique identifier for the customer in the client's app."""
1746
+
1747
+ name: str
1748
+ r"""Name of the customer."""
1749
+
1750
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
1751
+ r"""The date the customer was created."""
1752
+
1753
+ email: OptionalNullable[str] = UNSET
1754
+ r"""Email of the customer."""
1755
+
1756
+ avatar: OptionalNullable[str] = UNSET
1757
+ r"""Avatar URL of the customer."""
1758
+
1759
+ country: OptionalNullable[str] = UNSET
1760
+ r"""Country of the customer."""
1761
+
1762
+ sales: OptionalNullable[float] = UNSET
1763
+ r"""Total number of sales for the customer."""
1764
+
1765
+ sale_amount: Annotated[
1766
+ OptionalNullable[float], pydantic.Field(alias="saleAmount")
1767
+ ] = UNSET
1768
+ r"""Total amount of sales for the customer."""
1769
+
1770
+ @model_serializer(mode="wrap")
1771
+ def serialize_model(self, handler):
1772
+ optional_fields = ["email", "avatar", "country", "sales", "saleAmount"]
1773
+ nullable_fields = ["email", "avatar", "country", "sales", "saleAmount"]
1774
+ null_default_fields = []
1775
+
1776
+ serialized = handler(self)
1777
+
1778
+ m = {}
1779
+
1780
+ for n, f in type(self).model_fields.items():
1781
+ k = f.alias or n
1782
+ val = serialized.get(k)
1783
+ serialized.pop(k, None)
1784
+
1785
+ optional_nullable = k in optional_fields and k in nullable_fields
1786
+ is_set = (
1787
+ self.__pydantic_fields_set__.intersection({n})
1788
+ or k in null_default_fields
1789
+ ) # pylint: disable=no-member
1790
+
1791
+ if val is not None and val != UNSET_SENTINEL:
1792
+ m[k] = val
1793
+ elif val != UNSET_SENTINEL and (
1794
+ not k in optional_fields or (optional_nullable and is_set)
1795
+ ):
1796
+ m[k] = val
1797
+
1798
+ return m
1799
+
1800
+
1801
+ class LeadEventTypedDict(TypedDict):
1802
+ event: ListEventsResponseBodyEvent
1803
+ timestamp: str
1804
+ event_id: str
1805
+ event_name: str
1806
+ click: ResponseBodyClickTypedDict
1807
+ link: ResponseBodyLinkTypedDict
1808
+ customer: ListEventsResponseBodyCustomerTypedDict
1809
+ click_id: str
1810
+ r"""Deprecated: Use `click.id` instead."""
1811
+ link_id: str
1812
+ r"""Deprecated: Use `link.id` instead."""
1813
+ domain: str
1814
+ r"""Deprecated: Use `link.domain` instead."""
1815
+ key: str
1816
+ r"""Deprecated: Use `link.key` instead."""
1817
+ url: str
1818
+ r"""Deprecated: Use `click.url` instead."""
1819
+ continent: str
1820
+ r"""Deprecated: Use `click.continent` instead."""
1821
+ country: str
1822
+ r"""Deprecated: Use `click.country` instead."""
1823
+ city: str
1824
+ r"""Deprecated: Use `click.city` instead."""
1825
+ device: str
1826
+ r"""Deprecated: Use `click.device` instead."""
1827
+ browser: str
1828
+ r"""Deprecated: Use `click.browser` instead."""
1829
+ os: str
1830
+ r"""Deprecated: Use `click.os` instead."""
1831
+ qr: float
1832
+ r"""Deprecated: Use `click.qr` instead."""
1833
+ ip: str
1834
+ r"""Deprecated: Use `click.ip` instead."""
1835
+ metadata: NotRequired[Nullable[Any]]
1836
+
1837
+
1838
+ class LeadEvent(BaseModel):
1839
+ event: ListEventsResponseBodyEvent
1840
+
1841
+ timestamp: str
1842
+
1843
+ event_id: Annotated[str, pydantic.Field(alias="eventId")]
1844
+
1845
+ event_name: Annotated[str, pydantic.Field(alias="eventName")]
1846
+
1847
+ click: ResponseBodyClick
1848
+
1849
+ link: ResponseBodyLink
1850
+
1851
+ customer: ListEventsResponseBodyCustomer
1852
+
1853
+ click_id: Annotated[
1854
+ str,
1855
+ pydantic.Field(
1856
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1857
+ ),
1858
+ ]
1859
+ r"""Deprecated: Use `click.id` instead."""
1860
+
1861
+ link_id: Annotated[
1862
+ str,
1863
+ pydantic.Field(
1864
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1865
+ ),
1866
+ ]
1867
+ r"""Deprecated: Use `link.id` instead."""
1868
+
1869
+ domain: Annotated[
1870
+ str,
1871
+ pydantic.Field(
1872
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1873
+ ),
1874
+ ]
1875
+ r"""Deprecated: Use `link.domain` instead."""
1876
+
1877
+ key: Annotated[
1878
+ str,
1879
+ pydantic.Field(
1880
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1881
+ ),
1882
+ ]
1883
+ r"""Deprecated: Use `link.key` instead."""
1884
+
1885
+ url: Annotated[
1886
+ str,
1887
+ pydantic.Field(
1888
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1889
+ ),
1890
+ ]
1891
+ r"""Deprecated: Use `click.url` instead."""
1892
+
1893
+ continent: Annotated[
1894
+ str,
1895
+ pydantic.Field(
1896
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1897
+ ),
1898
+ ]
1899
+ r"""Deprecated: Use `click.continent` instead."""
1900
+
1901
+ country: Annotated[
1902
+ str,
1903
+ pydantic.Field(
1904
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1905
+ ),
1906
+ ]
1907
+ r"""Deprecated: Use `click.country` instead."""
1908
+
1909
+ city: Annotated[
1910
+ str,
1911
+ pydantic.Field(
1912
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1913
+ ),
1914
+ ]
1915
+ r"""Deprecated: Use `click.city` instead."""
1916
+
1917
+ device: Annotated[
1918
+ str,
1919
+ pydantic.Field(
1920
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1921
+ ),
1922
+ ]
1923
+ r"""Deprecated: Use `click.device` instead."""
1924
+
1925
+ browser: Annotated[
1926
+ str,
1927
+ pydantic.Field(
1928
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1929
+ ),
1930
+ ]
1931
+ r"""Deprecated: Use `click.browser` instead."""
1932
+
1933
+ os: Annotated[
1934
+ str,
1935
+ pydantic.Field(
1936
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1937
+ ),
1938
+ ]
1939
+ r"""Deprecated: Use `click.os` instead."""
1940
+
1941
+ qr: Annotated[
1942
+ float,
1943
+ pydantic.Field(
1944
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1945
+ ),
1946
+ ]
1947
+ r"""Deprecated: Use `click.qr` instead."""
1948
+
1949
+ ip: Annotated[
1950
+ str,
1951
+ pydantic.Field(
1952
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
1953
+ ),
1954
+ ]
1955
+ r"""Deprecated: Use `click.ip` instead."""
1956
+
1957
+ metadata: OptionalNullable[Any] = UNSET
1958
+
1959
+ @model_serializer(mode="wrap")
1960
+ def serialize_model(self, handler):
1961
+ optional_fields = ["metadata"]
1962
+ nullable_fields = ["metadata"]
1963
+ null_default_fields = []
1964
+
1965
+ serialized = handler(self)
1966
+
1967
+ m = {}
1968
+
1969
+ for n, f in type(self).model_fields.items():
1970
+ k = f.alias or n
1971
+ val = serialized.get(k)
1972
+ serialized.pop(k, None)
1973
+
1974
+ optional_nullable = k in optional_fields and k in nullable_fields
1975
+ is_set = (
1976
+ self.__pydantic_fields_set__.intersection({n})
1977
+ or k in null_default_fields
1978
+ ) # pylint: disable=no-member
1979
+
1980
+ if val is not None and val != UNSET_SENTINEL:
1981
+ m[k] = val
1982
+ elif val != UNSET_SENTINEL and (
1983
+ not k in optional_fields or (optional_nullable and is_set)
1984
+ ):
1985
+ m[k] = val
1986
+
1987
+ return m
1988
+
1989
+
1990
+ class ResponseBodyEvent(str, Enum):
1991
+ CLICK = "click"
1992
+
1993
+
1994
+ class ListEventsResponseBodyEventsClickTypedDict(TypedDict):
1995
+ id: str
1996
+ timestamp: str
1997
+ url: str
1998
+ country: str
1999
+ city: str
2000
+ region: str
2001
+ continent: str
2002
+ device: str
2003
+ browser: str
2004
+ os: str
2005
+ referer: str
2006
+ referer_url: str
2007
+ qr: bool
2008
+ ip: str
2009
+ trigger: NotRequired[Nullable[str]]
2010
+
2011
+
2012
+ class ListEventsResponseBodyEventsClick(BaseModel):
2013
+ id: str
2014
+
2015
+ timestamp: str
2016
+
2017
+ url: str
2018
+
2019
+ country: str
2020
+
2021
+ city: str
2022
+
2023
+ region: str
2024
+
2025
+ continent: str
2026
+
2027
+ device: str
2028
+
2029
+ browser: str
2030
+
2031
+ os: str
2032
+
2033
+ referer: str
2034
+
2035
+ referer_url: Annotated[str, pydantic.Field(alias="refererUrl")]
2036
+
2037
+ qr: bool
2038
+
2039
+ ip: str
2040
+
2041
+ trigger: OptionalNullable[str] = UNSET
2042
+
2043
+ @model_serializer(mode="wrap")
2044
+ def serialize_model(self, handler):
2045
+ optional_fields = ["trigger"]
2046
+ nullable_fields = ["trigger"]
2047
+ null_default_fields = []
2048
+
2049
+ serialized = handler(self)
2050
+
2051
+ m = {}
2052
+
2053
+ for n, f in type(self).model_fields.items():
2054
+ k = f.alias or n
2055
+ val = serialized.get(k)
2056
+ serialized.pop(k, None)
2057
+
2058
+ optional_nullable = k in optional_fields and k in nullable_fields
2059
+ is_set = (
2060
+ self.__pydantic_fields_set__.intersection({n})
2061
+ or k in null_default_fields
2062
+ ) # pylint: disable=no-member
2063
+
2064
+ if val is not None and val != UNSET_SENTINEL:
2065
+ m[k] = val
2066
+ elif val != UNSET_SENTINEL and (
2067
+ not k in optional_fields or (optional_nullable and is_set)
2068
+ ):
2069
+ m[k] = val
2070
+
2071
+ return m
2072
+
2073
+
2074
+ class ResponseBodyTestVariantsTypedDict(TypedDict):
2075
+ url: str
2076
+ percentage: float
2077
+
2078
+
2079
+ class ResponseBodyTestVariants(BaseModel):
2080
+ url: str
2081
+
2082
+ percentage: float
2083
+
2084
+
2085
+ class ListEventsResponseBodyEventsLinkTypedDict(TypedDict):
2086
+ id: str
2087
+ r"""The unique ID of the short link."""
2088
+ domain: str
2089
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
2090
+ key: str
2091
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
2092
+ url: str
2093
+ track_conversion: bool
2094
+ external_id: Nullable[str]
2095
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
2096
+ tenant_id: Nullable[str]
2097
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
2098
+ program_id: Nullable[str]
2099
+ r"""The ID of the program the short link is associated with."""
2100
+ partner_id: Nullable[str]
2101
+ r"""The ID of the partner the short link is associated with."""
2102
+ archived: bool
2103
+ expires_at: str
2104
+ expired_url: Nullable[str]
2105
+ disabled_at: str
2106
+ password: Nullable[str]
2107
+ r"""The password required to access the destination URL of the short link."""
2108
+ proxy: bool
2109
+ title: Nullable[str]
2110
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2111
+ description: Nullable[str]
2112
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2113
+ image: Nullable[str]
2114
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2115
+ video: Nullable[str]
2116
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
2117
+ rewrite: bool
2118
+ do_index: bool
2119
+ ios: Nullable[str]
2120
+ r"""The iOS destination URL for the short link for iOS device targeting."""
2121
+ android: Nullable[str]
2122
+ r"""The Android destination URL for the short link for Android device targeting."""
2123
+ geo: Nullable[Dict[str, str]]
2124
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
2125
+ public_stats: bool
2126
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutputTypedDict]]
2127
+ r"""The tags assigned to the short link."""
2128
+ folder_id: Nullable[str]
2129
+ r"""The unique ID of the folder assigned to the short link."""
2130
+ webhook_ids: List[str]
2131
+ r"""The IDs of the webhooks that the short link is associated with."""
2132
+ comments: Nullable[str]
2133
+ r"""The comments for the short link."""
2134
+ short_link: str
2135
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
2136
+ qr_code: str
2137
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
2138
+ utm_source: Nullable[str]
2139
+ r"""The UTM source of the short link."""
2140
+ utm_medium: Nullable[str]
2141
+ r"""The UTM medium of the short link."""
2142
+ utm_campaign: Nullable[str]
2143
+ r"""The UTM campaign of the short link."""
2144
+ utm_term: Nullable[str]
2145
+ r"""The UTM term of the short link."""
2146
+ utm_content: Nullable[str]
2147
+ r"""The UTM content of the short link."""
2148
+ test_started_at: str
2149
+ test_completed_at: str
2150
+ user_id: Nullable[str]
2151
+ workspace_id: str
2152
+ r"""The workspace ID of the short link."""
2153
+ last_clicked: str
2154
+ created_at: str
2155
+ updated_at: str
2156
+ tag_id: Nullable[str]
2157
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
2158
+ project_id: str
2159
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
2160
+ test_variants: NotRequired[Nullable[List[ResponseBodyTestVariantsTypedDict]]]
2161
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
2162
+ clicks: NotRequired[float]
2163
+ r"""The number of clicks on the short link."""
2164
+ leads: NotRequired[float]
2165
+ r"""The number of leads the short link has generated."""
2166
+ conversions: NotRequired[float]
2167
+ r"""The number of leads that converted to paying customers."""
2168
+ sales: NotRequired[float]
2169
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
2170
+ sale_amount: NotRequired[float]
2171
+ r"""The total dollar value of sales (in cents) generated by the short link."""
2172
+
2173
+
2174
+ class ListEventsResponseBodyEventsLink(BaseModel):
2175
+ id: str
2176
+ r"""The unique ID of the short link."""
2177
+
2178
+ domain: str
2179
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
2180
+
2181
+ key: str
2182
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
2183
+
2184
+ url: str
2185
+
2186
+ track_conversion: Annotated[bool, pydantic.Field(alias="trackConversion")]
2187
+
2188
+ external_id: Annotated[Nullable[str], pydantic.Field(alias="externalId")]
2189
+ r"""The ID of the link in your database. If set, it can be used to identify the link in future API requests (must be prefixed with 'ext_' when passed as a query parameter). This key is unique across your workspace."""
2190
+
2191
+ tenant_id: Annotated[Nullable[str], pydantic.Field(alias="tenantId")]
2192
+ r"""The ID of the tenant that created the link inside your system. If set, it can be used to fetch all links for a tenant."""
2193
+
2194
+ program_id: Annotated[Nullable[str], pydantic.Field(alias="programId")]
2195
+ r"""The ID of the program the short link is associated with."""
2196
+
2197
+ partner_id: Annotated[Nullable[str], pydantic.Field(alias="partnerId")]
2198
+ r"""The ID of the partner the short link is associated with."""
2199
+
2200
+ archived: bool
2201
+
2202
+ expires_at: Annotated[str, pydantic.Field(alias="expiresAt")]
2203
+
2204
+ expired_url: Annotated[Nullable[str], pydantic.Field(alias="expiredUrl")]
2205
+
2206
+ disabled_at: Annotated[str, pydantic.Field(alias="disabledAt")]
2207
+
2208
+ password: Nullable[str]
2209
+ r"""The password required to access the destination URL of the short link."""
2210
+
2211
+ proxy: bool
2212
+
2213
+ title: Nullable[str]
2214
+ r"""The title of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2215
+
2216
+ description: Nullable[str]
2217
+ r"""The description of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2218
+
2219
+ image: Nullable[str]
2220
+ r"""The image of the short link. Will be used for Custom Link Previews if `proxy` is true."""
2221
+
2222
+ video: Nullable[str]
2223
+ r"""The custom link preview video (og:video). Will be used for Custom Link Previews if `proxy` is true. Learn more: https://d.to/og"""
2224
+
2225
+ rewrite: bool
2226
+
2227
+ do_index: Annotated[bool, pydantic.Field(alias="doIndex")]
2228
+
2229
+ ios: Nullable[str]
2230
+ r"""The iOS destination URL for the short link for iOS device targeting."""
2231
+
2232
+ android: Nullable[str]
2233
+ r"""The Android destination URL for the short link for Android device targeting."""
2234
+
2235
+ geo: Nullable[Dict[str, str]]
2236
+ r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. See https://d.to/geo for more information."""
2237
+
2238
+ public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
2239
+
2240
+ tags: Nullable[List[components_linktagschemaoutput.LinkTagSchemaOutput]]
2241
+ r"""The tags assigned to the short link."""
2242
+
2243
+ folder_id: Annotated[Nullable[str], pydantic.Field(alias="folderId")]
2244
+ r"""The unique ID of the folder assigned to the short link."""
2245
+
2246
+ webhook_ids: Annotated[List[str], pydantic.Field(alias="webhookIds")]
2247
+ r"""The IDs of the webhooks that the short link is associated with."""
2248
+
2249
+ comments: Nullable[str]
2250
+ r"""The comments for the short link."""
2251
+
2252
+ short_link: Annotated[str, pydantic.Field(alias="shortLink")]
2253
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
2254
+
2255
+ qr_code: Annotated[str, pydantic.Field(alias="qrCode")]
2256
+ r"""The full URL of the QR code for the short link (e.g. `https://api.dub.co/qr?url=https://dub.sh/try`)."""
2257
+
2258
+ utm_source: Nullable[str]
2259
+ r"""The UTM source of the short link."""
2260
+
2261
+ utm_medium: Nullable[str]
2262
+ r"""The UTM medium of the short link."""
2263
+
2264
+ utm_campaign: Nullable[str]
2265
+ r"""The UTM campaign of the short link."""
2266
+
2267
+ utm_term: Nullable[str]
2268
+ r"""The UTM term of the short link."""
2269
+
2270
+ utm_content: Nullable[str]
2271
+ r"""The UTM content of the short link."""
2272
+
2273
+ test_started_at: Annotated[str, pydantic.Field(alias="testStartedAt")]
2274
+
2275
+ test_completed_at: Annotated[str, pydantic.Field(alias="testCompletedAt")]
2276
+
2277
+ user_id: Annotated[Nullable[str], pydantic.Field(alias="userId")]
2278
+
2279
+ workspace_id: Annotated[str, pydantic.Field(alias="workspaceId")]
2280
+ r"""The workspace ID of the short link."""
2281
+
2282
+ last_clicked: Annotated[str, pydantic.Field(alias="lastClicked")]
2283
+
2284
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
2285
+
2286
+ updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]
2287
+
2288
+ tag_id: Annotated[
2289
+ Nullable[str],
2290
+ pydantic.Field(
2291
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
2292
+ alias="tagId",
2293
+ ),
2294
+ ]
2295
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
2296
+
2297
+ project_id: Annotated[
2298
+ str,
2299
+ pydantic.Field(
2300
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
2301
+ alias="projectId",
2302
+ ),
2303
+ ]
2304
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
2305
+
2306
+ test_variants: Annotated[
2307
+ OptionalNullable[List[ResponseBodyTestVariants]],
2308
+ pydantic.Field(alias="testVariants"),
2309
+ ] = UNSET
2310
+ r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
2311
+
2312
+ clicks: Optional[float] = 0
2313
+ r"""The number of clicks on the short link."""
2314
+
2315
+ leads: Optional[float] = 0
2316
+ r"""The number of leads the short link has generated."""
2317
+
2318
+ conversions: Optional[float] = 0
2319
+ r"""The number of leads that converted to paying customers."""
2320
+
2321
+ sales: Optional[float] = 0
2322
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
2323
+
2324
+ sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
2325
+ r"""The total dollar value of sales (in cents) generated by the short link."""
2326
+
2327
+ @model_serializer(mode="wrap")
2328
+ def serialize_model(self, handler):
2329
+ optional_fields = [
2330
+ "testVariants",
2331
+ "clicks",
2332
+ "leads",
2333
+ "conversions",
2334
+ "sales",
2335
+ "saleAmount",
2336
+ ]
2337
+ nullable_fields = [
2338
+ "externalId",
2339
+ "tenantId",
2340
+ "programId",
2341
+ "partnerId",
2342
+ "expiredUrl",
2343
+ "password",
2344
+ "title",
2345
+ "description",
2346
+ "image",
2347
+ "video",
2348
+ "ios",
2349
+ "android",
2350
+ "geo",
2351
+ "tags",
2352
+ "folderId",
2353
+ "comments",
2354
+ "utm_source",
2355
+ "utm_medium",
2356
+ "utm_campaign",
2357
+ "utm_term",
2358
+ "utm_content",
2359
+ "testVariants",
2360
+ "userId",
2361
+ "tagId",
2362
+ ]
2363
+ null_default_fields = []
2364
+
2365
+ serialized = handler(self)
2366
+
2367
+ m = {}
2368
+
2369
+ for n, f in type(self).model_fields.items():
2370
+ k = f.alias or n
2371
+ val = serialized.get(k)
2372
+ serialized.pop(k, None)
2373
+
2374
+ optional_nullable = k in optional_fields and k in nullable_fields
2375
+ is_set = (
2376
+ self.__pydantic_fields_set__.intersection({n})
2377
+ or k in null_default_fields
2378
+ ) # pylint: disable=no-member
2379
+
2380
+ if val is not None and val != UNSET_SENTINEL:
2381
+ m[k] = val
2382
+ elif val != UNSET_SENTINEL and (
2383
+ not k in optional_fields or (optional_nullable and is_set)
2384
+ ):
2385
+ m[k] = val
2386
+
2387
+ return m
2388
+
2389
+
2390
+ class ClickEventTypedDict(TypedDict):
2391
+ event: ResponseBodyEvent
2392
+ timestamp: str
2393
+ click: ListEventsResponseBodyEventsClickTypedDict
2394
+ link: ListEventsResponseBodyEventsLinkTypedDict
2395
+ click_id: str
2396
+ r"""Deprecated: Use `click.id` instead."""
2397
+ link_id: str
2398
+ r"""Deprecated: Use `link.id` instead."""
2399
+ domain: str
2400
+ r"""Deprecated: Use `link.domain` instead."""
2401
+ key: str
2402
+ r"""Deprecated: Use `link.key` instead."""
2403
+ url: str
2404
+ r"""Deprecated: Use `click.url` instead."""
2405
+ continent: str
2406
+ r"""Deprecated: Use `click.continent` instead."""
2407
+ country: str
2408
+ r"""Deprecated: Use `click.country` instead."""
2409
+ city: str
2410
+ r"""Deprecated: Use `click.city` instead."""
2411
+ device: str
2412
+ r"""Deprecated: Use `click.device` instead."""
2413
+ browser: str
2414
+ r"""Deprecated: Use `click.browser` instead."""
2415
+ os: str
2416
+ r"""Deprecated: Use `click.os` instead."""
2417
+ qr: float
2418
+ r"""Deprecated: Use `click.qr` instead."""
2419
+ ip: str
2420
+ r"""Deprecated: Use `click.ip` instead."""
2421
+
2422
+
2423
+ class ClickEvent(BaseModel):
2424
+ event: ResponseBodyEvent
2425
+
2426
+ timestamp: str
2427
+
2428
+ click: ListEventsResponseBodyEventsClick
2429
+
2430
+ link: ListEventsResponseBodyEventsLink
2431
+
2432
+ click_id: Annotated[
2433
+ str,
2434
+ pydantic.Field(
2435
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2436
+ ),
2437
+ ]
2438
+ r"""Deprecated: Use `click.id` instead."""
2439
+
2440
+ link_id: Annotated[
2441
+ str,
2442
+ pydantic.Field(
2443
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2444
+ ),
2445
+ ]
2446
+ r"""Deprecated: Use `link.id` instead."""
2447
+
2448
+ domain: Annotated[
2449
+ str,
2450
+ pydantic.Field(
2451
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2452
+ ),
2453
+ ]
2454
+ r"""Deprecated: Use `link.domain` instead."""
2455
+
2456
+ key: Annotated[
2457
+ str,
2458
+ pydantic.Field(
2459
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2460
+ ),
2461
+ ]
2462
+ r"""Deprecated: Use `link.key` instead."""
2463
+
2464
+ url: Annotated[
2465
+ str,
2466
+ pydantic.Field(
2467
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2468
+ ),
2469
+ ]
2470
+ r"""Deprecated: Use `click.url` instead."""
2471
+
2472
+ continent: Annotated[
2473
+ str,
2474
+ pydantic.Field(
2475
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2476
+ ),
2477
+ ]
2478
+ r"""Deprecated: Use `click.continent` instead."""
2479
+
2480
+ country: Annotated[
2481
+ str,
2482
+ pydantic.Field(
2483
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2484
+ ),
2485
+ ]
2486
+ r"""Deprecated: Use `click.country` instead."""
2487
+
2488
+ city: Annotated[
2489
+ str,
2490
+ pydantic.Field(
2491
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2492
+ ),
2493
+ ]
2494
+ r"""Deprecated: Use `click.city` instead."""
2495
+
2496
+ device: Annotated[
2497
+ str,
2498
+ pydantic.Field(
2499
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2500
+ ),
2501
+ ]
2502
+ r"""Deprecated: Use `click.device` instead."""
2503
+
2504
+ browser: Annotated[
2505
+ str,
2506
+ pydantic.Field(
2507
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2508
+ ),
2509
+ ]
2510
+ r"""Deprecated: Use `click.browser` instead."""
2511
+
2512
+ os: Annotated[
2513
+ str,
2514
+ pydantic.Field(
2515
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2516
+ ),
2517
+ ]
2518
+ r"""Deprecated: Use `click.os` instead."""
2519
+
2520
+ qr: Annotated[
2521
+ float,
2522
+ pydantic.Field(
2523
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2524
+ ),
2525
+ ]
2526
+ r"""Deprecated: Use `click.qr` instead."""
2527
+
2528
+ ip: Annotated[
2529
+ str,
2530
+ pydantic.Field(
2531
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible."
2532
+ ),
2533
+ ]
2534
+ r"""Deprecated: Use `click.ip` instead."""
2535
+
2536
+
2537
+ ListEventsResponseBodyTypedDict = TypeAliasType(
2538
+ "ListEventsResponseBodyTypedDict",
2539
+ Union[ClickEventTypedDict, LeadEventTypedDict, SaleEventTypedDict],
545
2540
  )
546
2541
 
547
2542
 
548
2543
  ListEventsResponseBody = Annotated[
549
2544
  Union[
550
- Annotated[components_clickevent.ClickEvent, Tag("click")],
551
- Annotated[components_leadevent.LeadEvent, Tag("lead")],
552
- Annotated[components_saleevent.SaleEvent, Tag("sale")],
2545
+ Annotated[ClickEvent, Tag("click")],
2546
+ Annotated[LeadEvent, Tag("lead")],
2547
+ Annotated[SaleEvent, Tag("sale")],
553
2548
  ],
554
2549
  Discriminator(lambda m: get_discriminator(m, "event", "event")),
555
2550
  ]