@wevion/cli 1.0.3920 → 1.0.3923

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 (2) hide show
  1. package/openapi.json +2007 -827
  2. package/package.json +1 -1
package/openapi.json CHANGED
@@ -323884,6 +323884,7 @@
323884
323884
  "type": "string"
323885
323885
  },
323886
323886
  "white_page_id": {
323887
+ "description": "Shield landing page shown to bots and to the suspect cohort. Must be a landing page with page_kind \"safe\"; a flow (money) page is rejected with 400.",
323887
323888
  "anyOf": [
323888
323889
  {
323889
323890
  "format": "uuid",
@@ -325077,6 +325078,7 @@
325077
325078
  "type": "string"
325078
325079
  },
325079
325080
  "white_page_id": {
325081
+ "description": "Shield landing page shown to bots and to the suspect cohort. Must be a landing page with page_kind \"safe\"; a flow (money) page is rejected with 400.",
325080
325082
  "anyOf": [
325081
325083
  {
325082
325084
  "format": "uuid",
@@ -326521,6 +326523,7 @@
326521
326523
  "type": "boolean"
326522
326524
  },
326523
326525
  "black_page_id": {
326526
+ "description": "Flow primary (money) page served to a HUMAN visitor. Must be a landing page with page_kind \"money\"; a shield page is rejected with 400.",
326524
326527
  "anyOf": [
326525
326528
  {
326526
326529
  "format": "uuid",
@@ -326753,6 +326756,7 @@
326753
326756
  }
326754
326757
  },
326755
326758
  "white_page_id": {
326759
+ "description": "Shield landing page shown to bots and to the suspect cohort. Must be a landing page with page_kind \"safe\"; a flow (money) page is rejected with 400.",
326756
326760
  "anyOf": [
326757
326761
  {
326758
326762
  "format": "uuid",
@@ -327918,7 +327922,7 @@
327918
327922
  "tags": [
327919
327923
  "traffic-filter"
327920
327924
  ],
327921
- "description": "Returns a paginated, team-scoped list of click rows. All filters are optional: campaign_id, verdict, country, device_type, dateFrom, dateTo, limit (default 50), offset.",
327925
+ "description": "Returns a paginated, team-scoped list of click rows. All filters are optional: campaign_id, verdict, served_page_kind ('safe' | 'money' | 'offer'), country, device_type, dateFrom, dateTo, limit (default 50), offset.",
327922
327926
  "parameters": [
327923
327927
  {
327924
327928
  "schema": {
@@ -327938,6 +327942,16 @@
327938
327942
  "name": "verdict",
327939
327943
  "required": false
327940
327944
  },
327945
+ {
327946
+ "schema": {
327947
+ "maxLength": 40,
327948
+ "type": "string"
327949
+ },
327950
+ "in": "query",
327951
+ "name": "served_page_kind",
327952
+ "required": false,
327953
+ "description": "Keep only clicks served that page: 'safe', 'money' or 'offer'."
327954
+ },
327941
327955
  {
327942
327956
  "schema": {
327943
327957
  "maxLength": 10,
@@ -328090,6 +328104,7 @@
328090
328104
  "os",
328091
328105
  "browser",
328092
328106
  "referrer",
328107
+ "servedPageKind",
328093
328108
  "isUnique",
328094
328109
  "subId1",
328095
328110
  "subId2",
@@ -328261,6 +328276,17 @@
328261
328276
  }
328262
328277
  ]
328263
328278
  },
328279
+ "servedPageKind": {
328280
+ "description": "Page actually served to the visitor: 'safe', 'money' or 'offer'. Null on legacy clicks.",
328281
+ "anyOf": [
328282
+ {
328283
+ "type": "string"
328284
+ },
328285
+ {
328286
+ "type": "null"
328287
+ }
328288
+ ]
328289
+ },
328264
328290
  "isUnique": {
328265
328291
  "type": "boolean"
328266
328292
  },
@@ -328453,7 +328479,7 @@
328453
328479
  "tags": [
328454
328480
  "traffic-filter"
328455
328481
  ],
328456
- "description": "Returns matching click rows as a CSV download. Accepts the same filters as /clicks (campaign_id, verdict, country, device_type, dateFrom, dateTo). Capped at 50k rows.",
328482
+ "description": "Returns matching click rows as a CSV download. Accepts the same filters as /clicks (campaign_id, verdict, served_page_kind, country, device_type, dateFrom, dateTo). Capped at 50k rows.",
328457
328483
  "parameters": [
328458
328484
  {
328459
328485
  "schema": {
@@ -328473,6 +328499,16 @@
328473
328499
  "name": "verdict",
328474
328500
  "required": false
328475
328501
  },
328502
+ {
328503
+ "schema": {
328504
+ "maxLength": 40,
328505
+ "type": "string"
328506
+ },
328507
+ "in": "query",
328508
+ "name": "served_page_kind",
328509
+ "required": false,
328510
+ "description": "Keep only clicks served that page: 'safe', 'money' or 'offer'."
328511
+ },
328476
328512
  {
328477
328513
  "schema": {
328478
328514
  "maxLength": 10,
@@ -328675,6 +328711,7 @@
328675
328711
  "subId10",
328676
328712
  "currency",
328677
328713
  "cost",
328714
+ "servedPageKind",
328678
328715
  "isUnique",
328679
328716
  "createdAt"
328680
328717
  ],
@@ -328994,6 +329031,17 @@
328994
329031
  }
328995
329032
  ]
328996
329033
  },
329034
+ "servedPageKind": {
329035
+ "description": "Page actually served to the visitor: 'safe', 'money' or 'offer'. Null on legacy clicks.",
329036
+ "anyOf": [
329037
+ {
329038
+ "type": "string"
329039
+ },
329040
+ {
329041
+ "type": "null"
329042
+ }
329043
+ ]
329044
+ },
328997
329045
  "isUnique": {
328998
329046
  "type": "boolean"
328999
329047
  },
@@ -330423,7 +330471,8 @@
330423
330471
  "verificationRecordName",
330424
330472
  "verificationRecordValue",
330425
330473
  "ownershipVerifiedAt",
330426
- "createdAt"
330474
+ "createdAt",
330475
+ "isTestDomain"
330427
330476
  ],
330428
330477
  "properties": {
330429
330478
  "id": {
@@ -330528,6 +330577,10 @@
330528
330577
  },
330529
330578
  "campaignCount": {
330530
330579
  "type": "number"
330580
+ },
330581
+ "isTestDomain": {
330582
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
330583
+ "type": "boolean"
330531
330584
  }
330532
330585
  }
330533
330586
  }
@@ -330752,7 +330805,8 @@
330752
330805
  "verificationRecordName",
330753
330806
  "verificationRecordValue",
330754
330807
  "ownershipVerifiedAt",
330755
- "createdAt"
330808
+ "createdAt",
330809
+ "isTestDomain"
330756
330810
  ],
330757
330811
  "properties": {
330758
330812
  "id": {
@@ -330857,6 +330911,10 @@
330857
330911
  },
330858
330912
  "campaignCount": {
330859
330913
  "type": "number"
330914
+ },
330915
+ "isTestDomain": {
330916
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
330917
+ "type": "boolean"
330860
330918
  }
330861
330919
  }
330862
330920
  }
@@ -331140,7 +331198,8 @@
331140
331198
  "verificationRecordName",
331141
331199
  "verificationRecordValue",
331142
331200
  "ownershipVerifiedAt",
331143
- "createdAt"
331201
+ "createdAt",
331202
+ "isTestDomain"
331144
331203
  ],
331145
331204
  "properties": {
331146
331205
  "id": {
@@ -331245,6 +331304,10 @@
331245
331304
  },
331246
331305
  "campaignCount": {
331247
331306
  "type": "number"
331307
+ },
331308
+ "isTestDomain": {
331309
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
331310
+ "type": "boolean"
331248
331311
  }
331249
331312
  }
331250
331313
  }
@@ -331487,7 +331550,8 @@
331487
331550
  "verificationRecordName",
331488
331551
  "verificationRecordValue",
331489
331552
  "ownershipVerifiedAt",
331490
- "createdAt"
331553
+ "createdAt",
331554
+ "isTestDomain"
331491
331555
  ],
331492
331556
  "properties": {
331493
331557
  "id": {
@@ -331592,6 +331656,10 @@
331592
331656
  },
331593
331657
  "campaignCount": {
331594
331658
  "type": "number"
331659
+ },
331660
+ "isTestDomain": {
331661
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
331662
+ "type": "boolean"
331595
331663
  }
331596
331664
  }
331597
331665
  }
@@ -332271,7 +332339,8 @@
332271
332339
  "verificationRecordName",
332272
332340
  "verificationRecordValue",
332273
332341
  "ownershipVerifiedAt",
332274
- "createdAt"
332342
+ "createdAt",
332343
+ "isTestDomain"
332275
332344
  ],
332276
332345
  "properties": {
332277
332346
  "id": {
@@ -332376,6 +332445,10 @@
332376
332445
  },
332377
332446
  "campaignCount": {
332378
332447
  "type": "number"
332448
+ },
332449
+ "isTestDomain": {
332450
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
332451
+ "type": "boolean"
332379
332452
  }
332380
332453
  }
332381
332454
  }
@@ -332558,24 +332631,49 @@
332558
332631
  }
332559
332632
  }
332560
332633
  },
332561
- "/api/v1/traffic-filter/domains/{id}/verify": {
332634
+ "/api/v1/traffic-filter/domains/platform-subdomain/test": {
332562
332635
  "post": {
332563
- "operationId": "postApiV1TrafficFilterDomainsByIdVerify",
332564
- "summary": "Verify a Traffic Filter domain",
332636
+ "operationId": "postApiV1TrafficFilterDomainsPlatformSubdomainTest",
332637
+ "summary": "Issue a test-only subdomain",
332565
332638
  "tags": [
332566
332639
  "traffic-filter"
332567
332640
  ],
332568
- "description": "Activates a direct A-record only after its TXT ownership challenge is proven. An exact team-owned Cloudflare zone or an in-app NameSilo purchase is accepted as server-side ownership proof.",
332641
+ "description": "Issues a ready-to-use throwaway subdomain under the platform base suffix, with a server-generated label and no DNS setup, so a campaign can be assembled without owning a domain. The host sits on shared platform infrastructure: it is flagged isTestDomain and must never carry production traffic. Requires acknowledge_testing_only:true.",
332642
+ "requestBody": {
332643
+ "required": true,
332644
+ "content": {
332645
+ "application/json": {
332646
+ "schema": {
332647
+ "additionalProperties": false,
332648
+ "type": "object",
332649
+ "required": [
332650
+ "acknowledge_testing_only"
332651
+ ],
332652
+ "properties": {
332653
+ "acknowledge_testing_only": {
332654
+ "description": "Must be true: the caller states the host will only be used for testing.",
332655
+ "type": "boolean",
332656
+ "enum": [
332657
+ true
332658
+ ]
332659
+ },
332660
+ "team_id": {
332661
+ "anyOf": [
332662
+ {
332663
+ "format": "uuid",
332664
+ "type": "string"
332665
+ },
332666
+ {
332667
+ "type": "null"
332668
+ }
332669
+ ]
332670
+ }
332671
+ }
332672
+ }
332673
+ }
332674
+ }
332675
+ },
332569
332676
  "parameters": [
332570
- {
332571
- "schema": {
332572
- "format": "uuid",
332573
- "type": "string"
332574
- },
332575
- "in": "path",
332576
- "name": "id",
332577
- "required": true
332578
- },
332579
332677
  {
332580
332678
  "schema": {
332581
332679
  "format": "uuid",
@@ -332596,37 +332694,56 @@
332596
332694
  }
332597
332695
  ],
332598
332696
  "responses": {
332599
- "200": {
332600
- "description": "Successful response",
332697
+ "201": {
332698
+ "description": "Resource created",
332601
332699
  "content": {
332602
332700
  "application/json": {
332603
332701
  "schema": {
332604
332702
  "type": "object",
332605
332703
  "required": [
332606
332704
  "id",
332705
+ "teamId",
332607
332706
  "domain",
332707
+ "importMethod",
332608
332708
  "status",
332609
- "verified",
332610
- "message"
332709
+ "zoneId",
332710
+ "nameservers",
332711
+ "serverIp",
332712
+ "expiresAt",
332713
+ "errorMessage",
332714
+ "verificationToken",
332715
+ "verificationRecordName",
332716
+ "verificationRecordValue",
332717
+ "ownershipVerifiedAt",
332718
+ "createdAt",
332719
+ "isTestDomain"
332611
332720
  ],
332612
332721
  "properties": {
332613
332722
  "id": {
332614
332723
  "format": "uuid",
332615
332724
  "type": "string"
332616
332725
  },
332617
- "domain": {
332726
+ "teamId": {
332727
+ "format": "uuid",
332618
332728
  "type": "string"
332619
332729
  },
332620
- "status": {
332730
+ "domain": {
332621
332731
  "type": "string"
332622
332732
  },
332623
- "verified": {
332624
- "type": "boolean"
332733
+ "importMethod": {
332734
+ "anyOf": [
332735
+ {
332736
+ "type": "string"
332737
+ },
332738
+ {
332739
+ "type": "null"
332740
+ }
332741
+ ]
332625
332742
  },
332626
- "message": {
332743
+ "status": {
332627
332744
  "type": "string"
332628
332745
  },
332629
- "resolvedIp": {
332746
+ "zoneId": {
332630
332747
  "anyOf": [
332631
332748
  {
332632
332749
  "type": "string"
@@ -332636,11 +332753,16 @@
332636
332753
  }
332637
332754
  ]
332638
332755
  },
332639
- "resolvedIps": {
332640
- "type": "array",
332641
- "items": {
332642
- "type": "string"
332643
- }
332756
+ "nameservers": {
332757
+ "anyOf": [
332758
+ {
332759
+ "$comment": "json-value",
332760
+ "description": "Arbitrary JSON value with nested arrays and objects."
332761
+ },
332762
+ {
332763
+ "type": "null"
332764
+ }
332765
+ ]
332644
332766
  },
332645
332767
  "serverIp": {
332646
332768
  "anyOf": [
@@ -332652,87 +332774,57 @@
332652
332774
  }
332653
332775
  ]
332654
332776
  },
332655
- "viaCloudflare": {
332656
- "type": "boolean"
332657
- },
332658
- "txtVerified": {
332659
- "type": "boolean"
332660
- },
332661
- "verificationRecordName": {
332662
- "type": "string"
332663
- },
332664
- "verificationRecordValue": {
332665
- "type": "string"
332777
+ "expiresAt": {
332778
+ "anyOf": [
332779
+ {
332780
+ "format": "date-time",
332781
+ "type": "string"
332782
+ },
332783
+ {
332784
+ "type": "null"
332785
+ }
332786
+ ]
332666
332787
  },
332667
- "dnsRecords": {
332788
+ "errorMessage": {
332668
332789
  "anyOf": [
332669
332790
  {
332670
- "type": "array",
332671
- "items": {
332672
- "type": "object",
332673
- "required": [
332674
- "recordId",
332675
- "type",
332676
- "host",
332677
- "value",
332678
- "ttl",
332679
- "distance"
332680
- ],
332681
- "properties": {
332682
- "recordId": {
332683
- "type": "string"
332684
- },
332685
- "type": {
332686
- "type": "string"
332687
- },
332688
- "host": {
332689
- "type": "string"
332690
- },
332691
- "value": {
332692
- "type": "string"
332693
- },
332694
- "ttl": {
332695
- "type": "number"
332696
- },
332697
- "distance": {
332698
- "type": "number"
332699
- }
332700
- }
332701
- }
332791
+ "type": "string"
332702
332792
  },
332703
332793
  {
332704
332794
  "type": "null"
332705
332795
  }
332706
332796
  ]
332707
332797
  },
332708
- "availability": {
332798
+ "verificationToken": {
332799
+ "type": "string"
332800
+ },
332801
+ "verificationRecordName": {
332802
+ "type": "string"
332803
+ },
332804
+ "verificationRecordValue": {
332805
+ "type": "string"
332806
+ },
332807
+ "ownershipVerifiedAt": {
332709
332808
  "anyOf": [
332710
332809
  {
332711
- "type": "object",
332712
- "required": [
332713
- "available",
332714
- "price"
332715
- ],
332716
- "properties": {
332717
- "available": {
332718
- "type": "boolean"
332719
- },
332720
- "price": {
332721
- "anyOf": [
332722
- {
332723
- "type": "number"
332724
- },
332725
- {
332726
- "type": "null"
332727
- }
332728
- ]
332729
- }
332730
- }
332810
+ "format": "date-time",
332811
+ "type": "string"
332731
332812
  },
332732
332813
  {
332733
332814
  "type": "null"
332734
332815
  }
332735
332816
  ]
332817
+ },
332818
+ "createdAt": {
332819
+ "format": "date-time",
332820
+ "type": "string"
332821
+ },
332822
+ "campaignCount": {
332823
+ "type": "number"
332824
+ },
332825
+ "isTestDomain": {
332826
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
332827
+ "type": "boolean"
332736
332828
  }
332737
332829
  }
332738
332830
  }
@@ -332832,8 +332924,8 @@
332832
332924
  }
332833
332925
  }
332834
332926
  },
332835
- "404": {
332836
- "description": "Resource not found",
332927
+ "409": {
332928
+ "description": "Conflict - resource state prevents the operation",
332837
332929
  "content": {
332838
332930
  "application/json": {
332839
332931
  "schema": {
@@ -332915,23 +333007,22 @@
332915
333007
  }
332916
333008
  }
332917
333009
  },
332918
- "/api/v1/traffic-filter/domains/check-availability": {
332919
- "get": {
332920
- "operationId": "getApiV1TrafficFilterDomainsCheckAvailability",
332921
- "summary": "Check domain availability",
333010
+ "/api/v1/traffic-filter/domains/{id}/verify": {
333011
+ "post": {
333012
+ "operationId": "postApiV1TrafficFilterDomainsByIdVerify",
333013
+ "summary": "Verify a Traffic Filter domain",
332922
333014
  "tags": [
332923
333015
  "traffic-filter"
332924
333016
  ],
332925
- "description": "Checks whether a domain is available for registration via Namesilo.",
333017
+ "description": "Activates a direct A-record only after its TXT ownership challenge is proven. An exact team-owned Cloudflare zone or an in-app NameSilo purchase is accepted as server-side ownership proof.",
332926
333018
  "parameters": [
332927
333019
  {
332928
333020
  "schema": {
332929
- "minLength": 1,
332930
- "maxLength": 255,
333021
+ "format": "uuid",
332931
333022
  "type": "string"
332932
333023
  },
332933
- "in": "query",
332934
- "name": "domain",
333024
+ "in": "path",
333025
+ "name": "id",
332935
333026
  "required": true
332936
333027
  },
332937
333028
  {
@@ -332961,18 +333052,136 @@
332961
333052
  "schema": {
332962
333053
  "type": "object",
332963
333054
  "required": [
333055
+ "id",
332964
333056
  "domain",
332965
- "available"
333057
+ "status",
333058
+ "verified",
333059
+ "message"
332966
333060
  ],
332967
333061
  "properties": {
333062
+ "id": {
333063
+ "format": "uuid",
333064
+ "type": "string"
333065
+ },
332968
333066
  "domain": {
332969
333067
  "type": "string"
332970
333068
  },
332971
- "available": {
333069
+ "status": {
333070
+ "type": "string"
333071
+ },
333072
+ "verified": {
332972
333073
  "type": "boolean"
332973
333074
  },
332974
- "price": {
332975
- "type": "number"
333075
+ "message": {
333076
+ "type": "string"
333077
+ },
333078
+ "resolvedIp": {
333079
+ "anyOf": [
333080
+ {
333081
+ "type": "string"
333082
+ },
333083
+ {
333084
+ "type": "null"
333085
+ }
333086
+ ]
333087
+ },
333088
+ "resolvedIps": {
333089
+ "type": "array",
333090
+ "items": {
333091
+ "type": "string"
333092
+ }
333093
+ },
333094
+ "serverIp": {
333095
+ "anyOf": [
333096
+ {
333097
+ "type": "string"
333098
+ },
333099
+ {
333100
+ "type": "null"
333101
+ }
333102
+ ]
333103
+ },
333104
+ "viaCloudflare": {
333105
+ "type": "boolean"
333106
+ },
333107
+ "txtVerified": {
333108
+ "type": "boolean"
333109
+ },
333110
+ "verificationRecordName": {
333111
+ "type": "string"
333112
+ },
333113
+ "verificationRecordValue": {
333114
+ "type": "string"
333115
+ },
333116
+ "dnsRecords": {
333117
+ "anyOf": [
333118
+ {
333119
+ "type": "array",
333120
+ "items": {
333121
+ "type": "object",
333122
+ "required": [
333123
+ "recordId",
333124
+ "type",
333125
+ "host",
333126
+ "value",
333127
+ "ttl",
333128
+ "distance"
333129
+ ],
333130
+ "properties": {
333131
+ "recordId": {
333132
+ "type": "string"
333133
+ },
333134
+ "type": {
333135
+ "type": "string"
333136
+ },
333137
+ "host": {
333138
+ "type": "string"
333139
+ },
333140
+ "value": {
333141
+ "type": "string"
333142
+ },
333143
+ "ttl": {
333144
+ "type": "number"
333145
+ },
333146
+ "distance": {
333147
+ "type": "number"
333148
+ }
333149
+ }
333150
+ }
333151
+ },
333152
+ {
333153
+ "type": "null"
333154
+ }
333155
+ ]
333156
+ },
333157
+ "availability": {
333158
+ "anyOf": [
333159
+ {
333160
+ "type": "object",
333161
+ "required": [
333162
+ "available",
333163
+ "price"
333164
+ ],
333165
+ "properties": {
333166
+ "available": {
333167
+ "type": "boolean"
333168
+ },
333169
+ "price": {
333170
+ "anyOf": [
333171
+ {
333172
+ "type": "number"
333173
+ },
333174
+ {
333175
+ "type": "null"
333176
+ }
333177
+ ]
333178
+ }
333179
+ }
333180
+ },
333181
+ {
333182
+ "type": "null"
333183
+ }
333184
+ ]
332976
333185
  }
332977
333186
  }
332978
333187
  }
@@ -333072,18 +333281,8 @@
333072
333281
  }
333073
333282
  }
333074
333283
  },
333075
- "429": {
333076
- "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
333077
- "content": {
333078
- "application/json": {
333079
- "schema": {
333080
- "$ref": "#/components/schemas/RateLimitedResponse"
333081
- }
333082
- }
333083
- }
333084
- },
333085
- "500": {
333086
- "description": "Internal server error",
333284
+ "404": {
333285
+ "description": "Resource not found",
333087
333286
  "content": {
333088
333287
  "application/json": {
333089
333288
  "schema": {
@@ -333108,8 +333307,18 @@
333108
333307
  }
333109
333308
  }
333110
333309
  },
333111
- "502": {
333112
- "description": "Bad gateway - upstream provider failed",
333310
+ "429": {
333311
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
333312
+ "content": {
333313
+ "application/json": {
333314
+ "schema": {
333315
+ "$ref": "#/components/schemas/RateLimitedResponse"
333316
+ }
333317
+ }
333318
+ }
333319
+ },
333320
+ "500": {
333321
+ "description": "Internal server error",
333113
333322
  "content": {
333114
333323
  "application/json": {
333115
333324
  "schema": {
@@ -333153,41 +333362,27 @@
333153
333362
  }
333154
333363
  }
333155
333364
  }
333156
- },
333157
- "post": {
333158
- "operationId": "postApiV1TrafficFilterDomainsCheckAvailability",
333159
- "summary": "Bulk check domain availability",
333365
+ }
333366
+ },
333367
+ "/api/v1/traffic-filter/domains/check-availability": {
333368
+ "get": {
333369
+ "operationId": "getApiV1TrafficFilterDomainsCheckAvailability",
333370
+ "summary": "Check domain availability",
333160
333371
  "tags": [
333161
333372
  "traffic-filter"
333162
333373
  ],
333163
- "description": "Checks availability for multiple domains via Namesilo (max 20).",
333164
- "requestBody": {
333165
- "required": true,
333166
- "content": {
333167
- "application/json": {
333168
- "schema": {
333169
- "additionalProperties": false,
333170
- "type": "object",
333171
- "required": [
333172
- "domains"
333173
- ],
333174
- "properties": {
333175
- "domains": {
333176
- "minItems": 1,
333177
- "maxItems": 20,
333178
- "type": "array",
333179
- "items": {
333180
- "minLength": 1,
333181
- "maxLength": 255,
333182
- "type": "string"
333183
- }
333184
- }
333185
- }
333186
- }
333187
- }
333188
- }
333189
- },
333374
+ "description": "Checks whether a domain is available for registration via Namesilo.",
333190
333375
  "parameters": [
333376
+ {
333377
+ "schema": {
333378
+ "minLength": 1,
333379
+ "maxLength": 255,
333380
+ "type": "string"
333381
+ },
333382
+ "in": "query",
333383
+ "name": "domain",
333384
+ "required": true
333385
+ },
333191
333386
  {
333192
333387
  "schema": {
333193
333388
  "format": "uuid",
@@ -333215,46 +333410,24 @@
333215
333410
  "schema": {
333216
333411
  "type": "object",
333217
333412
  "required": [
333218
- "results"
333413
+ "domain",
333414
+ "available"
333219
333415
  ],
333220
333416
  "properties": {
333221
- "results": {
333222
- "type": "array",
333223
- "items": {
333224
- "type": "object",
333225
- "required": [
333226
- "domain",
333227
- "available",
333228
- "price"
333229
- ],
333230
- "properties": {
333231
- "domain": {
333232
- "type": "string"
333233
- },
333234
- "available": {
333235
- "type": "boolean"
333236
- },
333237
- "price": {
333238
- "anyOf": [
333239
- {
333240
- "type": "number"
333241
- },
333242
- {
333243
- "type": "null"
333244
- }
333245
- ]
333246
- },
333247
- "error": {
333248
- "type": "string"
333249
- }
333250
- }
333251
- }
333252
- }
333253
- }
333254
- }
333255
- }
333256
- }
333257
- },
333417
+ "domain": {
333418
+ "type": "string"
333419
+ },
333420
+ "available": {
333421
+ "type": "boolean"
333422
+ },
333423
+ "price": {
333424
+ "type": "number"
333425
+ }
333426
+ }
333427
+ }
333428
+ }
333429
+ }
333430
+ },
333258
333431
  "400": {
333259
333432
  "description": "Invalid request - schema validation failed",
333260
333433
  "content": {
@@ -333384,6 +333557,32 @@
333384
333557
  }
333385
333558
  }
333386
333559
  },
333560
+ "502": {
333561
+ "description": "Bad gateway - upstream provider failed",
333562
+ "content": {
333563
+ "application/json": {
333564
+ "schema": {
333565
+ "type": "object",
333566
+ "required": [
333567
+ "statusCode",
333568
+ "error",
333569
+ "message"
333570
+ ],
333571
+ "properties": {
333572
+ "statusCode": {
333573
+ "type": "number"
333574
+ },
333575
+ "error": {
333576
+ "type": "string"
333577
+ },
333578
+ "message": {
333579
+ "type": "string"
333580
+ }
333581
+ }
333582
+ }
333583
+ }
333584
+ }
333585
+ },
333387
333586
  "503": {
333388
333587
  "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
333389
333588
  "headers": {
@@ -333403,16 +333602,14 @@
333403
333602
  }
333404
333603
  }
333405
333604
  }
333406
- }
333407
- },
333408
- "/api/v1/traffic-filter/domains/register": {
333605
+ },
333409
333606
  "post": {
333410
- "operationId": "postApiV1TrafficFilterDomainsRegister",
333411
- "summary": "Register a domain via Namesilo",
333607
+ "operationId": "postApiV1TrafficFilterDomainsCheckAvailability",
333608
+ "summary": "Bulk check domain availability",
333412
333609
  "tags": [
333413
333610
  "traffic-filter"
333414
333611
  ],
333415
- "description": "Registers a domain through Namesilo (paid). Requires confirm:true to proceed.",
333612
+ "description": "Checks availability for multiple domains via Namesilo (max 20).",
333416
333613
  "requestBody": {
333417
333614
  "required": true,
333418
333615
  "content": {
@@ -333421,21 +333618,18 @@
333421
333618
  "additionalProperties": false,
333422
333619
  "type": "object",
333423
333620
  "required": [
333424
- "domain"
333621
+ "domains"
333425
333622
  ],
333426
333623
  "properties": {
333427
- "domain": {
333428
- "minLength": 1,
333429
- "maxLength": 255,
333430
- "type": "string"
333431
- },
333432
- "years": {
333433
- "minimum": 1,
333434
- "maximum": 10,
333435
- "type": "integer"
333436
- },
333437
- "confirm": {
333438
- "type": "boolean"
333624
+ "domains": {
333625
+ "minItems": 1,
333626
+ "maxItems": 20,
333627
+ "type": "array",
333628
+ "items": {
333629
+ "minLength": 1,
333630
+ "maxLength": 255,
333631
+ "type": "string"
333632
+ }
333439
333633
  }
333440
333634
  }
333441
333635
  }
@@ -333463,149 +333657,45 @@
333463
333657
  }
333464
333658
  ],
333465
333659
  "responses": {
333466
- "201": {
333467
- "description": "Resource created",
333660
+ "200": {
333661
+ "description": "Successful response",
333468
333662
  "content": {
333469
333663
  "application/json": {
333470
333664
  "schema": {
333471
333665
  "type": "object",
333472
333666
  "required": [
333473
- "orderId",
333474
- "domain"
333667
+ "results"
333475
333668
  ],
333476
333669
  "properties": {
333477
- "orderId": {
333478
- "anyOf": [
333479
- {
333480
- "type": "string"
333481
- },
333482
- {
333483
- "type": "null"
333484
- }
333485
- ]
333486
- },
333487
- "domain": {
333488
- "type": "object",
333489
- "required": [
333490
- "id",
333491
- "teamId",
333492
- "domain",
333493
- "importMethod",
333494
- "status",
333495
- "zoneId",
333496
- "nameservers",
333497
- "serverIp",
333498
- "expiresAt",
333499
- "errorMessage",
333500
- "verificationToken",
333501
- "verificationRecordName",
333502
- "verificationRecordValue",
333503
- "ownershipVerifiedAt",
333504
- "createdAt"
333505
- ],
333506
- "properties": {
333507
- "id": {
333508
- "format": "uuid",
333509
- "type": "string"
333510
- },
333511
- "teamId": {
333512
- "format": "uuid",
333513
- "type": "string"
333514
- },
333515
- "domain": {
333516
- "type": "string"
333517
- },
333518
- "importMethod": {
333519
- "anyOf": [
333520
- {
333521
- "type": "string"
333522
- },
333523
- {
333524
- "type": "null"
333525
- }
333526
- ]
333527
- },
333528
- "status": {
333529
- "type": "string"
333530
- },
333531
- "zoneId": {
333532
- "anyOf": [
333533
- {
333534
- "type": "string"
333535
- },
333536
- {
333537
- "type": "null"
333538
- }
333539
- ]
333540
- },
333541
- "nameservers": {
333542
- "anyOf": [
333543
- {
333544
- "$comment": "json-value",
333545
- "description": "Arbitrary JSON value with nested arrays and objects."
333546
- },
333547
- {
333548
- "type": "null"
333549
- }
333550
- ]
333551
- },
333552
- "serverIp": {
333553
- "anyOf": [
333554
- {
333555
- "type": "string"
333556
- },
333557
- {
333558
- "type": "null"
333559
- }
333560
- ]
333561
- },
333562
- "expiresAt": {
333563
- "anyOf": [
333564
- {
333565
- "format": "date-time",
333566
- "type": "string"
333567
- },
333568
- {
333569
- "type": "null"
333570
- }
333571
- ]
333572
- },
333573
- "errorMessage": {
333574
- "anyOf": [
333575
- {
333576
- "type": "string"
333577
- },
333578
- {
333579
- "type": "null"
333580
- }
333581
- ]
333582
- },
333583
- "verificationToken": {
333584
- "type": "string"
333585
- },
333586
- "verificationRecordName": {
333587
- "type": "string"
333588
- },
333589
- "verificationRecordValue": {
333590
- "type": "string"
333591
- },
333592
- "ownershipVerifiedAt": {
333593
- "anyOf": [
333594
- {
333595
- "format": "date-time",
333596
- "type": "string"
333597
- },
333598
- {
333599
- "type": "null"
333600
- }
333601
- ]
333602
- },
333603
- "createdAt": {
333604
- "format": "date-time",
333605
- "type": "string"
333606
- },
333607
- "campaignCount": {
333608
- "type": "number"
333670
+ "results": {
333671
+ "type": "array",
333672
+ "items": {
333673
+ "type": "object",
333674
+ "required": [
333675
+ "domain",
333676
+ "available",
333677
+ "price"
333678
+ ],
333679
+ "properties": {
333680
+ "domain": {
333681
+ "type": "string"
333682
+ },
333683
+ "available": {
333684
+ "type": "boolean"
333685
+ },
333686
+ "price": {
333687
+ "anyOf": [
333688
+ {
333689
+ "type": "number"
333690
+ },
333691
+ {
333692
+ "type": "null"
333693
+ }
333694
+ ]
333695
+ },
333696
+ "error": {
333697
+ "type": "string"
333698
+ }
333609
333699
  }
333610
333700
  }
333611
333701
  }
@@ -333707,70 +333797,18 @@
333707
333797
  }
333708
333798
  }
333709
333799
  },
333710
- "409": {
333711
- "description": "Conflict - resource state prevents the operation",
333712
- "content": {
333713
- "application/json": {
333714
- "schema": {
333715
- "type": "object",
333716
- "required": [
333717
- "statusCode",
333718
- "error",
333719
- "message"
333720
- ],
333721
- "properties": {
333722
- "statusCode": {
333723
- "type": "number"
333724
- },
333725
- "error": {
333726
- "type": "string"
333727
- },
333728
- "message": {
333729
- "type": "string"
333730
- }
333731
- }
333732
- }
333733
- }
333734
- }
333735
- },
333736
- "429": {
333737
- "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
333738
- "content": {
333739
- "application/json": {
333740
- "schema": {
333741
- "$ref": "#/components/schemas/RateLimitedResponse"
333742
- }
333743
- }
333744
- }
333745
- },
333746
- "500": {
333747
- "description": "Internal server error",
333748
- "content": {
333749
- "application/json": {
333750
- "schema": {
333751
- "type": "object",
333752
- "required": [
333753
- "statusCode",
333754
- "error",
333755
- "message"
333756
- ],
333757
- "properties": {
333758
- "statusCode": {
333759
- "type": "number"
333760
- },
333761
- "error": {
333762
- "type": "string"
333763
- },
333764
- "message": {
333765
- "type": "string"
333766
- }
333767
- }
333768
- }
333769
- }
333770
- }
333771
- },
333772
- "502": {
333773
- "description": "Bad gateway - upstream provider failed",
333800
+ "429": {
333801
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
333802
+ "content": {
333803
+ "application/json": {
333804
+ "schema": {
333805
+ "$ref": "#/components/schemas/RateLimitedResponse"
333806
+ }
333807
+ }
333808
+ }
333809
+ },
333810
+ "500": {
333811
+ "description": "Internal server error",
333774
333812
  "content": {
333775
333813
  "application/json": {
333776
333814
  "schema": {
@@ -333816,14 +333854,14 @@
333816
333854
  }
333817
333855
  }
333818
333856
  },
333819
- "/api/v1/traffic-filter/domains/import": {
333857
+ "/api/v1/traffic-filter/domains/register": {
333820
333858
  "post": {
333821
- "operationId": "postApiV1TrafficFilterDomainsImport",
333822
- "summary": "Bulk import domains (A-record)",
333859
+ "operationId": "postApiV1TrafficFilterDomainsRegister",
333860
+ "summary": "Register a domain via Namesilo",
333823
333861
  "tags": [
333824
333862
  "traffic-filter"
333825
333863
  ],
333826
- "description": "Inserts pending_dns rows for A-record domains (max 50). Each row must also pass its TXT ownership challenge before activation.",
333864
+ "description": "Registers a domain through Namesilo (paid). Requires confirm:true to proceed.",
333827
333865
  "requestBody": {
333828
333866
  "required": true,
333829
333867
  "content": {
@@ -333832,18 +333870,21 @@
333832
333870
  "additionalProperties": false,
333833
333871
  "type": "object",
333834
333872
  "required": [
333835
- "domains"
333873
+ "domain"
333836
333874
  ],
333837
333875
  "properties": {
333838
- "domains": {
333839
- "minItems": 1,
333840
- "maxItems": 50,
333841
- "type": "array",
333842
- "items": {
333843
- "minLength": 1,
333844
- "maxLength": 255,
333845
- "type": "string"
333846
- }
333876
+ "domain": {
333877
+ "minLength": 1,
333878
+ "maxLength": 255,
333879
+ "type": "string"
333880
+ },
333881
+ "years": {
333882
+ "minimum": 1,
333883
+ "maximum": 10,
333884
+ "type": "integer"
333885
+ },
333886
+ "confirm": {
333887
+ "type": "boolean"
333847
333888
  }
333848
333889
  }
333849
333890
  }
@@ -333871,27 +333912,155 @@
333871
333912
  }
333872
333913
  ],
333873
333914
  "responses": {
333874
- "200": {
333875
- "description": "Successful response",
333915
+ "201": {
333916
+ "description": "Resource created",
333876
333917
  "content": {
333877
333918
  "application/json": {
333878
333919
  "schema": {
333879
333920
  "type": "object",
333880
333921
  "required": [
333881
- "inserted",
333882
- "skipped"
333922
+ "orderId",
333923
+ "domain"
333883
333924
  ],
333884
333925
  "properties": {
333885
- "inserted": {
333886
- "type": "array",
333887
- "items": {
333888
- "type": "string"
333889
- }
333926
+ "orderId": {
333927
+ "anyOf": [
333928
+ {
333929
+ "type": "string"
333930
+ },
333931
+ {
333932
+ "type": "null"
333933
+ }
333934
+ ]
333890
333935
  },
333891
- "skipped": {
333892
- "type": "array",
333893
- "items": {
333894
- "type": "string"
333936
+ "domain": {
333937
+ "type": "object",
333938
+ "required": [
333939
+ "id",
333940
+ "teamId",
333941
+ "domain",
333942
+ "importMethod",
333943
+ "status",
333944
+ "zoneId",
333945
+ "nameservers",
333946
+ "serverIp",
333947
+ "expiresAt",
333948
+ "errorMessage",
333949
+ "verificationToken",
333950
+ "verificationRecordName",
333951
+ "verificationRecordValue",
333952
+ "ownershipVerifiedAt",
333953
+ "createdAt",
333954
+ "isTestDomain"
333955
+ ],
333956
+ "properties": {
333957
+ "id": {
333958
+ "format": "uuid",
333959
+ "type": "string"
333960
+ },
333961
+ "teamId": {
333962
+ "format": "uuid",
333963
+ "type": "string"
333964
+ },
333965
+ "domain": {
333966
+ "type": "string"
333967
+ },
333968
+ "importMethod": {
333969
+ "anyOf": [
333970
+ {
333971
+ "type": "string"
333972
+ },
333973
+ {
333974
+ "type": "null"
333975
+ }
333976
+ ]
333977
+ },
333978
+ "status": {
333979
+ "type": "string"
333980
+ },
333981
+ "zoneId": {
333982
+ "anyOf": [
333983
+ {
333984
+ "type": "string"
333985
+ },
333986
+ {
333987
+ "type": "null"
333988
+ }
333989
+ ]
333990
+ },
333991
+ "nameservers": {
333992
+ "anyOf": [
333993
+ {
333994
+ "$comment": "json-value",
333995
+ "description": "Arbitrary JSON value with nested arrays and objects."
333996
+ },
333997
+ {
333998
+ "type": "null"
333999
+ }
334000
+ ]
334001
+ },
334002
+ "serverIp": {
334003
+ "anyOf": [
334004
+ {
334005
+ "type": "string"
334006
+ },
334007
+ {
334008
+ "type": "null"
334009
+ }
334010
+ ]
334011
+ },
334012
+ "expiresAt": {
334013
+ "anyOf": [
334014
+ {
334015
+ "format": "date-time",
334016
+ "type": "string"
334017
+ },
334018
+ {
334019
+ "type": "null"
334020
+ }
334021
+ ]
334022
+ },
334023
+ "errorMessage": {
334024
+ "anyOf": [
334025
+ {
334026
+ "type": "string"
334027
+ },
334028
+ {
334029
+ "type": "null"
334030
+ }
334031
+ ]
334032
+ },
334033
+ "verificationToken": {
334034
+ "type": "string"
334035
+ },
334036
+ "verificationRecordName": {
334037
+ "type": "string"
334038
+ },
334039
+ "verificationRecordValue": {
334040
+ "type": "string"
334041
+ },
334042
+ "ownershipVerifiedAt": {
334043
+ "anyOf": [
334044
+ {
334045
+ "format": "date-time",
334046
+ "type": "string"
334047
+ },
334048
+ {
334049
+ "type": "null"
334050
+ }
334051
+ ]
334052
+ },
334053
+ "createdAt": {
334054
+ "format": "date-time",
334055
+ "type": "string"
334056
+ },
334057
+ "campaignCount": {
334058
+ "type": "number"
334059
+ },
334060
+ "isTestDomain": {
334061
+ "description": "True for a throwaway platform host issued for testing. It sits on shared infrastructure and must not carry real traffic.",
334062
+ "type": "boolean"
334063
+ }
333895
334064
  }
333896
334065
  }
333897
334066
  }
@@ -333992,20 +334161,72 @@
333992
334161
  }
333993
334162
  }
333994
334163
  },
333995
- "429": {
333996
- "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
334164
+ "409": {
334165
+ "description": "Conflict - resource state prevents the operation",
333997
334166
  "content": {
333998
334167
  "application/json": {
333999
334168
  "schema": {
334000
- "$ref": "#/components/schemas/RateLimitedResponse"
334001
- }
334002
- }
334003
- }
334004
- },
334005
- "500": {
334006
- "description": "Internal server error",
334007
- "content": {
334008
- "application/json": {
334169
+ "type": "object",
334170
+ "required": [
334171
+ "statusCode",
334172
+ "error",
334173
+ "message"
334174
+ ],
334175
+ "properties": {
334176
+ "statusCode": {
334177
+ "type": "number"
334178
+ },
334179
+ "error": {
334180
+ "type": "string"
334181
+ },
334182
+ "message": {
334183
+ "type": "string"
334184
+ }
334185
+ }
334186
+ }
334187
+ }
334188
+ }
334189
+ },
334190
+ "429": {
334191
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
334192
+ "content": {
334193
+ "application/json": {
334194
+ "schema": {
334195
+ "$ref": "#/components/schemas/RateLimitedResponse"
334196
+ }
334197
+ }
334198
+ }
334199
+ },
334200
+ "500": {
334201
+ "description": "Internal server error",
334202
+ "content": {
334203
+ "application/json": {
334204
+ "schema": {
334205
+ "type": "object",
334206
+ "required": [
334207
+ "statusCode",
334208
+ "error",
334209
+ "message"
334210
+ ],
334211
+ "properties": {
334212
+ "statusCode": {
334213
+ "type": "number"
334214
+ },
334215
+ "error": {
334216
+ "type": "string"
334217
+ },
334218
+ "message": {
334219
+ "type": "string"
334220
+ }
334221
+ }
334222
+ }
334223
+ }
334224
+ }
334225
+ },
334226
+ "502": {
334227
+ "description": "Bad gateway - upstream provider failed",
334228
+ "content": {
334229
+ "application/json": {
334009
334230
  "schema": {
334010
334231
  "type": "object",
334011
334232
  "required": [
@@ -334049,24 +334270,41 @@
334049
334270
  }
334050
334271
  }
334051
334272
  },
334052
- "/api/v1/traffic-filter/domains/{id}/auto-link-cf": {
334273
+ "/api/v1/traffic-filter/domains/import": {
334053
334274
  "post": {
334054
- "operationId": "postApiV1TrafficFilterDomainsByIdAutoLinkCf",
334055
- "summary": "Auto-link a Cloudflare zone",
334275
+ "operationId": "postApiV1TrafficFilterDomainsImport",
334276
+ "summary": "Bulk import domains (A-record)",
334056
334277
  "tags": [
334057
334278
  "traffic-filter"
334058
334279
  ],
334059
- "description": "Finds the Cloudflare zone for the domain and stores its zone id + nameservers.",
334280
+ "description": "Inserts pending_dns rows for A-record domains (max 50). Each row must also pass its TXT ownership challenge before activation.",
334281
+ "requestBody": {
334282
+ "required": true,
334283
+ "content": {
334284
+ "application/json": {
334285
+ "schema": {
334286
+ "additionalProperties": false,
334287
+ "type": "object",
334288
+ "required": [
334289
+ "domains"
334290
+ ],
334291
+ "properties": {
334292
+ "domains": {
334293
+ "minItems": 1,
334294
+ "maxItems": 50,
334295
+ "type": "array",
334296
+ "items": {
334297
+ "minLength": 1,
334298
+ "maxLength": 255,
334299
+ "type": "string"
334300
+ }
334301
+ }
334302
+ }
334303
+ }
334304
+ }
334305
+ }
334306
+ },
334060
334307
  "parameters": [
334061
- {
334062
- "schema": {
334063
- "format": "uuid",
334064
- "type": "string"
334065
- },
334066
- "in": "path",
334067
- "name": "id",
334068
- "required": true
334069
- },
334070
334308
  {
334071
334309
  "schema": {
334072
334310
  "format": "uuid",
@@ -334094,29 +334332,21 @@
334094
334332
  "schema": {
334095
334333
  "type": "object",
334096
334334
  "required": [
334097
- "ok"
334335
+ "inserted",
334336
+ "skipped"
334098
334337
  ],
334099
334338
  "properties": {
334100
- "ok": {
334101
- "type": "boolean"
334102
- },
334103
- "zoneId": {
334104
- "type": "string"
334105
- },
334106
- "nameservers": {
334339
+ "inserted": {
334107
334340
  "type": "array",
334108
334341
  "items": {
334109
334342
  "type": "string"
334110
334343
  }
334111
334344
  },
334112
- "zoneStatus": {
334113
- "type": "string"
334114
- },
334115
- "alreadyLinked": {
334116
- "type": "boolean"
334117
- },
334118
- "error": {
334119
- "type": "string"
334345
+ "skipped": {
334346
+ "type": "array",
334347
+ "items": {
334348
+ "type": "string"
334349
+ }
334120
334350
  }
334121
334351
  }
334122
334352
  }
@@ -334216,32 +334446,6 @@
334216
334446
  }
334217
334447
  }
334218
334448
  },
334219
- "404": {
334220
- "description": "Resource not found",
334221
- "content": {
334222
- "application/json": {
334223
- "schema": {
334224
- "type": "object",
334225
- "required": [
334226
- "statusCode",
334227
- "error",
334228
- "message"
334229
- ],
334230
- "properties": {
334231
- "statusCode": {
334232
- "type": "number"
334233
- },
334234
- "error": {
334235
- "type": "string"
334236
- },
334237
- "message": {
334238
- "type": "string"
334239
- }
334240
- }
334241
- }
334242
- }
334243
- }
334244
- },
334245
334449
  "429": {
334246
334450
  "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
334247
334451
  "content": {
@@ -334299,14 +334503,14 @@
334299
334503
  }
334300
334504
  }
334301
334505
  },
334302
- "/api/v1/traffic-filter/domains/{id}/apply-cf-profile": {
334506
+ "/api/v1/traffic-filter/domains/{id}/auto-link-cf": {
334303
334507
  "post": {
334304
- "operationId": "postApiV1TrafficFilterDomainsByIdApplyCfProfile",
334305
- "summary": "Apply Cloudflare hardening profile",
334508
+ "operationId": "postApiV1TrafficFilterDomainsByIdAutoLinkCf",
334509
+ "summary": "Auto-link a Cloudflare zone",
334306
334510
  "tags": [
334307
334511
  "traffic-filter"
334308
334512
  ],
334309
- "description": "Applies the hardening zone settings (cache/minify/bot-fight/etc.) to the domain zone.",
334513
+ "description": "Finds the Cloudflare zone for the domain and stores its zone id + nameservers.",
334310
334514
  "parameters": [
334311
334515
  {
334312
334516
  "schema": {
@@ -334350,49 +334554,21 @@
334350
334554
  "ok": {
334351
334555
  "type": "boolean"
334352
334556
  },
334353
- "domain": {
334557
+ "zoneId": {
334354
334558
  "type": "string"
334355
334559
  },
334356
- "report": {
334357
- "type": "object",
334358
- "required": [
334359
- "applied",
334360
- "skipped",
334361
- "errors"
334362
- ],
334363
- "properties": {
334364
- "applied": {
334365
- "type": "array",
334366
- "items": {
334367
- "type": "string"
334368
- }
334369
- },
334370
- "skipped": {
334371
- "type": "array",
334372
- "items": {
334373
- "type": "string"
334374
- }
334375
- },
334376
- "errors": {
334377
- "type": "array",
334378
- "items": {
334379
- "type": "object",
334380
- "required": [
334381
- "setting",
334382
- "error"
334383
- ],
334384
- "properties": {
334385
- "setting": {
334386
- "type": "string"
334387
- },
334388
- "error": {
334389
- "type": "string"
334390
- }
334391
- }
334392
- }
334393
- }
334560
+ "nameservers": {
334561
+ "type": "array",
334562
+ "items": {
334563
+ "type": "string"
334394
334564
  }
334395
334565
  },
334566
+ "zoneStatus": {
334567
+ "type": "string"
334568
+ },
334569
+ "alreadyLinked": {
334570
+ "type": "boolean"
334571
+ },
334396
334572
  "error": {
334397
334573
  "type": "string"
334398
334574
  }
@@ -334577,15 +334753,24 @@
334577
334753
  }
334578
334754
  }
334579
334755
  },
334580
- "/api/v1/traffic-filter/domains/apply-cf-profile-all": {
334756
+ "/api/v1/traffic-filter/domains/{id}/apply-cf-profile": {
334581
334757
  "post": {
334582
- "operationId": "postApiV1TrafficFilterDomainsApplyCfProfileAll",
334583
- "summary": "Apply Cloudflare hardening profile to all linked domains",
334758
+ "operationId": "postApiV1TrafficFilterDomainsByIdApplyCfProfile",
334759
+ "summary": "Apply Cloudflare hardening profile",
334584
334760
  "tags": [
334585
334761
  "traffic-filter"
334586
334762
  ],
334587
- "description": "Applies the hardening profile to every domain that has a Cloudflare zone linked.",
334763
+ "description": "Applies the hardening zone settings (cache/minify/bot-fight/etc.) to the domain zone.",
334588
334764
  "parameters": [
334765
+ {
334766
+ "schema": {
334767
+ "format": "uuid",
334768
+ "type": "string"
334769
+ },
334770
+ "in": "path",
334771
+ "name": "id",
334772
+ "required": true
334773
+ },
334589
334774
  {
334590
334775
  "schema": {
334591
334776
  "format": "uuid",
@@ -334613,69 +334798,57 @@
334613
334798
  "schema": {
334614
334799
  "type": "object",
334615
334800
  "required": [
334616
- "results"
334801
+ "ok"
334617
334802
  ],
334618
334803
  "properties": {
334619
- "results": {
334620
- "type": "array",
334621
- "items": {
334622
- "type": "object",
334623
- "required": [
334624
- "domain",
334625
- "ok"
334626
- ],
334627
- "properties": {
334628
- "domain": {
334629
- "type": "string"
334630
- },
334631
- "ok": {
334632
- "type": "boolean"
334633
- },
334634
- "report": {
334635
- "type": "object",
334636
- "required": [
334637
- "applied",
334638
- "skipped",
334639
- "errors"
334640
- ],
334641
- "properties": {
334642
- "applied": {
334643
- "type": "array",
334644
- "items": {
334645
- "type": "string"
334646
- }
334647
- },
334648
- "skipped": {
334649
- "type": "array",
334650
- "items": {
334651
- "type": "string"
334652
- }
334804
+ "ok": {
334805
+ "type": "boolean"
334806
+ },
334807
+ "domain": {
334808
+ "type": "string"
334809
+ },
334810
+ "report": {
334811
+ "type": "object",
334812
+ "required": [
334813
+ "applied",
334814
+ "skipped",
334815
+ "errors"
334816
+ ],
334817
+ "properties": {
334818
+ "applied": {
334819
+ "type": "array",
334820
+ "items": {
334821
+ "type": "string"
334822
+ }
334823
+ },
334824
+ "skipped": {
334825
+ "type": "array",
334826
+ "items": {
334827
+ "type": "string"
334828
+ }
334829
+ },
334830
+ "errors": {
334831
+ "type": "array",
334832
+ "items": {
334833
+ "type": "object",
334834
+ "required": [
334835
+ "setting",
334836
+ "error"
334837
+ ],
334838
+ "properties": {
334839
+ "setting": {
334840
+ "type": "string"
334653
334841
  },
334654
- "errors": {
334655
- "type": "array",
334656
- "items": {
334657
- "type": "object",
334658
- "required": [
334659
- "setting",
334660
- "error"
334661
- ],
334662
- "properties": {
334663
- "setting": {
334664
- "type": "string"
334665
- },
334666
- "error": {
334667
- "type": "string"
334668
- }
334669
- }
334670
- }
334842
+ "error": {
334843
+ "type": "string"
334671
334844
  }
334672
334845
  }
334673
- },
334674
- "error": {
334675
- "type": "string"
334676
334846
  }
334677
334847
  }
334678
334848
  }
334849
+ },
334850
+ "error": {
334851
+ "type": "string"
334679
334852
  }
334680
334853
  }
334681
334854
  }
@@ -334775,6 +334948,32 @@
334775
334948
  }
334776
334949
  }
334777
334950
  },
334951
+ "404": {
334952
+ "description": "Resource not found",
334953
+ "content": {
334954
+ "application/json": {
334955
+ "schema": {
334956
+ "type": "object",
334957
+ "required": [
334958
+ "statusCode",
334959
+ "error",
334960
+ "message"
334961
+ ],
334962
+ "properties": {
334963
+ "statusCode": {
334964
+ "type": "number"
334965
+ },
334966
+ "error": {
334967
+ "type": "string"
334968
+ },
334969
+ "message": {
334970
+ "type": "string"
334971
+ }
334972
+ }
334973
+ }
334974
+ }
334975
+ }
334976
+ },
334778
334977
  "429": {
334779
334978
  "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
334780
334979
  "content": {
@@ -334832,61 +335031,15 @@
334832
335031
  }
334833
335032
  }
334834
335033
  },
334835
- "/api/v1/traffic-filter/domains/{id}/dns": {
335034
+ "/api/v1/traffic-filter/domains/apply-cf-profile-all": {
334836
335035
  "post": {
334837
- "operationId": "postApiV1TrafficFilterDomainsByIdDns",
334838
- "summary": "Add a DNS record",
335036
+ "operationId": "postApiV1TrafficFilterDomainsApplyCfProfileAll",
335037
+ "summary": "Apply Cloudflare hardening profile to all linked domains",
334839
335038
  "tags": [
334840
335039
  "traffic-filter"
334841
335040
  ],
334842
- "description": "Adds a DNS record to a Traffic Filter domain via Namesilo.",
334843
- "requestBody": {
334844
- "required": true,
334845
- "content": {
334846
- "application/json": {
334847
- "schema": {
334848
- "additionalProperties": false,
334849
- "type": "object",
334850
- "required": [
334851
- "rrtype",
334852
- "rrhost",
334853
- "rrvalue"
334854
- ],
334855
- "properties": {
334856
- "rrtype": {
334857
- "minLength": 1,
334858
- "maxLength": 10,
334859
- "type": "string"
334860
- },
334861
- "rrhost": {
334862
- "maxLength": 255,
334863
- "type": "string"
334864
- },
334865
- "rrvalue": {
334866
- "minLength": 1,
334867
- "maxLength": 500,
334868
- "type": "string"
334869
- },
334870
- "rrttl": {
334871
- "minimum": 60,
334872
- "maximum": 2592000,
334873
- "type": "integer"
334874
- }
334875
- }
334876
- }
334877
- }
334878
- }
334879
- },
335041
+ "description": "Applies the hardening profile to every domain that has a Cloudflare zone linked.",
334880
335042
  "parameters": [
334881
- {
334882
- "schema": {
334883
- "format": "uuid",
334884
- "type": "string"
334885
- },
334886
- "in": "path",
334887
- "name": "id",
334888
- "required": true
334889
- },
334890
335043
  {
334891
335044
  "schema": {
334892
335045
  "format": "uuid",
@@ -334914,18 +335067,69 @@
334914
335067
  "schema": {
334915
335068
  "type": "object",
334916
335069
  "required": [
334917
- "recordId"
335070
+ "results"
334918
335071
  ],
334919
335072
  "properties": {
334920
- "recordId": {
334921
- "anyOf": [
334922
- {
334923
- "type": "string"
334924
- },
334925
- {
334926
- "type": "null"
335073
+ "results": {
335074
+ "type": "array",
335075
+ "items": {
335076
+ "type": "object",
335077
+ "required": [
335078
+ "domain",
335079
+ "ok"
335080
+ ],
335081
+ "properties": {
335082
+ "domain": {
335083
+ "type": "string"
335084
+ },
335085
+ "ok": {
335086
+ "type": "boolean"
335087
+ },
335088
+ "report": {
335089
+ "type": "object",
335090
+ "required": [
335091
+ "applied",
335092
+ "skipped",
335093
+ "errors"
335094
+ ],
335095
+ "properties": {
335096
+ "applied": {
335097
+ "type": "array",
335098
+ "items": {
335099
+ "type": "string"
335100
+ }
335101
+ },
335102
+ "skipped": {
335103
+ "type": "array",
335104
+ "items": {
335105
+ "type": "string"
335106
+ }
335107
+ },
335108
+ "errors": {
335109
+ "type": "array",
335110
+ "items": {
335111
+ "type": "object",
335112
+ "required": [
335113
+ "setting",
335114
+ "error"
335115
+ ],
335116
+ "properties": {
335117
+ "setting": {
335118
+ "type": "string"
335119
+ },
335120
+ "error": {
335121
+ "type": "string"
335122
+ }
335123
+ }
335124
+ }
335125
+ }
335126
+ }
335127
+ },
335128
+ "error": {
335129
+ "type": "string"
335130
+ }
334927
335131
  }
334928
- ]
335132
+ }
334929
335133
  }
334930
335134
  }
334931
335135
  }
@@ -335025,32 +335229,6 @@
335025
335229
  }
335026
335230
  }
335027
335231
  },
335028
- "404": {
335029
- "description": "Resource not found",
335030
- "content": {
335031
- "application/json": {
335032
- "schema": {
335033
- "type": "object",
335034
- "required": [
335035
- "statusCode",
335036
- "error",
335037
- "message"
335038
- ],
335039
- "properties": {
335040
- "statusCode": {
335041
- "type": "number"
335042
- },
335043
- "error": {
335044
- "type": "string"
335045
- },
335046
- "message": {
335047
- "type": "string"
335048
- }
335049
- }
335050
- }
335051
- }
335052
- }
335053
- },
335054
335232
  "429": {
335055
335233
  "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
335056
335234
  "content": {
@@ -335087,37 +335265,11 @@
335087
335265
  }
335088
335266
  }
335089
335267
  },
335090
- "502": {
335091
- "description": "Bad gateway - upstream provider failed",
335092
- "content": {
335093
- "application/json": {
335094
- "schema": {
335095
- "type": "object",
335096
- "required": [
335097
- "statusCode",
335098
- "error",
335099
- "message"
335100
- ],
335101
- "properties": {
335102
- "statusCode": {
335103
- "type": "number"
335104
- },
335105
- "error": {
335106
- "type": "string"
335107
- },
335108
- "message": {
335109
- "type": "string"
335110
- }
335111
- }
335112
- }
335113
- }
335114
- }
335115
- },
335116
- "503": {
335117
- "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
335118
- "headers": {
335119
- "Retry-After": {
335120
- "description": "Seconds to wait before retrying the identical request.",
335268
+ "503": {
335269
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
335270
+ "headers": {
335271
+ "Retry-After": {
335272
+ "description": "Seconds to wait before retrying the identical request.",
335121
335273
  "schema": {
335122
335274
  "type": "integer"
335123
335275
  }
@@ -335134,54 +335286,70 @@
335134
335286
  }
335135
335287
  }
335136
335288
  },
335137
- "/api/v1/traffic-filter/filter-lists": {
335138
- "get": {
335139
- "operationId": "getApiV1TrafficFilterFilterLists",
335140
- "summary": "List Traffic Filter filter lists",
335289
+ "/api/v1/traffic-filter/domains/{id}/dns": {
335290
+ "post": {
335291
+ "operationId": "postApiV1TrafficFilterDomainsByIdDns",
335292
+ "summary": "Add a DNS record",
335141
335293
  "tags": [
335142
335294
  "traffic-filter"
335143
335295
  ],
335144
- "description": "Returns all filter lists for the current team.",
335145
- "parameters": [
335146
- {
335147
- "schema": {
335148
- "anyOf": [
335149
- {
335150
- "type": "string",
335151
- "enum": [
335152
- "ua"
335153
- ]
335154
- },
335155
- {
335156
- "type": "string",
335157
- "enum": [
335158
- "ip"
335159
- ]
335296
+ "description": "Adds a DNS record to a Traffic Filter domain via Namesilo.",
335297
+ "requestBody": {
335298
+ "required": true,
335299
+ "content": {
335300
+ "application/json": {
335301
+ "schema": {
335302
+ "additionalProperties": false,
335303
+ "type": "object",
335304
+ "required": [
335305
+ "rrtype",
335306
+ "rrhost",
335307
+ "rrvalue"
335308
+ ],
335309
+ "properties": {
335310
+ "rrtype": {
335311
+ "minLength": 1,
335312
+ "maxLength": 10,
335313
+ "type": "string"
335314
+ },
335315
+ "rrhost": {
335316
+ "maxLength": 255,
335317
+ "type": "string"
335318
+ },
335319
+ "rrvalue": {
335320
+ "minLength": 1,
335321
+ "maxLength": 500,
335322
+ "type": "string"
335323
+ },
335324
+ "rrttl": {
335325
+ "minimum": 60,
335326
+ "maximum": 2592000,
335327
+ "type": "integer"
335328
+ }
335160
335329
  }
335161
- ]
335162
- },
335163
- "in": "query",
335164
- "name": "type",
335165
- "required": false
335166
- },
335330
+ }
335331
+ }
335332
+ }
335333
+ },
335334
+ "parameters": [
335167
335335
  {
335168
335336
  "schema": {
335169
- "minimum": 1,
335170
- "maximum": 100,
335171
- "type": "integer"
335337
+ "format": "uuid",
335338
+ "type": "string"
335172
335339
  },
335173
- "in": "query",
335174
- "name": "limit",
335175
- "required": false
335340
+ "in": "path",
335341
+ "name": "id",
335342
+ "required": true
335176
335343
  },
335177
335344
  {
335178
335345
  "schema": {
335179
- "minimum": 0,
335180
- "type": "integer"
335346
+ "format": "uuid",
335347
+ "type": "string"
335181
335348
  },
335182
- "in": "query",
335183
- "name": "offset",
335184
- "required": false
335349
+ "in": "header",
335350
+ "name": "x-team-id",
335351
+ "required": false,
335352
+ "description": "Destination workspace team id."
335185
335353
  }
335186
335354
  ],
335187
335355
  "security": [
@@ -335200,54 +335368,77 @@
335200
335368
  "schema": {
335201
335369
  "type": "object",
335202
335370
  "required": [
335203
- "items",
335204
- "total"
335371
+ "recordId"
335205
335372
  ],
335206
335373
  "properties": {
335207
- "items": {
335208
- "type": "array",
335209
- "items": {
335210
- "type": "object",
335211
- "required": [
335212
- "id",
335213
- "teamId",
335214
- "name",
335215
- "type",
335216
- "entries",
335217
- "createdAt"
335218
- ],
335219
- "properties": {
335220
- "id": {
335221
- "format": "uuid",
335222
- "type": "string"
335223
- },
335224
- "teamId": {
335225
- "format": "uuid",
335226
- "type": "string"
335227
- },
335228
- "name": {
335229
- "type": "string"
335230
- },
335231
- "type": {
335232
- "type": "string"
335233
- },
335234
- "entries": {
335235
- "type": "array",
335236
- "items": {
335237
- "type": "string"
335238
- }
335239
- },
335240
- "createdAt": {
335241
- "format": "date-time",
335242
- "type": "string"
335243
- }
335374
+ "recordId": {
335375
+ "anyOf": [
335376
+ {
335377
+ "type": "string"
335378
+ },
335379
+ {
335380
+ "type": "null"
335381
+ }
335382
+ ]
335383
+ }
335384
+ }
335385
+ }
335386
+ }
335387
+ }
335388
+ },
335389
+ "400": {
335390
+ "description": "Invalid request - schema validation failed",
335391
+ "content": {
335392
+ "application/json": {
335393
+ "schema": {
335394
+ "anyOf": [
335395
+ {
335396
+ "description": "Explicit destination workspace required: send the x-team-id header or activate a team scope for this operation.",
335397
+ "additionalProperties": false,
335398
+ "type": "object",
335399
+ "required": [
335400
+ "statusCode",
335401
+ "error",
335402
+ "message"
335403
+ ],
335404
+ "properties": {
335405
+ "statusCode": {
335406
+ "type": "number"
335407
+ },
335408
+ "error": {
335409
+ "type": "string"
335410
+ },
335411
+ "message": {
335412
+ "type": "string"
335413
+ },
335414
+ "code": {
335415
+ "type": "string",
335416
+ "enum": [
335417
+ "SCOPE_TEAM_REQUIRED"
335418
+ ]
335244
335419
  }
335245
335420
  }
335246
335421
  },
335247
- "total": {
335248
- "type": "number"
335422
+ {
335423
+ "type": "object",
335424
+ "required": [
335425
+ "statusCode",
335426
+ "error",
335427
+ "message"
335428
+ ],
335429
+ "properties": {
335430
+ "statusCode": {
335431
+ "type": "number"
335432
+ },
335433
+ "error": {
335434
+ "type": "string"
335435
+ },
335436
+ "message": {
335437
+ "type": "string"
335438
+ }
335439
+ }
335249
335440
  }
335250
- }
335441
+ ]
335251
335442
  }
335252
335443
  }
335253
335444
  }
@@ -335262,18 +335453,34 @@
335262
335453
  }
335263
335454
  }
335264
335455
  },
335265
- "429": {
335266
- "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
335456
+ "403": {
335457
+ "description": "Forbidden - caller lacks the required role/permission",
335267
335458
  "content": {
335268
335459
  "application/json": {
335269
335460
  "schema": {
335270
- "$ref": "#/components/schemas/RateLimitedResponse"
335461
+ "type": "object",
335462
+ "required": [
335463
+ "statusCode",
335464
+ "error",
335465
+ "message"
335466
+ ],
335467
+ "properties": {
335468
+ "statusCode": {
335469
+ "type": "number"
335470
+ },
335471
+ "error": {
335472
+ "type": "string"
335473
+ },
335474
+ "message": {
335475
+ "type": "string"
335476
+ }
335477
+ }
335271
335478
  }
335272
335479
  }
335273
335480
  }
335274
335481
  },
335275
- "500": {
335276
- "description": "Internal server error",
335482
+ "404": {
335483
+ "description": "Resource not found",
335277
335484
  "content": {
335278
335485
  "application/json": {
335279
335486
  "schema": {
@@ -335298,13 +335505,260 @@
335298
335505
  }
335299
335506
  }
335300
335507
  },
335301
- "503": {
335302
- "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
335303
- "headers": {
335304
- "Retry-After": {
335305
- "description": "Seconds to wait before retrying the identical request.",
335306
- "schema": {
335307
- "type": "integer"
335508
+ "429": {
335509
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
335510
+ "content": {
335511
+ "application/json": {
335512
+ "schema": {
335513
+ "$ref": "#/components/schemas/RateLimitedResponse"
335514
+ }
335515
+ }
335516
+ }
335517
+ },
335518
+ "500": {
335519
+ "description": "Internal server error",
335520
+ "content": {
335521
+ "application/json": {
335522
+ "schema": {
335523
+ "type": "object",
335524
+ "required": [
335525
+ "statusCode",
335526
+ "error",
335527
+ "message"
335528
+ ],
335529
+ "properties": {
335530
+ "statusCode": {
335531
+ "type": "number"
335532
+ },
335533
+ "error": {
335534
+ "type": "string"
335535
+ },
335536
+ "message": {
335537
+ "type": "string"
335538
+ }
335539
+ }
335540
+ }
335541
+ }
335542
+ }
335543
+ },
335544
+ "502": {
335545
+ "description": "Bad gateway - upstream provider failed",
335546
+ "content": {
335547
+ "application/json": {
335548
+ "schema": {
335549
+ "type": "object",
335550
+ "required": [
335551
+ "statusCode",
335552
+ "error",
335553
+ "message"
335554
+ ],
335555
+ "properties": {
335556
+ "statusCode": {
335557
+ "type": "number"
335558
+ },
335559
+ "error": {
335560
+ "type": "string"
335561
+ },
335562
+ "message": {
335563
+ "type": "string"
335564
+ }
335565
+ }
335566
+ }
335567
+ }
335568
+ }
335569
+ },
335570
+ "503": {
335571
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
335572
+ "headers": {
335573
+ "Retry-After": {
335574
+ "description": "Seconds to wait before retrying the identical request.",
335575
+ "schema": {
335576
+ "type": "integer"
335577
+ }
335578
+ }
335579
+ },
335580
+ "content": {
335581
+ "application/json": {
335582
+ "schema": {
335583
+ "$ref": "#/components/schemas/ErrorResponse"
335584
+ }
335585
+ }
335586
+ }
335587
+ }
335588
+ }
335589
+ }
335590
+ },
335591
+ "/api/v1/traffic-filter/filter-lists": {
335592
+ "get": {
335593
+ "operationId": "getApiV1TrafficFilterFilterLists",
335594
+ "summary": "List Traffic Filter filter lists",
335595
+ "tags": [
335596
+ "traffic-filter"
335597
+ ],
335598
+ "description": "Returns all filter lists for the current team.",
335599
+ "parameters": [
335600
+ {
335601
+ "schema": {
335602
+ "anyOf": [
335603
+ {
335604
+ "type": "string",
335605
+ "enum": [
335606
+ "ua"
335607
+ ]
335608
+ },
335609
+ {
335610
+ "type": "string",
335611
+ "enum": [
335612
+ "ip"
335613
+ ]
335614
+ }
335615
+ ]
335616
+ },
335617
+ "in": "query",
335618
+ "name": "type",
335619
+ "required": false
335620
+ },
335621
+ {
335622
+ "schema": {
335623
+ "minimum": 1,
335624
+ "maximum": 100,
335625
+ "type": "integer"
335626
+ },
335627
+ "in": "query",
335628
+ "name": "limit",
335629
+ "required": false
335630
+ },
335631
+ {
335632
+ "schema": {
335633
+ "minimum": 0,
335634
+ "type": "integer"
335635
+ },
335636
+ "in": "query",
335637
+ "name": "offset",
335638
+ "required": false
335639
+ }
335640
+ ],
335641
+ "security": [
335642
+ {
335643
+ "bearerAuth": []
335644
+ },
335645
+ {
335646
+ "apiKeyAuth": []
335647
+ }
335648
+ ],
335649
+ "responses": {
335650
+ "200": {
335651
+ "description": "Successful response",
335652
+ "content": {
335653
+ "application/json": {
335654
+ "schema": {
335655
+ "type": "object",
335656
+ "required": [
335657
+ "items",
335658
+ "total"
335659
+ ],
335660
+ "properties": {
335661
+ "items": {
335662
+ "type": "array",
335663
+ "items": {
335664
+ "type": "object",
335665
+ "required": [
335666
+ "id",
335667
+ "teamId",
335668
+ "name",
335669
+ "type",
335670
+ "entries",
335671
+ "createdAt"
335672
+ ],
335673
+ "properties": {
335674
+ "id": {
335675
+ "format": "uuid",
335676
+ "type": "string"
335677
+ },
335678
+ "teamId": {
335679
+ "format": "uuid",
335680
+ "type": "string"
335681
+ },
335682
+ "name": {
335683
+ "type": "string"
335684
+ },
335685
+ "type": {
335686
+ "type": "string"
335687
+ },
335688
+ "entries": {
335689
+ "type": "array",
335690
+ "items": {
335691
+ "type": "string"
335692
+ }
335693
+ },
335694
+ "createdAt": {
335695
+ "format": "date-time",
335696
+ "type": "string"
335697
+ }
335698
+ }
335699
+ }
335700
+ },
335701
+ "total": {
335702
+ "type": "number"
335703
+ }
335704
+ }
335705
+ }
335706
+ }
335707
+ }
335708
+ },
335709
+ "401": {
335710
+ "description": "Unauthorized - missing or invalid bearer token",
335711
+ "content": {
335712
+ "application/json": {
335713
+ "schema": {
335714
+ "$ref": "#/components/schemas/ErrorResponse"
335715
+ }
335716
+ }
335717
+ }
335718
+ },
335719
+ "429": {
335720
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
335721
+ "content": {
335722
+ "application/json": {
335723
+ "schema": {
335724
+ "$ref": "#/components/schemas/RateLimitedResponse"
335725
+ }
335726
+ }
335727
+ }
335728
+ },
335729
+ "500": {
335730
+ "description": "Internal server error",
335731
+ "content": {
335732
+ "application/json": {
335733
+ "schema": {
335734
+ "type": "object",
335735
+ "required": [
335736
+ "statusCode",
335737
+ "error",
335738
+ "message"
335739
+ ],
335740
+ "properties": {
335741
+ "statusCode": {
335742
+ "type": "number"
335743
+ },
335744
+ "error": {
335745
+ "type": "string"
335746
+ },
335747
+ "message": {
335748
+ "type": "string"
335749
+ }
335750
+ }
335751
+ }
335752
+ }
335753
+ }
335754
+ },
335755
+ "503": {
335756
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
335757
+ "headers": {
335758
+ "Retry-After": {
335759
+ "description": "Seconds to wait before retrying the identical request.",
335760
+ "schema": {
335761
+ "type": "integer"
335308
335762
  }
335309
335763
  }
335310
335764
  },
@@ -342195,7 +342649,7 @@
342195
342649
  "tags": [
342196
342650
  "traffic-filter"
342197
342651
  ],
342198
- "description": "Returns landing pages for the current team. Archived pages are hidden by default; pass an explicit status filter to select a specific state.",
342652
+ "description": "Returns landing pages for the current team. Archived pages are hidden by default; pass an explicit status filter to select a specific state. Pass page_kind to list only shield pages (\"safe\") or only flow pages (\"money\").",
342199
342653
  "parameters": [
342200
342654
  {
342201
342655
  "schema": {
@@ -342212,13 +342666,34 @@
342212
342666
  {
342213
342667
  "type": "string",
342214
342668
  "enum": [
342215
- "active"
342669
+ "safe"
342216
342670
  ]
342217
342671
  },
342218
342672
  {
342219
342673
  "type": "string",
342220
342674
  "enum": [
342221
- "paused"
342675
+ "money"
342676
+ ]
342677
+ }
342678
+ ]
342679
+ },
342680
+ "in": "query",
342681
+ "name": "page_kind",
342682
+ "required": false
342683
+ },
342684
+ {
342685
+ "schema": {
342686
+ "anyOf": [
342687
+ {
342688
+ "type": "string",
342689
+ "enum": [
342690
+ "active"
342691
+ ]
342692
+ },
342693
+ {
342694
+ "type": "string",
342695
+ "enum": [
342696
+ "paused"
342222
342697
  ]
342223
342698
  },
342224
342699
  {
@@ -342290,6 +342765,7 @@
342290
342765
  "id",
342291
342766
  "name",
342292
342767
  "type",
342768
+ "page_kind",
342293
342769
  "html",
342294
342770
  "bundle_version",
342295
342771
  "bundle_entry_file",
@@ -342314,6 +342790,22 @@
342314
342790
  "type": {
342315
342791
  "type": "string"
342316
342792
  },
342793
+ "page_kind": {
342794
+ "anyOf": [
342795
+ {
342796
+ "type": "string",
342797
+ "enum": [
342798
+ "safe"
342799
+ ]
342800
+ },
342801
+ {
342802
+ "type": "string",
342803
+ "enum": [
342804
+ "money"
342805
+ ]
342806
+ }
342807
+ ]
342808
+ },
342317
342809
  "html": {
342318
342810
  "anyOf": [
342319
342811
  {
@@ -342526,7 +343018,7 @@
342526
343018
  "tags": [
342527
343019
  "traffic-filter"
342528
343020
  ],
342529
- "description": "Creates a new landing page for the current team.",
343021
+ "description": "Creates a new landing page for the current team. page_kind defaults to \"money\"; a page of a derived type (\"imported\" / \"cloned\") can only be a shield page and is rejected with 400 otherwise.",
342530
343022
  "requestBody": {
342531
343023
  "required": true,
342532
343024
  "content": {
@@ -342547,6 +343039,22 @@
342547
343039
  "maxLength": 50,
342548
343040
  "type": "string"
342549
343041
  },
343042
+ "page_kind": {
343043
+ "anyOf": [
343044
+ {
343045
+ "type": "string",
343046
+ "enum": [
343047
+ "safe"
343048
+ ]
343049
+ },
343050
+ {
343051
+ "type": "string",
343052
+ "enum": [
343053
+ "money"
343054
+ ]
343055
+ }
343056
+ ]
343057
+ },
342550
343058
  "html": {
342551
343059
  "anyOf": [
342552
343060
  {
@@ -342671,6 +343179,7 @@
342671
343179
  "id",
342672
343180
  "name",
342673
343181
  "type",
343182
+ "page_kind",
342674
343183
  "html",
342675
343184
  "bundle_version",
342676
343185
  "bundle_entry_file",
@@ -342695,6 +343204,22 @@
342695
343204
  "type": {
342696
343205
  "type": "string"
342697
343206
  },
343207
+ "page_kind": {
343208
+ "anyOf": [
343209
+ {
343210
+ "type": "string",
343211
+ "enum": [
343212
+ "safe"
343213
+ ]
343214
+ },
343215
+ {
343216
+ "type": "string",
343217
+ "enum": [
343218
+ "money"
343219
+ ]
343220
+ }
343221
+ ]
343222
+ },
342698
343223
  "html": {
342699
343224
  "anyOf": [
342700
343225
  {
@@ -342994,6 +343519,7 @@
342994
343519
  "id",
342995
343520
  "name",
342996
343521
  "type",
343522
+ "page_kind",
342997
343523
  "html",
342998
343524
  "bundle_version",
342999
343525
  "bundle_entry_file",
@@ -343018,6 +343544,22 @@
343018
343544
  "type": {
343019
343545
  "type": "string"
343020
343546
  },
343547
+ "page_kind": {
343548
+ "anyOf": [
343549
+ {
343550
+ "type": "string",
343551
+ "enum": [
343552
+ "safe"
343553
+ ]
343554
+ },
343555
+ {
343556
+ "type": "string",
343557
+ "enum": [
343558
+ "money"
343559
+ ]
343560
+ }
343561
+ ]
343562
+ },
343021
343563
  "html": {
343022
343564
  "anyOf": [
343023
343565
  {
@@ -343250,7 +343792,7 @@
343250
343792
  "tags": [
343251
343793
  "traffic-filter"
343252
343794
  ],
343253
- "description": "Updates an existing landing page.",
343795
+ "description": "Updates an existing landing page. Turning a page of a derived type (\"imported\" / \"cloned\") into a money page is rejected with 400.",
343254
343796
  "requestBody": {
343255
343797
  "required": true,
343256
343798
  "content": {
@@ -343268,6 +343810,22 @@
343268
343810
  "maxLength": 50,
343269
343811
  "type": "string"
343270
343812
  },
343813
+ "page_kind": {
343814
+ "anyOf": [
343815
+ {
343816
+ "type": "string",
343817
+ "enum": [
343818
+ "safe"
343819
+ ]
343820
+ },
343821
+ {
343822
+ "type": "string",
343823
+ "enum": [
343824
+ "money"
343825
+ ]
343826
+ }
343827
+ ]
343828
+ },
343271
343829
  "html": {
343272
343830
  "anyOf": [
343273
343831
  {
@@ -343401,6 +343959,7 @@
343401
343959
  "id",
343402
343960
  "name",
343403
343961
  "type",
343962
+ "page_kind",
343404
343963
  "html",
343405
343964
  "bundle_version",
343406
343965
  "bundle_entry_file",
@@ -343425,6 +343984,22 @@
343425
343984
  "type": {
343426
343985
  "type": "string"
343427
343986
  },
343987
+ "page_kind": {
343988
+ "anyOf": [
343989
+ {
343990
+ "type": "string",
343991
+ "enum": [
343992
+ "safe"
343993
+ ]
343994
+ },
343995
+ {
343996
+ "type": "string",
343997
+ "enum": [
343998
+ "money"
343999
+ ]
344000
+ }
344001
+ ]
344002
+ },
343428
344003
  "html": {
343429
344004
  "anyOf": [
343430
344005
  {
@@ -343926,7 +344501,7 @@
343926
344501
  "tags": [
343927
344502
  "traffic-filter"
343928
344503
  ],
343929
- "description": "Fetches the page HTML, rewrites it to stay self-contained, and saves it as an imported landing page.",
344504
+ "description": "Fetches the page HTML, rewrites it to stay self-contained, and saves it as an imported landing page. An import always produces a shield page: page_kind may only be \"safe\", and any other value is rejected with 400.",
343930
344505
  "requestBody": {
343931
344506
  "required": true,
343932
344507
  "content": {
@@ -343948,6 +344523,22 @@
343948
344523
  "maxLength": 200,
343949
344524
  "type": "string"
343950
344525
  },
344526
+ "page_kind": {
344527
+ "anyOf": [
344528
+ {
344529
+ "type": "string",
344530
+ "enum": [
344531
+ "safe"
344532
+ ]
344533
+ },
344534
+ {
344535
+ "type": "string",
344536
+ "enum": [
344537
+ "money"
344538
+ ]
344539
+ }
344540
+ ]
344541
+ },
343951
344542
  "host_assets": {
343952
344543
  "type": "boolean"
343953
344544
  }
@@ -343987,6 +344578,7 @@
343987
344578
  "id",
343988
344579
  "name",
343989
344580
  "type",
344581
+ "page_kind",
343990
344582
  "html",
343991
344583
  "bundle_version",
343992
344584
  "bundle_entry_file",
@@ -344011,6 +344603,22 @@
344011
344603
  "type": {
344012
344604
  "type": "string"
344013
344605
  },
344606
+ "page_kind": {
344607
+ "anyOf": [
344608
+ {
344609
+ "type": "string",
344610
+ "enum": [
344611
+ "safe"
344612
+ ]
344613
+ },
344614
+ {
344615
+ "type": "string",
344616
+ "enum": [
344617
+ "money"
344618
+ ]
344619
+ }
344620
+ ]
344621
+ },
344014
344622
  "html": {
344015
344623
  "anyOf": [
344016
344624
  {
@@ -344305,7 +344913,7 @@
344305
344913
  "tags": [
344306
344914
  "traffic-filter"
344307
344915
  ],
344308
- "description": "Generates a complete standalone HTML landing page with Anthropic and saves it.",
344916
+ "description": "Generates a complete standalone HTML landing page with Anthropic and saves it. page_kind decides which list the page lands in and defaults to \"money\".",
344309
344917
  "requestBody": {
344310
344918
  "required": true,
344311
344919
  "content": {
@@ -344334,6 +344942,22 @@
344334
344942
  "minLength": 1,
344335
344943
  "maxLength": 200,
344336
344944
  "type": "string"
344945
+ },
344946
+ "page_kind": {
344947
+ "anyOf": [
344948
+ {
344949
+ "type": "string",
344950
+ "enum": [
344951
+ "safe"
344952
+ ]
344953
+ },
344954
+ {
344955
+ "type": "string",
344956
+ "enum": [
344957
+ "money"
344958
+ ]
344959
+ }
344960
+ ]
344337
344961
  }
344338
344962
  }
344339
344963
  }
@@ -344371,6 +344995,7 @@
344371
344995
  "id",
344372
344996
  "name",
344373
344997
  "type",
344998
+ "page_kind",
344374
344999
  "html",
344375
345000
  "bundle_version",
344376
345001
  "bundle_entry_file",
@@ -344395,6 +345020,22 @@
344395
345020
  "type": {
344396
345021
  "type": "string"
344397
345022
  },
345023
+ "page_kind": {
345024
+ "anyOf": [
345025
+ {
345026
+ "type": "string",
345027
+ "enum": [
345028
+ "safe"
345029
+ ]
345030
+ },
345031
+ {
345032
+ "type": "string",
345033
+ "enum": [
345034
+ "money"
345035
+ ]
345036
+ }
345037
+ ]
345038
+ },
344398
345039
  "html": {
344399
345040
  "anyOf": [
344400
345041
  {
@@ -344689,7 +345330,7 @@
344689
345330
  "tags": [
344690
345331
  "traffic-filter"
344691
345332
  ],
344692
- "description": "Builds an advertorial HTML page (hero, price, rating, testimonials, FAQ) with real Pexels imagery and saves it.",
345333
+ "description": "Builds an advertorial HTML page (hero, price, rating, testimonials, FAQ) with real Pexels imagery and saves it. page_kind decides which list the page lands in and defaults to \"money\".",
344693
345334
  "requestBody": {
344694
345335
  "required": true,
344695
345336
  "content": {
@@ -344752,6 +345393,22 @@
344752
345393
  "minLength": 1,
344753
345394
  "maxLength": 200,
344754
345395
  "type": "string"
345396
+ },
345397
+ "page_kind": {
345398
+ "anyOf": [
345399
+ {
345400
+ "type": "string",
345401
+ "enum": [
345402
+ "safe"
345403
+ ]
345404
+ },
345405
+ {
345406
+ "type": "string",
345407
+ "enum": [
345408
+ "money"
345409
+ ]
345410
+ }
345411
+ ]
344755
345412
  }
344756
345413
  }
344757
345414
  }
@@ -344789,6 +345446,7 @@
344789
345446
  "id",
344790
345447
  "name",
344791
345448
  "type",
345449
+ "page_kind",
344792
345450
  "html",
344793
345451
  "bundle_version",
344794
345452
  "bundle_entry_file",
@@ -344813,6 +345471,22 @@
344813
345471
  "type": {
344814
345472
  "type": "string"
344815
345473
  },
345474
+ "page_kind": {
345475
+ "anyOf": [
345476
+ {
345477
+ "type": "string",
345478
+ "enum": [
345479
+ "safe"
345480
+ ]
345481
+ },
345482
+ {
345483
+ "type": "string",
345484
+ "enum": [
345485
+ "money"
345486
+ ]
345487
+ }
345488
+ ]
345489
+ },
344816
345490
  "html": {
344817
345491
  "anyOf": [
344818
345492
  {
@@ -345074,6 +345748,512 @@
345074
345748
  }
345075
345749
  }
345076
345750
  },
345751
+ "/api/v1/traffic-filter/landing-pages/{id}/preview-url": {
345752
+ "get": {
345753
+ "operationId": "getApiV1TrafficFilterLandingPagesByIdPreviewUrl",
345754
+ "summary": "Build a signed preview URL for a Traffic Filter landing page",
345755
+ "tags": [
345756
+ "traffic-filter"
345757
+ ],
345758
+ "description": "Returns the public URL of the landing page with a short-lived signed preview token appended. Public landing pages are reachable only from inside a campaign funnel, so the dashboard needs this token to open a preview in a new tab. The token expires after 10 minutes and is bound to this landing page and this team.",
345759
+ "parameters": [
345760
+ {
345761
+ "schema": {
345762
+ "format": "uuid",
345763
+ "type": "string"
345764
+ },
345765
+ "in": "path",
345766
+ "name": "id",
345767
+ "required": true
345768
+ },
345769
+ {
345770
+ "schema": {
345771
+ "format": "uuid",
345772
+ "type": "string"
345773
+ },
345774
+ "in": "header",
345775
+ "name": "x-team-id",
345776
+ "required": false,
345777
+ "description": "Explicit team (workspace) scope: a team.id the caller belongs to."
345778
+ },
345779
+ {
345780
+ "schema": {
345781
+ "type": "string"
345782
+ },
345783
+ "in": "header",
345784
+ "name": "x-active-scope",
345785
+ "required": false,
345786
+ "description": "Active scope selector in `<scopeType>:<uuid>` form, e.g. `organization:<organization_id>` or `team:<team_id>`. Omit the header for the all-workspaces view."
345787
+ }
345788
+ ],
345789
+ "security": [
345790
+ {
345791
+ "bearerAuth": []
345792
+ },
345793
+ {
345794
+ "apiKeyAuth": []
345795
+ }
345796
+ ],
345797
+ "responses": {
345798
+ "200": {
345799
+ "description": "Successful response",
345800
+ "content": {
345801
+ "application/json": {
345802
+ "schema": {
345803
+ "additionalProperties": false,
345804
+ "type": "object",
345805
+ "required": [
345806
+ "url"
345807
+ ],
345808
+ "properties": {
345809
+ "url": {
345810
+ "description": "Absolute public preview URL, token included.",
345811
+ "type": "string"
345812
+ }
345813
+ }
345814
+ }
345815
+ }
345816
+ }
345817
+ },
345818
+ "401": {
345819
+ "description": "Unauthorized - missing or invalid bearer token",
345820
+ "content": {
345821
+ "application/json": {
345822
+ "schema": {
345823
+ "$ref": "#/components/schemas/ErrorResponse"
345824
+ }
345825
+ }
345826
+ }
345827
+ },
345828
+ "404": {
345829
+ "description": "Resource not found",
345830
+ "content": {
345831
+ "application/json": {
345832
+ "schema": {
345833
+ "type": "object",
345834
+ "required": [
345835
+ "statusCode",
345836
+ "error",
345837
+ "message"
345838
+ ],
345839
+ "properties": {
345840
+ "statusCode": {
345841
+ "type": "number"
345842
+ },
345843
+ "error": {
345844
+ "type": "string"
345845
+ },
345846
+ "message": {
345847
+ "type": "string"
345848
+ }
345849
+ }
345850
+ }
345851
+ }
345852
+ }
345853
+ },
345854
+ "429": {
345855
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
345856
+ "content": {
345857
+ "application/json": {
345858
+ "schema": {
345859
+ "$ref": "#/components/schemas/RateLimitedResponse"
345860
+ }
345861
+ }
345862
+ }
345863
+ },
345864
+ "500": {
345865
+ "description": "Internal server error",
345866
+ "content": {
345867
+ "application/json": {
345868
+ "schema": {
345869
+ "type": "object",
345870
+ "required": [
345871
+ "statusCode",
345872
+ "error",
345873
+ "message"
345874
+ ],
345875
+ "properties": {
345876
+ "statusCode": {
345877
+ "type": "number"
345878
+ },
345879
+ "error": {
345880
+ "type": "string"
345881
+ },
345882
+ "message": {
345883
+ "type": "string"
345884
+ }
345885
+ }
345886
+ }
345887
+ }
345888
+ }
345889
+ },
345890
+ "503": {
345891
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
345892
+ "headers": {
345893
+ "Retry-After": {
345894
+ "description": "Seconds to wait before retrying the identical request.",
345895
+ "schema": {
345896
+ "type": "integer"
345897
+ }
345898
+ }
345899
+ },
345900
+ "content": {
345901
+ "application/json": {
345902
+ "schema": {
345903
+ "$ref": "#/components/schemas/ErrorResponse"
345904
+ }
345905
+ }
345906
+ }
345907
+ }
345908
+ }
345909
+ }
345910
+ },
345911
+ "/api/v1/traffic-filter/forms/{id}/preview-url": {
345912
+ "get": {
345913
+ "operationId": "getApiV1TrafficFilterFormsByIdPreviewUrl",
345914
+ "summary": "Build a signed preview URL for a Traffic Filter form",
345915
+ "tags": [
345916
+ "traffic-filter"
345917
+ ],
345918
+ "description": "Returns the public URL of the lead-capture form with a short-lived signed preview token appended. The public form page is reachable only from inside a campaign funnel, so this token is the only way to open it from the dashboard. The token expires after 10 minutes and is bound to this form and this team. It is a temporary preview link, not an address to hand out.",
345919
+ "parameters": [
345920
+ {
345921
+ "schema": {
345922
+ "format": "uuid",
345923
+ "type": "string"
345924
+ },
345925
+ "in": "path",
345926
+ "name": "id",
345927
+ "required": true
345928
+ },
345929
+ {
345930
+ "schema": {
345931
+ "format": "uuid",
345932
+ "type": "string"
345933
+ },
345934
+ "in": "header",
345935
+ "name": "x-team-id",
345936
+ "required": false,
345937
+ "description": "Explicit team (workspace) scope: a team.id the caller belongs to."
345938
+ },
345939
+ {
345940
+ "schema": {
345941
+ "type": "string"
345942
+ },
345943
+ "in": "header",
345944
+ "name": "x-active-scope",
345945
+ "required": false,
345946
+ "description": "Active scope selector in `<scopeType>:<uuid>` form, e.g. `organization:<organization_id>` or `team:<team_id>`. Omit the header for the all-workspaces view."
345947
+ }
345948
+ ],
345949
+ "security": [
345950
+ {
345951
+ "bearerAuth": []
345952
+ },
345953
+ {
345954
+ "apiKeyAuth": []
345955
+ }
345956
+ ],
345957
+ "responses": {
345958
+ "200": {
345959
+ "description": "Successful response",
345960
+ "content": {
345961
+ "application/json": {
345962
+ "schema": {
345963
+ "additionalProperties": false,
345964
+ "type": "object",
345965
+ "required": [
345966
+ "url"
345967
+ ],
345968
+ "properties": {
345969
+ "url": {
345970
+ "description": "Absolute public preview URL, token included.",
345971
+ "type": "string"
345972
+ }
345973
+ }
345974
+ }
345975
+ }
345976
+ }
345977
+ },
345978
+ "401": {
345979
+ "description": "Unauthorized - missing or invalid bearer token",
345980
+ "content": {
345981
+ "application/json": {
345982
+ "schema": {
345983
+ "$ref": "#/components/schemas/ErrorResponse"
345984
+ }
345985
+ }
345986
+ }
345987
+ },
345988
+ "404": {
345989
+ "description": "Resource not found",
345990
+ "content": {
345991
+ "application/json": {
345992
+ "schema": {
345993
+ "type": "object",
345994
+ "required": [
345995
+ "statusCode",
345996
+ "error",
345997
+ "message"
345998
+ ],
345999
+ "properties": {
346000
+ "statusCode": {
346001
+ "type": "number"
346002
+ },
346003
+ "error": {
346004
+ "type": "string"
346005
+ },
346006
+ "message": {
346007
+ "type": "string"
346008
+ }
346009
+ }
346010
+ }
346011
+ }
346012
+ }
346013
+ },
346014
+ "429": {
346015
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
346016
+ "content": {
346017
+ "application/json": {
346018
+ "schema": {
346019
+ "$ref": "#/components/schemas/RateLimitedResponse"
346020
+ }
346021
+ }
346022
+ }
346023
+ },
346024
+ "500": {
346025
+ "description": "Internal server error",
346026
+ "content": {
346027
+ "application/json": {
346028
+ "schema": {
346029
+ "type": "object",
346030
+ "required": [
346031
+ "statusCode",
346032
+ "error",
346033
+ "message"
346034
+ ],
346035
+ "properties": {
346036
+ "statusCode": {
346037
+ "type": "number"
346038
+ },
346039
+ "error": {
346040
+ "type": "string"
346041
+ },
346042
+ "message": {
346043
+ "type": "string"
346044
+ }
346045
+ }
346046
+ }
346047
+ }
346048
+ }
346049
+ },
346050
+ "503": {
346051
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
346052
+ "headers": {
346053
+ "Retry-After": {
346054
+ "description": "Seconds to wait before retrying the identical request.",
346055
+ "schema": {
346056
+ "type": "integer"
346057
+ }
346058
+ }
346059
+ },
346060
+ "content": {
346061
+ "application/json": {
346062
+ "schema": {
346063
+ "$ref": "#/components/schemas/ErrorResponse"
346064
+ }
346065
+ }
346066
+ }
346067
+ }
346068
+ }
346069
+ }
346070
+ },
346071
+ "/api/v1/traffic-filter/offers/{id}/preview-url": {
346072
+ "get": {
346073
+ "operationId": "getApiV1TrafficFilterOffersByIdPreviewUrl",
346074
+ "summary": "Build a signed preview URL for a self-hosted Traffic Filter offer",
346075
+ "tags": [
346076
+ "traffic-filter"
346077
+ ],
346078
+ "description": "Returns the public URL of a `local` offer page with a short-lived signed preview token appended. Only self-hosted offers have a page served by this backend: an offer that points at an external network URL has nothing to preview here and answers 409. The token expires after 10 minutes and is bound to this offer and this team.",
346079
+ "parameters": [
346080
+ {
346081
+ "schema": {
346082
+ "format": "uuid",
346083
+ "type": "string"
346084
+ },
346085
+ "in": "path",
346086
+ "name": "id",
346087
+ "required": true
346088
+ },
346089
+ {
346090
+ "schema": {
346091
+ "format": "uuid",
346092
+ "type": "string"
346093
+ },
346094
+ "in": "header",
346095
+ "name": "x-team-id",
346096
+ "required": false,
346097
+ "description": "Explicit team (workspace) scope: a team.id the caller belongs to."
346098
+ },
346099
+ {
346100
+ "schema": {
346101
+ "type": "string"
346102
+ },
346103
+ "in": "header",
346104
+ "name": "x-active-scope",
346105
+ "required": false,
346106
+ "description": "Active scope selector in `<scopeType>:<uuid>` form, e.g. `organization:<organization_id>` or `team:<team_id>`. Omit the header for the all-workspaces view."
346107
+ }
346108
+ ],
346109
+ "security": [
346110
+ {
346111
+ "bearerAuth": []
346112
+ },
346113
+ {
346114
+ "apiKeyAuth": []
346115
+ }
346116
+ ],
346117
+ "responses": {
346118
+ "200": {
346119
+ "description": "Successful response",
346120
+ "content": {
346121
+ "application/json": {
346122
+ "schema": {
346123
+ "additionalProperties": false,
346124
+ "type": "object",
346125
+ "required": [
346126
+ "url"
346127
+ ],
346128
+ "properties": {
346129
+ "url": {
346130
+ "description": "Absolute public preview URL, token included.",
346131
+ "type": "string"
346132
+ }
346133
+ }
346134
+ }
346135
+ }
346136
+ }
346137
+ },
346138
+ "401": {
346139
+ "description": "Unauthorized - missing or invalid bearer token",
346140
+ "content": {
346141
+ "application/json": {
346142
+ "schema": {
346143
+ "$ref": "#/components/schemas/ErrorResponse"
346144
+ }
346145
+ }
346146
+ }
346147
+ },
346148
+ "404": {
346149
+ "description": "Resource not found",
346150
+ "content": {
346151
+ "application/json": {
346152
+ "schema": {
346153
+ "type": "object",
346154
+ "required": [
346155
+ "statusCode",
346156
+ "error",
346157
+ "message"
346158
+ ],
346159
+ "properties": {
346160
+ "statusCode": {
346161
+ "type": "number"
346162
+ },
346163
+ "error": {
346164
+ "type": "string"
346165
+ },
346166
+ "message": {
346167
+ "type": "string"
346168
+ }
346169
+ }
346170
+ }
346171
+ }
346172
+ }
346173
+ },
346174
+ "409": {
346175
+ "description": "Conflict - resource state prevents the operation",
346176
+ "content": {
346177
+ "application/json": {
346178
+ "schema": {
346179
+ "type": "object",
346180
+ "required": [
346181
+ "statusCode",
346182
+ "error",
346183
+ "message"
346184
+ ],
346185
+ "properties": {
346186
+ "statusCode": {
346187
+ "type": "number"
346188
+ },
346189
+ "error": {
346190
+ "type": "string"
346191
+ },
346192
+ "message": {
346193
+ "type": "string"
346194
+ }
346195
+ }
346196
+ }
346197
+ }
346198
+ }
346199
+ },
346200
+ "429": {
346201
+ "description": "Too many requests - rate limit exceeded. Reachable on every API-key operation: the per-key cap sold with the plan answers `code: API_KEY_RATE_LIMITED` with `retry_after_seconds` and the `Retry-After` header. The global per-IP limiter can answer here too, with the same status and only `statusCode`, `error` and `message`.",
346202
+ "content": {
346203
+ "application/json": {
346204
+ "schema": {
346205
+ "$ref": "#/components/schemas/RateLimitedResponse"
346206
+ }
346207
+ }
346208
+ }
346209
+ },
346210
+ "500": {
346211
+ "description": "Internal server error",
346212
+ "content": {
346213
+ "application/json": {
346214
+ "schema": {
346215
+ "type": "object",
346216
+ "required": [
346217
+ "statusCode",
346218
+ "error",
346219
+ "message"
346220
+ ],
346221
+ "properties": {
346222
+ "statusCode": {
346223
+ "type": "number"
346224
+ },
346225
+ "error": {
346226
+ "type": "string"
346227
+ },
346228
+ "message": {
346229
+ "type": "string"
346230
+ }
346231
+ }
346232
+ }
346233
+ }
346234
+ }
346235
+ },
346236
+ "503": {
346237
+ "description": "Session revocation check unavailable (Redis): retry after the Retry-After header.",
346238
+ "headers": {
346239
+ "Retry-After": {
346240
+ "description": "Seconds to wait before retrying the identical request.",
346241
+ "schema": {
346242
+ "type": "integer"
346243
+ }
346244
+ }
346245
+ },
346246
+ "content": {
346247
+ "application/json": {
346248
+ "schema": {
346249
+ "$ref": "#/components/schemas/ErrorResponse"
346250
+ }
346251
+ }
346252
+ }
346253
+ }
346254
+ }
346255
+ }
346256
+ },
345077
346257
  "/api/v1/traffic-filter/leads": {
345078
346258
  "get": {
345079
346259
  "operationId": "getApiV1TrafficFilterLeads",