@whop/cli 0.6.0 → 0.7.0

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.
@@ -27,7 +27,7 @@ var native_spec_default = {
27
27
  ],
28
28
  tags: [
29
29
  {
30
- description: "An Account represents a person or business in Whop. Each account has its own profile, wallet, and settings, so you can create one for every customer, creator, merchant, or seller your integration supports.\n\nCreate an account when someone needs to hold funds, receive payments, send money, or use account-scoped API features. Save the returned `id` and `wallet` details, and use `metadata` to store your own stable identifier, like a user ID from your system.\n",
30
+ description: "An Account represents a person or business on Whop that can have its own profile, wallet, and account-scoped settings. Use accounts for customers, creators, merchants, sellers, or connected businesses your integration supports.\n\nUse the Accounts API to create accounts, list accounts visible to your credentials, retrieve or update an account, and retrieve the account associated with the current API key.\n",
31
31
  name: "Accounts",
32
32
  "x-whop-summary": "A business on Whop: profile, wallet, capabilities, settings."
33
33
  },
@@ -91,15 +91,17 @@ var native_spec_default = {
91
91
  "x-whop-summary": "Turn a plan into a shareable, prefilled checkout link."
92
92
  },
93
93
  {
94
- description: "Referrals track businesses referred to Whop and the earnings generated from their processing volume. They help you see much volume your referred businesses have processed and how much you've earned from them.\n\nUse the Referrals API to list referred businesses, retrieve one referral, and review earnings across all referrals or for a single referred business.\n",
94
+ description: "Referrals track businesses referred to Whop and the earnings generated from their processing volume. They help you see how much volume your referred businesses have processed and how much you've earned from them.\n\nUse the Referrals API to list referred businesses, retrieve one referral, and review earnings across all referrals or for a single referred business.\n",
95
95
  name: "Referrals",
96
96
  "x-whop-summary": "Track who referred a purchase and what they earn."
97
97
  },
98
98
  {
99
+ description: "A Person represents a visitor or customer of an account, assembled from [pixel events](/api-reference/beta/events/event) and purchase activity \u2014 ad clicks, storefront visits, and checkouts.\n\nUse the People API to list the people of an account and retrieve a single person.\n",
99
100
  name: "People",
100
101
  "x-whop-summary": "Visitors and customers of an account, aggregated from pixel events."
101
102
  },
102
103
  {
104
+ description: "An Event records conversion or engagement activity for an account, such as page views, purchases, or leads. Each event ties the action to the [person](/api-reference/beta/people/person) who took it, so activity can be attributed to the ads and links that drove it.\n\nUse the Events API to send new tracking events and list the events recorded for a person.\n",
103
105
  name: "Events",
104
106
  "x-whop-summary": "Conversion and engagement events tracked for attribution."
105
107
  },
@@ -124,12 +126,19 @@ var native_spec_default = {
124
126
  "x-whop-summary": "Reusable targeting lists for ad groups."
125
127
  },
126
128
  {
129
+ description: "A Media Asset is an AI-generated image or video created from a prompt and billed from an account balance. When generation finishes, the asset includes a file that can be attached anywhere Whop accepts files.\n\nUse the Media API to start a generation job and retrieve the asset while it processes or after it is ready.\n",
127
130
  name: "Media",
128
131
  "x-whop-summary": "AI-generated assets, billed from a balance, attachable wherever files are accepted."
129
132
  },
130
133
  {
134
+ description: "A Social Account represents an external profile connected to a Whop account or user, such as a Facebook page or Instagram account. Connecting a social account lets Whop run [ads](/api-reference/beta/ads/ad) under that profile's identity and promote its existing posts.\n\nUse the Social Accounts API to list connected accounts, create a Whop-managed Facebook page, start an OAuth connection, disconnect a social account, and list a connected profile's posts.\n",
131
135
  name: "Social Accounts",
132
136
  "x-whop-summary": "Connected Facebook and Instagram accounts that run ads."
137
+ },
138
+ {
139
+ description: "An App is software you build on the Whop platform \u2014 from a fully-hosted web app served at `<route>.whop.app` to an API integration installed into whops as experiences. Apps belong to an account and hold their own credentials and settings.\n\nUse the Apps API to create and configure apps, and \u2014 for hosted apps \u2014 read their server runtime logs: every console line, uncaught exception, and failed request is captured for 7 days and queryable by build, level, time window, and message text.\n",
140
+ name: "Apps",
141
+ "x-whop-summary": "Apps you build on Whop: metadata, hosted builds, runtime logs."
133
142
  }
134
143
  ],
135
144
  "x-tagGroups": [
@@ -198,6 +207,13 @@ var native_spec_default = {
198
207
  tags: [
199
208
  "Social Accounts"
200
209
  ]
210
+ },
211
+ {
212
+ description: "Build, host, and observe apps on the Whop platform.",
213
+ name: "Developer",
214
+ tags: [
215
+ "Apps"
216
+ ]
201
217
  }
202
218
  ],
203
219
  paths: {
@@ -942,6 +958,302 @@ var native_spec_default = {
942
958
  ]
943
959
  }
944
960
  },
961
+ "/accounts/{account_id}/preferences": {
962
+ get: {
963
+ description: "Retrieves the account's preferences: a singleton settings document keyed by preference name.",
964
+ operationId: "preferences",
965
+ responses: {
966
+ "200": {
967
+ content: {
968
+ "application/json": {
969
+ schema: {
970
+ properties: {
971
+ ads_payment_methods: {
972
+ description: "How the account pays for Whop Ads spend. `primary` is charged first; `backup` covers the charge when the primary fails. `null` until ads billing has been configured.",
973
+ properties: {
974
+ backup: {
975
+ properties: {
976
+ id: {
977
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`.",
978
+ type: "string"
979
+ },
980
+ type: {
981
+ description: "The funding source kind: a ledger balance or a saved card.",
982
+ enum: [
983
+ "platform_balance",
984
+ "card"
985
+ ],
986
+ type: "string"
987
+ }
988
+ },
989
+ required: [
990
+ "type",
991
+ "id"
992
+ ],
993
+ type: [
994
+ "object",
995
+ "null"
996
+ ]
997
+ },
998
+ primary: {
999
+ properties: {
1000
+ id: {
1001
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`.",
1002
+ type: "string"
1003
+ },
1004
+ type: {
1005
+ description: "The funding source kind: a ledger balance or a saved card.",
1006
+ enum: [
1007
+ "platform_balance",
1008
+ "card"
1009
+ ],
1010
+ type: "string"
1011
+ }
1012
+ },
1013
+ required: [
1014
+ "type",
1015
+ "id"
1016
+ ],
1017
+ type: [
1018
+ "object",
1019
+ "null"
1020
+ ]
1021
+ }
1022
+ },
1023
+ required: [
1024
+ "primary",
1025
+ "backup"
1026
+ ],
1027
+ type: [
1028
+ "object",
1029
+ "null"
1030
+ ]
1031
+ }
1032
+ },
1033
+ required: [
1034
+ "ads_payment_methods"
1035
+ ],
1036
+ type: "object"
1037
+ }
1038
+ }
1039
+ },
1040
+ description: "preferences retrieved"
1041
+ },
1042
+ "401": {
1043
+ $ref: "#/components/responses/Unauthorized",
1044
+ description: "unauthorized"
1045
+ },
1046
+ "404": {
1047
+ $ref: "#/components/responses/NotFound",
1048
+ description: "account not found"
1049
+ }
1050
+ },
1051
+ security: [
1052
+ {
1053
+ bearerAuth: [
1054
+ "ad_campaign:create"
1055
+ ]
1056
+ }
1057
+ ],
1058
+ summary: "Retrieve Account Preferences",
1059
+ tags: [
1060
+ "Accounts"
1061
+ ],
1062
+ parameters: [
1063
+ {
1064
+ description: "Account ID, prefixed `biz_`.",
1065
+ in: "path",
1066
+ name: "account_id",
1067
+ required: true,
1068
+ schema: {
1069
+ type: "string"
1070
+ }
1071
+ }
1072
+ ]
1073
+ },
1074
+ patch: {
1075
+ description: "Updates the account's preferences. Each top-level key present in the body is replaced as a whole; omitted keys are left untouched. `ads_payment_methods` always requires a `primary` entry. `backup` is optional when the primary is `platform_balance` \u2014 omitting it removes any configured card \u2014 while a `card` primary requires a `platform_balance` backup. A `platform_balance` entry may omit `id` to use the account's own balance ledger. Changing which funding sources are configured requires a user token, while account API keys may only swap `primary` and `backup`.",
1076
+ operationId: "update-preferences",
1077
+ parameters: [
1078
+ {
1079
+ description: "Account ID, prefixed `biz_`.",
1080
+ in: "path",
1081
+ name: "account_id",
1082
+ required: true,
1083
+ schema: {
1084
+ type: "string"
1085
+ }
1086
+ }
1087
+ ],
1088
+ requestBody: {
1089
+ content: {
1090
+ "application/json": {
1091
+ schema: {
1092
+ properties: {
1093
+ ads_payment_methods: {
1094
+ description: "How the account pays for Whop Ads spend. `primary` is charged first; `backup` covers the charge when the primary fails.",
1095
+ properties: {
1096
+ backup: {
1097
+ description: "Optional when the primary is `platform_balance`; omitting it removes any configured card. Required (as `platform_balance`) when the primary is `card`.",
1098
+ properties: {
1099
+ id: {
1100
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`. Optional for `platform_balance` \u2014 defaults to the account's own balance ledger. Required for `card`.",
1101
+ type: "string"
1102
+ },
1103
+ type: {
1104
+ description: "The funding source kind.",
1105
+ enum: [
1106
+ "platform_balance",
1107
+ "card"
1108
+ ],
1109
+ type: "string"
1110
+ }
1111
+ },
1112
+ required: [
1113
+ "type"
1114
+ ],
1115
+ type: "object"
1116
+ },
1117
+ primary: {
1118
+ properties: {
1119
+ id: {
1120
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`. Optional for `platform_balance` \u2014 defaults to the account's own balance ledger. Required for `card`.",
1121
+ type: "string"
1122
+ },
1123
+ type: {
1124
+ description: "The funding source kind.",
1125
+ enum: [
1126
+ "platform_balance",
1127
+ "card"
1128
+ ],
1129
+ type: "string"
1130
+ }
1131
+ },
1132
+ required: [
1133
+ "type"
1134
+ ],
1135
+ type: "object"
1136
+ }
1137
+ },
1138
+ required: [
1139
+ "primary"
1140
+ ],
1141
+ type: "object"
1142
+ }
1143
+ },
1144
+ type: "object"
1145
+ }
1146
+ }
1147
+ },
1148
+ required: true
1149
+ },
1150
+ responses: {
1151
+ "200": {
1152
+ content: {
1153
+ "application/json": {
1154
+ schema: {
1155
+ properties: {
1156
+ ads_payment_methods: {
1157
+ description: "How the account pays for Whop Ads spend. `primary` is charged first; `backup` covers the charge when the primary fails. `null` until ads billing has been configured.",
1158
+ properties: {
1159
+ backup: {
1160
+ properties: {
1161
+ id: {
1162
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`.",
1163
+ type: "string"
1164
+ },
1165
+ type: {
1166
+ description: "The funding source kind: a ledger balance or a saved card.",
1167
+ enum: [
1168
+ "platform_balance",
1169
+ "card"
1170
+ ],
1171
+ type: "string"
1172
+ }
1173
+ },
1174
+ required: [
1175
+ "type",
1176
+ "id"
1177
+ ],
1178
+ type: [
1179
+ "object",
1180
+ "null"
1181
+ ]
1182
+ },
1183
+ primary: {
1184
+ properties: {
1185
+ id: {
1186
+ description: "The funding source ID: a ledger account (`ldgr_`) for `platform_balance`, a payment method (`payt_`) for `card`.",
1187
+ type: "string"
1188
+ },
1189
+ type: {
1190
+ description: "The funding source kind: a ledger balance or a saved card.",
1191
+ enum: [
1192
+ "platform_balance",
1193
+ "card"
1194
+ ],
1195
+ type: "string"
1196
+ }
1197
+ },
1198
+ required: [
1199
+ "type",
1200
+ "id"
1201
+ ],
1202
+ type: [
1203
+ "object",
1204
+ "null"
1205
+ ]
1206
+ }
1207
+ },
1208
+ required: [
1209
+ "primary",
1210
+ "backup"
1211
+ ],
1212
+ type: [
1213
+ "object",
1214
+ "null"
1215
+ ]
1216
+ }
1217
+ },
1218
+ required: [
1219
+ "ads_payment_methods"
1220
+ ],
1221
+ type: "object"
1222
+ }
1223
+ }
1224
+ },
1225
+ description: "preferences updated"
1226
+ },
1227
+ "400": {
1228
+ $ref: "#/components/responses/InvalidParameters",
1229
+ description: "invalid preferences"
1230
+ },
1231
+ "401": {
1232
+ $ref: "#/components/responses/Unauthorized",
1233
+ description: "unauthorized"
1234
+ },
1235
+ "403": {
1236
+ $ref: "#/components/responses/Forbidden",
1237
+ description: "forbidden"
1238
+ },
1239
+ "404": {
1240
+ $ref: "#/components/responses/NotFound",
1241
+ description: "account not found"
1242
+ }
1243
+ },
1244
+ security: [
1245
+ {
1246
+ bearerAuth: [
1247
+ "ad_campaign:create"
1248
+ ]
1249
+ }
1250
+ ],
1251
+ summary: "Update Account Preferences",
1252
+ tags: [
1253
+ "Accounts"
1254
+ ]
1255
+ }
1256
+ },
945
1257
  "/ad_campaigns": {
946
1258
  get: {
947
1259
  description: "Lists the ad campaigns for an account, with stats over the requested window.",
@@ -2676,9 +2988,27 @@ var native_spec_default = {
2676
2988
  type: "string"
2677
2989
  },
2678
2990
  creatives: {
2679
- description: "The ad's creatives. Each entry is an uploaded file id with an optional format; omit format for the original/uncropped asset.",
2991
+ description: "The ad's creative assets. Each entry is an uploaded file id with an optional format; omit format for the original asset.",
2680
2992
  items: {
2681
2993
  properties: {
2994
+ crop: {
2995
+ description: "The saved crop window for this creative, in source image pixels. Omit it for the original asset or for a format that has not been cropped.",
2996
+ properties: {
2997
+ height: {
2998
+ type: "number"
2999
+ },
3000
+ width: {
3001
+ type: "number"
3002
+ },
3003
+ x: {
3004
+ type: "number"
3005
+ },
3006
+ y: {
3007
+ type: "number"
3008
+ }
3009
+ },
3010
+ type: "object"
3011
+ },
2682
3012
  format: {
2683
3013
  enum: [
2684
3014
  "square",
@@ -2710,7 +3040,7 @@ var native_spec_default = {
2710
3040
  type: "array"
2711
3041
  },
2712
3042
  lead_form: {
2713
- description: "Instant lead form for the ad. Only allowed when the ad group's conversion_location is an instant-form destination (instant_forms, instant_forms_and_messenger, website_and_instant_forms).",
3043
+ description: "Instant lead form for the ad. Only allowed when the ad group's conversion_location is an instant-form destination (instant_forms, instant_forms_and_messenger, website_and_instant_forms). Mutually exclusive with lead_form_id.",
2714
3044
  properties: {
2715
3045
  completion: {
2716
3046
  description: "Optional completion screen shown after submission; url sets the follow-up website button.",
@@ -2884,6 +3214,10 @@ var native_spec_default = {
2884
3214
  },
2885
3215
  type: "object"
2886
3216
  },
3217
+ lead_form_id: {
3218
+ description: "Use an existing Meta instant form instead of creating one \u2014 the form's Meta id, from a form already on the ad's Facebook page. Only allowed when the ad group's conversion_location is an instant-form destination. Mutually exclusive with lead_form.",
3219
+ type: "string"
3220
+ },
2887
3221
  messaging_config: {
2888
3222
  description: "Click-to-message welcome copy: the greeting (message) and the ice-breaker prompt (keyword).",
2889
3223
  properties: {
@@ -3152,9 +3486,27 @@ var native_spec_default = {
3152
3486
  type: "string"
3153
3487
  },
3154
3488
  creatives: {
3155
- description: "The ad's creatives. Each entry is an uploaded file id with an optional format; omit format for the original/uncropped asset. Replaces a live ad's creative on the platform.",
3489
+ description: "The ad's creative assets. Each entry is an uploaded file id with an optional format; omit format for the original asset. Replaces a live ad's creative on the platform.",
3156
3490
  items: {
3157
3491
  properties: {
3492
+ crop: {
3493
+ description: "The saved crop window for this creative, in source image pixels. Omit it for the original asset or for a format that has not been cropped.",
3494
+ properties: {
3495
+ height: {
3496
+ type: "number"
3497
+ },
3498
+ width: {
3499
+ type: "number"
3500
+ },
3501
+ x: {
3502
+ type: "number"
3503
+ },
3504
+ y: {
3505
+ type: "number"
3506
+ }
3507
+ },
3508
+ type: "object"
3509
+ },
3158
3510
  format: {
3159
3511
  enum: [
3160
3512
  "square",
@@ -3186,7 +3538,7 @@ var native_spec_default = {
3186
3538
  type: "array"
3187
3539
  },
3188
3540
  lead_form: {
3189
- description: "Instant lead form for the ad. Only allowed when the ad group's conversion_location is an instant-form destination (instant_forms, instant_forms_and_messenger, website_and_instant_forms).",
3541
+ description: "Instant lead form for the ad. Only allowed when the ad group's conversion_location is an instant-form destination (instant_forms, instant_forms_and_messenger, website_and_instant_forms). Mutually exclusive with lead_form_id.",
3190
3542
  properties: {
3191
3543
  completion: {
3192
3544
  description: "Optional completion screen shown after submission; url sets the follow-up website button.",
@@ -3360,6 +3712,10 @@ var native_spec_default = {
3360
3712
  },
3361
3713
  type: "object"
3362
3714
  },
3715
+ lead_form_id: {
3716
+ description: "Use an existing Meta instant form instead of creating one \u2014 the form's Meta id, from a form already on the ad's Facebook page. Only allowed when the ad group's conversion_location is an instant-form destination. Mutually exclusive with lead_form. Replaces a stored lead_form.",
3717
+ type: "string"
3718
+ },
3363
3719
  messaging_config: {
3364
3720
  description: "Click-to-message welcome copy: the greeting (message) and the ice-breaker prompt (keyword).",
3365
3721
  properties: {
@@ -3537,6 +3893,255 @@ var native_spec_default = {
3537
3893
  ]
3538
3894
  }
3539
3895
  },
3896
+ "/apps/{id}/logs": {
3897
+ get: {
3898
+ description: "Lists a hosted app's server runtime logs, most recent first: console output, uncaught exceptions, and failed-request summaries captured on whop.app hosting. Logs are retained for 7 days.",
3899
+ operationId: "logs",
3900
+ parameters: [
3901
+ {
3902
+ description: "The ID of the app, which will look like app_*************.",
3903
+ in: "path",
3904
+ name: "id",
3905
+ required: true,
3906
+ schema: {
3907
+ type: "string"
3908
+ }
3909
+ },
3910
+ {
3911
+ description: "Only return logs from this build.",
3912
+ in: "query",
3913
+ name: "app_build_id",
3914
+ required: false,
3915
+ schema: {
3916
+ type: "string"
3917
+ }
3918
+ },
3919
+ {
3920
+ description: "Only return console lines of this level.",
3921
+ in: "query",
3922
+ name: "level",
3923
+ required: false,
3924
+ schema: {
3925
+ enum: [
3926
+ "log",
3927
+ "debug",
3928
+ "info",
3929
+ "warn",
3930
+ "error"
3931
+ ],
3932
+ type: "string"
3933
+ }
3934
+ },
3935
+ {
3936
+ description: "Only return logs whose message contains this text (case-insensitive).",
3937
+ in: "query",
3938
+ name: "query",
3939
+ required: false,
3940
+ schema: {
3941
+ type: "string"
3942
+ }
3943
+ },
3944
+ {
3945
+ description: "Start of the time window as an ISO 8601 timestamp. Defaults to 7 days before created_before.",
3946
+ in: "query",
3947
+ name: "created_after",
3948
+ required: false,
3949
+ schema: {
3950
+ format: "date-time",
3951
+ type: "string"
3952
+ }
3953
+ },
3954
+ {
3955
+ description: "End of the time window as an ISO 8601 timestamp. Defaults to now.",
3956
+ in: "query",
3957
+ name: "created_before",
3958
+ required: false,
3959
+ schema: {
3960
+ format: "date-time",
3961
+ type: "string"
3962
+ }
3963
+ },
3964
+ {
3965
+ description: "The number of log lines to return (max 500).",
3966
+ in: "query",
3967
+ name: "first",
3968
+ required: false,
3969
+ schema: {
3970
+ type: "integer"
3971
+ }
3972
+ },
3973
+ {
3974
+ description: "A cursor for fetching logs after a previous page.",
3975
+ in: "query",
3976
+ name: "after",
3977
+ required: false,
3978
+ schema: {
3979
+ type: "string"
3980
+ }
3981
+ },
3982
+ {
3983
+ description: "A cursor for fetching logs before a later page.",
3984
+ in: "query",
3985
+ name: "before",
3986
+ required: false,
3987
+ schema: {
3988
+ type: "string"
3989
+ }
3990
+ }
3991
+ ],
3992
+ responses: {
3993
+ "200": {
3994
+ content: {
3995
+ "application/json": {
3996
+ schema: {
3997
+ properties: {
3998
+ data: {
3999
+ items: {
4000
+ properties: {
4001
+ app_build_id: {
4002
+ type: "string"
4003
+ },
4004
+ app_id: {
4005
+ type: "string"
4006
+ },
4007
+ cpu_time_ms: {
4008
+ type: "integer"
4009
+ },
4010
+ created_at: {
4011
+ format: "date-time",
4012
+ type: "string"
4013
+ },
4014
+ level: {
4015
+ type: "string"
4016
+ },
4017
+ message: {
4018
+ type: "string"
4019
+ },
4020
+ outcome: {
4021
+ type: [
4022
+ "string",
4023
+ "null"
4024
+ ]
4025
+ },
4026
+ request_id: {
4027
+ type: "string"
4028
+ },
4029
+ request_method: {
4030
+ type: [
4031
+ "string",
4032
+ "null"
4033
+ ]
4034
+ },
4035
+ request_path: {
4036
+ type: [
4037
+ "string",
4038
+ "null"
4039
+ ]
4040
+ },
4041
+ response_status: {
4042
+ type: [
4043
+ "integer",
4044
+ "null"
4045
+ ]
4046
+ },
4047
+ source: {
4048
+ enum: [
4049
+ "console",
4050
+ "exception",
4051
+ "request"
4052
+ ],
4053
+ type: "string"
4054
+ },
4055
+ stack: {
4056
+ type: [
4057
+ "string",
4058
+ "null"
4059
+ ]
4060
+ },
4061
+ truncated: {
4062
+ type: "boolean"
4063
+ },
4064
+ wall_time_ms: {
4065
+ type: "integer"
4066
+ }
4067
+ },
4068
+ required: [
4069
+ "app_id",
4070
+ "app_build_id",
4071
+ "request_id",
4072
+ "created_at",
4073
+ "source",
4074
+ "level",
4075
+ "message"
4076
+ ],
4077
+ type: "object"
4078
+ },
4079
+ type: "array"
4080
+ },
4081
+ page_info: {
4082
+ properties: {
4083
+ end_cursor: {
4084
+ type: [
4085
+ "string",
4086
+ "null"
4087
+ ]
4088
+ },
4089
+ has_next_page: {
4090
+ type: "boolean"
4091
+ },
4092
+ has_previous_page: {
4093
+ type: "boolean"
4094
+ },
4095
+ start_cursor: {
4096
+ type: [
4097
+ "string",
4098
+ "null"
4099
+ ]
4100
+ }
4101
+ },
4102
+ required: [
4103
+ "has_next_page",
4104
+ "has_previous_page"
4105
+ ],
4106
+ type: "object"
4107
+ }
4108
+ },
4109
+ required: [
4110
+ "data",
4111
+ "page_info"
4112
+ ],
4113
+ type: "object"
4114
+ }
4115
+ }
4116
+ },
4117
+ description: "logs listed"
4118
+ },
4119
+ "401": {
4120
+ $ref: "#/components/responses/Unauthorized",
4121
+ description: "missing or invalid authentication"
4122
+ },
4123
+ "403": {
4124
+ $ref: "#/components/responses/Forbidden",
4125
+ description: "missing the developer:logs:read scope"
4126
+ },
4127
+ "404": {
4128
+ $ref: "#/components/responses/NotFound",
4129
+ description: "app not found"
4130
+ }
4131
+ },
4132
+ security: [
4133
+ {
4134
+ bearerAuth: [
4135
+ "developer:logs:read"
4136
+ ]
4137
+ }
4138
+ ],
4139
+ summary: "List App Logs",
4140
+ tags: [
4141
+ "Apps"
4142
+ ]
4143
+ }
4144
+ },
3540
4145
  "/audiences": {
3541
4146
  get: {
3542
4147
  description: "Lists uploaded customer-list audiences for an account. Pass `audience_id` to return a specific audience.",
@@ -7616,7 +8221,7 @@ var native_spec_default = {
7616
8221
  },
7617
8222
  "/financial-activity": {
7618
8223
  get: {
7619
- description: "Returns a paginated activity feed for one account or user, derived from ledger lines with typed resource and source objects for presentation. Pass exactly one of `account_id` (a `biz_` identifier) or `user_id` (a `user_` identifier). Filter by line type, currency, posted timestamp, or settlement date to reconcile a specific window.",
8224
+ description: "Returns a paginated activity feed for one account or user, derived from ledger lines with typed resource and source objects for presentation. Pass exactly one of `account_id` (a `biz_` identifier) or `user_id` (a `user_` identifier). Filter by line type, currency, posted timestamp, or settlement date to reconcile a specific window. Pass `include_owned_accounts=true` with your own `user_id` to aggregate your personal ledger and the businesses you own into one feed; each row then carries the owning `account`.",
7620
8225
  operationId: "list",
7621
8226
  parameters: [
7622
8227
  {
@@ -7637,6 +8242,15 @@ var native_spec_default = {
7637
8242
  type: "string"
7638
8243
  }
7639
8244
  },
8245
+ {
8246
+ description: "When true, aggregates the authenticated user's personal ledger with the businesses they own (owner role with balance read) into one feed. Requires user_id to be the authenticated user; cannot be combined with account_id or the settlement-date filters. Each returned row includes the owning `account`.",
8247
+ in: "query",
8248
+ name: "include_owned_accounts",
8249
+ required: false,
8250
+ schema: {
8251
+ type: "boolean"
8252
+ }
8253
+ },
7640
8254
  {
7641
8255
  description: "Optional ledger line categories to include. Some categories (for example `onchain_deposit`, which covers inbound crypto deposits such as MoonPay onramps) are only returned when explicitly requested here.",
7642
8256
  explode: true,
@@ -8072,7 +8686,7 @@ var native_spec_default = {
8072
8686
  type: "string"
8073
8687
  },
8074
8688
  reference_media: {
8075
- description: "Optional reference image file IDs (`file_` prefixed), up to 4. For video the first reference seeds the opening frame.",
8689
+ description: "Optional reference image file IDs (`file_` prefixed), up to 4. For video, a single reference seeds the opening frame; multiple references guide subject and style instead.",
8076
8690
  items: {
8077
8691
  type: "string"
8078
8692
  },
@@ -8380,6 +8994,13 @@ var native_spec_default = {
8380
8994
  "null"
8381
8995
  ]
8382
8996
  },
8997
+ payout_request_id: {
8998
+ description: "The id POST /payouts returned when this payout was requested \u2014 match it to find your settled payout. Null for fiat-ledger payouts.",
8999
+ type: [
9000
+ "string",
9001
+ "null"
9002
+ ]
9003
+ },
8383
9004
  payout_token: {
8384
9005
  description: "The saved payout method used. Requires payout:destination:read; null without it.",
8385
9006
  properties: {
@@ -8452,6 +9073,7 @@ var native_spec_default = {
8452
9073
  required: [
8453
9074
  "object",
8454
9075
  "id",
9076
+ "payout_request_id",
8455
9077
  "status",
8456
9078
  "amount",
8457
9079
  "currency",
@@ -8534,6 +9156,217 @@ var native_spec_default = {
8534
9156
  tags: [
8535
9157
  "Payouts"
8536
9158
  ]
9159
+ },
9160
+ post: {
9161
+ description: "Creates a payout from a stablecoin account to a saved payout method. The account's funds are moved from its stablecoin balance through the payout provider to the destination. Only available for stablecoin accounts \u2014 fiat-ledger accounts use POST /withdrawals. Requires the payouts API to be enabled for the account; contact support to enable it. The payout settles asynchronously; poll GET /payouts for the entry whose payout_request_id matches this payout's id.",
9162
+ operationId: "create",
9163
+ parameters: [
9164
+ {
9165
+ $ref: "#/components/parameters/ApiVersionDate"
9166
+ }
9167
+ ],
9168
+ requestBody: {
9169
+ content: {
9170
+ "application/json": {
9171
+ schema: {
9172
+ properties: {
9173
+ account_id: {
9174
+ description: "The account to pay out from (a biz_ identifier).",
9175
+ type: "string"
9176
+ },
9177
+ amount: {
9178
+ description: "The amount to pay out in the specified currency.",
9179
+ format: "float",
9180
+ type: "number"
9181
+ },
9182
+ currency: {
9183
+ description: "The payout currency. Defaults to usd.",
9184
+ type: "string"
9185
+ },
9186
+ idempotency_key: {
9187
+ description: "A client-generated key that makes retries safe. Retrying with the same key returns the original payout instead of creating a second one.",
9188
+ type: "string"
9189
+ },
9190
+ payout_method_id: {
9191
+ description: "The saved payout method to deliver to (a potk_ identifier).",
9192
+ type: "string"
9193
+ }
9194
+ },
9195
+ required: [
9196
+ "account_id",
9197
+ "amount",
9198
+ "payout_method_id"
9199
+ ],
9200
+ type: "object"
9201
+ }
9202
+ }
9203
+ },
9204
+ required: true
9205
+ },
9206
+ responses: {
9207
+ "201": {
9208
+ content: {
9209
+ "application/json": {
9210
+ schema: {
9211
+ properties: {
9212
+ amount: {
9213
+ description: "The payout amount in whole currency units.",
9214
+ format: "float",
9215
+ type: "number"
9216
+ },
9217
+ created_at: {
9218
+ description: "When the payout was created.",
9219
+ format: "date-time",
9220
+ type: "string"
9221
+ },
9222
+ currency: {
9223
+ description: "Payout currency.",
9224
+ type: "string"
9225
+ },
9226
+ estimated_arrival: {
9227
+ description: "Estimated time the funds become available in the destination account. Null until the payout settles.",
9228
+ format: "date-time",
9229
+ type: [
9230
+ "string",
9231
+ "null"
9232
+ ]
9233
+ },
9234
+ fee_amount: {
9235
+ description: "The fee charged for the payout, in the payout currency.",
9236
+ format: "float",
9237
+ type: "number"
9238
+ },
9239
+ id: {
9240
+ description: "Payout ID.",
9241
+ type: "string"
9242
+ },
9243
+ object: {
9244
+ enum: [
9245
+ "payout"
9246
+ ],
9247
+ type: "string"
9248
+ },
9249
+ payer_name: {
9250
+ description: "Name of the entity processing the payout. Null until the payout settles.",
9251
+ type: [
9252
+ "string",
9253
+ "null"
9254
+ ]
9255
+ },
9256
+ payout_token: {
9257
+ description: "The saved payout method used. Requires payout:destination:read; null without it.",
9258
+ properties: {
9259
+ nickname: {
9260
+ description: "Saved payout method nickname.",
9261
+ type: [
9262
+ "string",
9263
+ "null"
9264
+ ]
9265
+ },
9266
+ payout_destination: {
9267
+ description: "Payout destination display details.",
9268
+ properties: {
9269
+ icon_url: {
9270
+ description: "Payout destination icon URL.",
9271
+ type: [
9272
+ "string",
9273
+ "null"
9274
+ ]
9275
+ },
9276
+ payer_name: {
9277
+ description: "Payout destination display name.",
9278
+ type: [
9279
+ "string",
9280
+ "null"
9281
+ ]
9282
+ }
9283
+ },
9284
+ required: [
9285
+ "payer_name",
9286
+ "icon_url"
9287
+ ],
9288
+ type: [
9289
+ "object",
9290
+ "null"
9291
+ ]
9292
+ }
9293
+ },
9294
+ required: [
9295
+ "nickname",
9296
+ "payout_destination"
9297
+ ],
9298
+ type: [
9299
+ "object",
9300
+ "null"
9301
+ ]
9302
+ },
9303
+ speed: {
9304
+ description: "Payout delivery speed.",
9305
+ enum: [
9306
+ "standard",
9307
+ "instant"
9308
+ ],
9309
+ type: "string"
9310
+ },
9311
+ status: {
9312
+ description: "Current payout status, in the same vocabulary as GET /payouts.",
9313
+ enum: [
9314
+ "requested",
9315
+ "in_transit",
9316
+ "completed",
9317
+ "failed",
9318
+ "canceled"
9319
+ ],
9320
+ type: "string"
9321
+ }
9322
+ },
9323
+ required: [
9324
+ "object",
9325
+ "id",
9326
+ "status",
9327
+ "amount",
9328
+ "currency",
9329
+ "fee_amount",
9330
+ "speed",
9331
+ "created_at",
9332
+ "estimated_arrival",
9333
+ "payer_name",
9334
+ "payout_token"
9335
+ ],
9336
+ type: "object"
9337
+ }
9338
+ }
9339
+ },
9340
+ description: "payout created"
9341
+ },
9342
+ "400": {
9343
+ $ref: "#/components/responses/InvalidParameters",
9344
+ description: "amount is not a number"
9345
+ },
9346
+ "401": {
9347
+ $ref: "#/components/responses/Unauthorized",
9348
+ description: "missing or invalid authentication"
9349
+ },
9350
+ "403": {
9351
+ $ref: "#/components/responses/Forbidden",
9352
+ description: "credential lacks the withdraw-funds scope"
9353
+ },
9354
+ "404": {
9355
+ $ref: "#/components/responses/NotFound",
9356
+ description: "payout method not found"
9357
+ }
9358
+ },
9359
+ security: [
9360
+ {
9361
+ bearerAuth: [
9362
+ "payout:withdraw_funds"
9363
+ ]
9364
+ }
9365
+ ],
9366
+ summary: "Create Payout",
9367
+ tags: [
9368
+ "Payouts"
9369
+ ]
8537
9370
  }
8538
9371
  },
8539
9372
  "/payouts/methods": {
@@ -11429,18 +12262,36 @@ var native_spec_default = {
11429
12262
  }
11430
12263
  },
11431
12264
  {
11432
- description: "Only return business referrals with a transaction before this timestamp.",
12265
+ description: "Only return business referrals created before this timestamp.",
12266
+ in: "query",
12267
+ name: "created_before",
12268
+ required: false,
12269
+ schema: {
12270
+ type: "string"
12271
+ }
12272
+ },
12273
+ {
12274
+ description: "Only return business referrals created after this timestamp.",
12275
+ in: "query",
12276
+ name: "created_after",
12277
+ required: false,
12278
+ schema: {
12279
+ type: "string"
12280
+ }
12281
+ },
12282
+ {
12283
+ description: "Filter to businesses attributed to this referred user \u2014 the business owner for first-tier referrals, or the partner you recruited for second-tier referrals.",
11433
12284
  in: "query",
11434
- name: "active_before",
12285
+ name: "referred_user_id",
11435
12286
  required: false,
11436
12287
  schema: {
11437
12288
  type: "string"
11438
12289
  }
11439
12290
  },
11440
12291
  {
11441
- description: "Only return business referrals with a transaction after this timestamp.",
12292
+ description: "Same as referred_user_id but resolved by exact username. Ignored when referred_user_id is present.",
11442
12293
  in: "query",
11443
- name: "active_after",
12294
+ name: "referred_username",
11444
12295
  required: false,
11445
12296
  schema: {
11446
12297
  type: "string"
@@ -11530,52 +12381,69 @@ var native_spec_default = {
11530
12381
  ],
11531
12382
  type: "object"
11532
12383
  },
12384
+ first_tier_partner: {
12385
+ description: "The partner who referred the business owner onto Whop (first tier). Null if there is no active first-tier partner.",
12386
+ properties: {
12387
+ id: {
12388
+ description: "User ID, prefixed `user_`.",
12389
+ type: "string"
12390
+ },
12391
+ name: {
12392
+ description: "The user's display name.",
12393
+ type: [
12394
+ "string",
12395
+ "null"
12396
+ ]
12397
+ },
12398
+ profile_picture: {
12399
+ description: "The user's profile picture.",
12400
+ properties: {
12401
+ url: {
12402
+ description: "The user's profile picture URL.",
12403
+ type: "string"
12404
+ }
12405
+ },
12406
+ required: [
12407
+ "url"
12408
+ ],
12409
+ type: "object"
12410
+ },
12411
+ username: {
12412
+ description: "The user's unique username.",
12413
+ type: "string"
12414
+ }
12415
+ },
12416
+ required: [
12417
+ "id",
12418
+ "username",
12419
+ "name",
12420
+ "profile_picture"
12421
+ ],
12422
+ type: [
12423
+ "object",
12424
+ "null"
12425
+ ]
12426
+ },
11533
12427
  id: {
11534
12428
  description: "Business referral ID.",
11535
12429
  type: "string"
11536
12430
  },
11537
- object: {
12431
+ my_partner_tier: {
12432
+ description: "Which tier the caller earns on for this business: `first` (they referred the owner) or `second` (they referred the first-tier partner).",
11538
12433
  enum: [
11539
- "business_referral"
12434
+ "first",
12435
+ "second"
11540
12436
  ],
11541
12437
  type: "string"
11542
12438
  },
11543
- payout_percentage: {
11544
- description: "Referrer's share of Whop gross profit, as a fraction (0.3 = 30%). Second-tier referrals earn a flat 0.1.",
11545
- format: "float",
11546
- type: "number"
11547
- },
11548
- referral_expires_at: {
11549
- description: "When the referral expires.",
11550
- format: "date-time",
11551
- type: [
11552
- "string",
11553
- "null"
11554
- ]
11555
- },
11556
- referral_started_at: {
11557
- description: "When the referral became active.",
11558
- format: "date-time",
11559
- type: [
11560
- "string",
11561
- "null"
11562
- ]
11563
- },
11564
- second_tier: {
11565
- description: "Whether the acting user is the second-tier (grandparent) referrer, not the direct referrer.",
11566
- type: "boolean"
11567
- },
11568
- status: {
11569
- description: "Current referral status.",
12439
+ object: {
11570
12440
  enum: [
11571
- "active",
11572
- "removed"
12441
+ "business_referral"
11573
12442
  ],
11574
- example: "active",
11575
12443
  type: "string"
11576
12444
  },
11577
- user: {
11578
- description: "Owner of the referred account.",
12445
+ owner: {
12446
+ description: "The owner of the referred business.",
11579
12447
  properties: {
11580
12448
  id: {
11581
12449
  description: "User ID, prefixed `user_`.",
@@ -11617,6 +12485,36 @@ var native_spec_default = {
11617
12485
  "null"
11618
12486
  ]
11619
12487
  },
12488
+ payout_percentage: {
12489
+ description: "Referrer's share of Whop gross profit, as a fraction (0.3 = 30%). Second-tier referrals earn a flat 0.1.",
12490
+ format: "float",
12491
+ type: "number"
12492
+ },
12493
+ referral_expires_at: {
12494
+ description: "When the referral expires.",
12495
+ format: "date-time",
12496
+ type: [
12497
+ "string",
12498
+ "null"
12499
+ ]
12500
+ },
12501
+ referral_started_at: {
12502
+ description: "When the referral became active.",
12503
+ format: "date-time",
12504
+ type: [
12505
+ "string",
12506
+ "null"
12507
+ ]
12508
+ },
12509
+ status: {
12510
+ description: "Current referral status.",
12511
+ enum: [
12512
+ "active",
12513
+ "removed"
12514
+ ],
12515
+ example: "active",
12516
+ type: "string"
12517
+ },
11620
12518
  volume_usd: {
11621
12519
  properties: {
11622
12520
  attributed: {
@@ -11644,9 +12542,10 @@ var native_spec_default = {
11644
12542
  "object",
11645
12543
  "id",
11646
12544
  "account",
11647
- "user",
12545
+ "owner",
12546
+ "first_tier_partner",
12547
+ "my_partner_tier",
11648
12548
  "status",
11649
- "second_tier",
11650
12549
  "payout_percentage",
11651
12550
  "referral_started_at",
11652
12551
  "referral_expires_at",
@@ -12076,51 +12975,69 @@ var native_spec_default = {
12076
12975
  ],
12077
12976
  type: "object"
12078
12977
  },
12978
+ first_tier_partner: {
12979
+ description: "The partner who referred the business owner onto Whop (first tier). Null if there is no active first-tier partner.",
12980
+ properties: {
12981
+ id: {
12982
+ description: "User ID, prefixed `user_`.",
12983
+ type: "string"
12984
+ },
12985
+ name: {
12986
+ description: "The user's display name.",
12987
+ type: [
12988
+ "string",
12989
+ "null"
12990
+ ]
12991
+ },
12992
+ profile_picture: {
12993
+ description: "The user's profile picture.",
12994
+ properties: {
12995
+ url: {
12996
+ description: "The user's profile picture URL.",
12997
+ type: "string"
12998
+ }
12999
+ },
13000
+ required: [
13001
+ "url"
13002
+ ],
13003
+ type: "object"
13004
+ },
13005
+ username: {
13006
+ description: "The user's unique username.",
13007
+ type: "string"
13008
+ }
13009
+ },
13010
+ required: [
13011
+ "id",
13012
+ "username",
13013
+ "name",
13014
+ "profile_picture"
13015
+ ],
13016
+ type: [
13017
+ "object",
13018
+ "null"
13019
+ ]
13020
+ },
12079
13021
  id: {
12080
13022
  description: "Business referral ID.",
12081
13023
  type: "string"
12082
13024
  },
12083
- object: {
13025
+ my_partner_tier: {
13026
+ description: "Which tier the caller earns on for this business: `first` (they referred the owner) or `second` (they referred the first-tier partner).",
12084
13027
  enum: [
12085
- "business_referral"
13028
+ "first",
13029
+ "second"
12086
13030
  ],
12087
13031
  type: "string"
12088
13032
  },
12089
- payout_percentage: {
12090
- description: "Referrer's share of Whop gross profit, as a fraction (0.3 = 30%). Second-tier referrals earn a flat 0.1.",
12091
- format: "float",
12092
- type: "number"
12093
- },
12094
- referral_expires_at: {
12095
- description: "When the referral expires.",
12096
- format: "date-time",
12097
- type: [
12098
- "string",
12099
- "null"
12100
- ]
12101
- },
12102
- referral_started_at: {
12103
- description: "When the referral became active.",
12104
- format: "date-time",
12105
- type: [
12106
- "string",
12107
- "null"
12108
- ]
12109
- },
12110
- second_tier: {
12111
- description: "Whether the acting user is the second-tier (grandparent) referrer, not the direct referrer.",
12112
- type: "boolean"
12113
- },
12114
- status: {
12115
- description: "Current referral status.",
13033
+ object: {
12116
13034
  enum: [
12117
- "active",
12118
- "removed"
13035
+ "business_referral"
12119
13036
  ],
12120
13037
  type: "string"
12121
13038
  },
12122
- user: {
12123
- description: "Owner of the referred account.",
13039
+ owner: {
13040
+ description: "The owner of the referred business.",
12124
13041
  properties: {
12125
13042
  id: {
12126
13043
  description: "User ID, prefixed `user_`.",
@@ -12162,6 +13079,35 @@ var native_spec_default = {
12162
13079
  "null"
12163
13080
  ]
12164
13081
  },
13082
+ payout_percentage: {
13083
+ description: "Referrer's share of Whop gross profit, as a fraction (0.3 = 30%). Second-tier referrals earn a flat 0.1.",
13084
+ format: "float",
13085
+ type: "number"
13086
+ },
13087
+ referral_expires_at: {
13088
+ description: "When the referral expires.",
13089
+ format: "date-time",
13090
+ type: [
13091
+ "string",
13092
+ "null"
13093
+ ]
13094
+ },
13095
+ referral_started_at: {
13096
+ description: "When the referral became active.",
13097
+ format: "date-time",
13098
+ type: [
13099
+ "string",
13100
+ "null"
13101
+ ]
13102
+ },
13103
+ status: {
13104
+ description: "Current referral status.",
13105
+ enum: [
13106
+ "active",
13107
+ "removed"
13108
+ ],
13109
+ type: "string"
13110
+ },
12165
13111
  volume_usd: {
12166
13112
  properties: {
12167
13113
  attributed: {
@@ -12189,9 +13135,10 @@ var native_spec_default = {
12189
13135
  "object",
12190
13136
  "id",
12191
13137
  "account",
12192
- "user",
13138
+ "owner",
13139
+ "first_tier_partner",
13140
+ "my_partner_tier",
12193
13141
  "status",
12194
- "second_tier",
12195
13142
  "payout_percentage",
12196
13143
  "referral_started_at",
12197
13144
  "referral_expires_at",
@@ -12766,7 +13713,7 @@ var native_spec_default = {
12766
13713
  },
12767
13714
  "/social_accounts": {
12768
13715
  get: {
12769
- description: "Lists the social accounts linked to an account or user. The owner is passed as exactly one of account_id (a biz_ identifier) or user_id (a user_ identifier); an account-scoped API key defaults to its own account when neither is given.",
13716
+ description: "Lists the social accounts linked to an account or user.",
12770
13717
  operationId: "list",
12771
13718
  parameters: [
12772
13719
  {
@@ -12968,13 +13915,81 @@ var native_spec_default = {
12968
13915
  ]
12969
13916
  },
12970
13917
  post: {
12971
- description: "Starts an OAuth connection flow for a social account and returns an authorize_url to redirect the user to. Today the only supported platform is meta_business, which grants the advertise scope so the connected Facebook page and Instagram account can run ads. The required permission follows the requested capability: the advertise scope requires ad_campaign:create (so advertiser roles can connect), other scopes require social_account:create. The connection is authorized against the account given by account_id (a biz_ identifier); an account-scoped API key may omit it to default to its own account.",
13918
+ description: "Creates or returns a Whop-managed Facebook page for an account.",
12972
13919
  operationId: "create",
12973
13920
  parameters: [
12974
13921
  {
12975
13922
  $ref: "#/components/parameters/ApiVersionDate"
12976
13923
  }
12977
13924
  ],
13925
+ requestBody: {
13926
+ content: {
13927
+ "application/json": {
13928
+ schema: {
13929
+ properties: {
13930
+ account_id: {
13931
+ description: "The Account (biz_ identifier) to create the social account for. An account-scoped API key may omit this to default to its own account.",
13932
+ type: "string"
13933
+ },
13934
+ platform: {
13935
+ description: "The platform to create the social account on.",
13936
+ enum: [
13937
+ "facebook"
13938
+ ],
13939
+ type: "string"
13940
+ }
13941
+ },
13942
+ required: [
13943
+ "platform"
13944
+ ],
13945
+ type: "object"
13946
+ }
13947
+ }
13948
+ },
13949
+ required: true
13950
+ },
13951
+ responses: {
13952
+ "200": {
13953
+ content: {
13954
+ "application/json": {
13955
+ schema: {
13956
+ $ref: "#/components/schemas/SocialAccount"
13957
+ }
13958
+ }
13959
+ },
13960
+ description: "social account created"
13961
+ },
13962
+ "400": {
13963
+ $ref: "#/components/responses/InvalidParameters",
13964
+ description: "unsupported platform"
13965
+ },
13966
+ "401": {
13967
+ $ref: "#/components/responses/Unauthorized",
13968
+ description: "missing or invalid authentication"
13969
+ }
13970
+ },
13971
+ security: [
13972
+ {
13973
+ bearerAuth: [
13974
+ "social_account:create"
13975
+ ]
13976
+ }
13977
+ ],
13978
+ summary: "Create a Social Account",
13979
+ tags: [
13980
+ "Social Accounts"
13981
+ ]
13982
+ }
13983
+ },
13984
+ "/social_accounts/connect": {
13985
+ post: {
13986
+ description: "Starts an OAuth connection flow and returns an authorize_url where the user can connect a social account.",
13987
+ operationId: "connect",
13988
+ parameters: [
13989
+ {
13990
+ $ref: "#/components/parameters/ApiVersionDate"
13991
+ }
13992
+ ],
12978
13993
  requestBody: {
12979
13994
  content: {
12980
13995
  "application/json": {
@@ -12985,7 +14000,7 @@ var native_spec_default = {
12985
14000
  type: "string"
12986
14001
  },
12987
14002
  platform: {
12988
- description: "The platform to connect the social account on.",
14003
+ description: "The platform to connect the social account on. Today, the supported option is `meta_business`.",
12989
14004
  enum: [
12990
14005
  "meta_business"
12991
14006
  ],
@@ -12996,7 +14011,7 @@ var native_spec_default = {
12996
14011
  type: "string"
12997
14012
  },
12998
14013
  scopes: {
12999
- description: "Capabilities to grant for the connected social account, for example `advertise`.",
14014
+ description: "Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business account for ads.",
13000
14015
  items: {
13001
14016
  enum: [
13002
14017
  "advertise"
@@ -13007,7 +14022,6 @@ var native_spec_default = {
13007
14022
  }
13008
14023
  },
13009
14024
  required: [
13010
- "redirect_url",
13011
14025
  "platform"
13012
14026
  ],
13013
14027
  type: "object"
@@ -13060,7 +14074,7 @@ var native_spec_default = {
13060
14074
  },
13061
14075
  "/social_accounts/{id}": {
13062
14076
  delete: {
13063
- description: "Disconnects a social account from an account or user by discarding the link record. The underlying social account record is retained.",
14077
+ description: "Disconnects a social account from an account or user without deleting the underlying platform account.",
13064
14078
  operationId: "delete",
13065
14079
  parameters: [
13066
14080
  {
@@ -13138,7 +14152,7 @@ var native_spec_default = {
13138
14152
  },
13139
14153
  "/social_accounts/{id}/posts": {
13140
14154
  get: {
13141
- description: "Lists the existing posts of a connected social account. Supported for Facebook pages and Instagram accounts. Pass post_id to return only that single post. The owning account is passed as account_id (a biz_ identifier).",
14155
+ description: "Lists the existing posts of a connected Facebook page or Instagram account.",
13142
14156
  operationId: "posts",
13143
14157
  parameters: [
13144
14158
  {
@@ -15403,6 +16417,57 @@ var native_spec_default = {
15403
16417
  schema: {
15404
16418
  type: "string"
15405
16419
  }
16420
+ },
16421
+ {
16422
+ description: "On `GET /users/me`, also compute the caller's balance history (opt-in; runs a heavier query). Ignored for other users and for callers without balance-read scope.",
16423
+ in: "query",
16424
+ name: "include_balance_history",
16425
+ required: false,
16426
+ schema: {
16427
+ type: "boolean"
16428
+ }
16429
+ },
16430
+ {
16431
+ description: "Balance-history window start, ISO 8601 date or datetime. Defaults to 30 days ago. Only used with `include_balance_history`.",
16432
+ in: "query",
16433
+ name: "from",
16434
+ required: false,
16435
+ schema: {
16436
+ type: "string"
16437
+ }
16438
+ },
16439
+ {
16440
+ description: "Balance-history window end, ISO 8601 date or datetime. Defaults to now. Only used with `include_balance_history`.",
16441
+ in: "query",
16442
+ name: "to",
16443
+ required: false,
16444
+ schema: {
16445
+ type: "string"
16446
+ }
16447
+ },
16448
+ {
16449
+ description: "Balance-history point granularity. Defaults to `day`. Only used with `include_balance_history`.",
16450
+ in: "query",
16451
+ name: "interval",
16452
+ required: false,
16453
+ schema: {
16454
+ enum: [
16455
+ "hour",
16456
+ "day",
16457
+ "week",
16458
+ "month"
16459
+ ],
16460
+ type: "string"
16461
+ }
16462
+ },
16463
+ {
16464
+ description: "IANA time zone the balance-history points are bucketed in. Defaults to `UTC`. Only used with `include_balance_history`.",
16465
+ in: "query",
16466
+ name: "time_zone",
16467
+ required: false,
16468
+ schema: {
16469
+ type: "string"
16470
+ }
15406
16471
  }
15407
16472
  ],
15408
16473
  responses: {
@@ -15651,7 +16716,7 @@ var native_spec_default = {
15651
16716
  ]
15652
16717
  },
15653
16718
  business_structure: {
15654
- description: "Business entity type, such as `llc` or `corporation`.",
16719
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
15655
16720
  type: [
15656
16721
  "string",
15657
16722
  "null"
@@ -15876,7 +16941,7 @@ var native_spec_default = {
15876
16941
  type: "string"
15877
16942
  },
15878
16943
  business_structure: {
15879
- description: "Business entity type, such as `llc` or `corporation`.",
16944
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
15880
16945
  type: "string"
15881
16946
  },
15882
16947
  business_website: {
@@ -15950,7 +17015,7 @@ var native_spec_default = {
15950
17015
  ]
15951
17016
  },
15952
17017
  business_structure: {
15953
- description: "Business entity type, such as `llc` or `corporation`.",
17018
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
15954
17019
  type: [
15955
17020
  "string",
15956
17021
  "null"
@@ -16133,7 +17198,7 @@ var native_spec_default = {
16133
17198
  ]
16134
17199
  },
16135
17200
  business_structure: {
16136
- description: "Business entity type, such as `llc` or `corporation`.",
17201
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
16137
17202
  type: [
16138
17203
  "string",
16139
17204
  "null"
@@ -16365,7 +17430,7 @@ var native_spec_default = {
16365
17430
  ]
16366
17431
  },
16367
17432
  business_structure: {
16368
- description: "Business entity type, such as `llc` or `corporation`.",
17433
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
16369
17434
  type: [
16370
17435
  "string",
16371
17436
  "null"
@@ -16610,7 +17675,7 @@ var native_spec_default = {
16610
17675
  type: "string"
16611
17676
  },
16612
17677
  business_structure: {
16613
- description: "Updated business entity type, such as `llc` or `corporation`.",
17678
+ description: "Updated legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
16614
17679
  type: "string"
16615
17680
  },
16616
17681
  country: {
@@ -16720,7 +17785,7 @@ var native_spec_default = {
16720
17785
  ]
16721
17786
  },
16722
17787
  business_structure: {
16723
- description: "Business entity type, such as `llc` or `corporation`.",
17788
+ description: "Legal entity structure of the business, such as `private_corporation` or `sole_proprietorship`. Supported values vary by country of incorporation \u2014 see [Business structures](/developer/verification/business-structures).",
16724
17789
  type: [
16725
17790
  "string",
16726
17791
  "null"
@@ -17477,12 +18542,23 @@ var native_spec_default = {
17477
18542
  action: {
17478
18543
  description: "The recommendation; new values may be added, so handle unknown actions gracefully",
17479
18544
  enum: [
17480
- "apply_for_financing",
18545
+ "theme_business",
18546
+ "create_product",
18547
+ "create_plan",
18548
+ "verify_identity",
18549
+ "connect_affiliate_program",
18550
+ "create_promotion",
18551
+ "setup_tracking_pixel",
17481
18552
  "migrate_from_stripe",
17482
18553
  "accept_first_payment",
17483
- "join_whop_university"
18554
+ "launch_first_ad",
18555
+ "invite_team_member",
18556
+ "enable_tax_collection",
18557
+ "create_card",
18558
+ "join_whop_university",
18559
+ "apply_for_financing"
17484
18560
  ],
17485
- example: "apply_for_financing",
18561
+ example: "theme_business",
17486
18562
  type: "string"
17487
18563
  },
17488
18564
  blocked_capabilities: {
@@ -17511,6 +18587,20 @@ var native_spec_default = {
17511
18587
  "null"
17512
18588
  ]
17513
18589
  },
18590
+ impact_score: {
18591
+ description: "Estimated revenue impact from 0-100, comparable across accounts, or `null` when not ranked",
18592
+ type: [
18593
+ "integer",
18594
+ "null"
18595
+ ]
18596
+ },
18597
+ reasoning: {
18598
+ description: "Why this action was recommended for this account, or `null`",
18599
+ type: [
18600
+ "string",
18601
+ "null"
18602
+ ]
18603
+ },
17514
18604
  status: {
17515
18605
  description: "Always optional \u2014 never blocking",
17516
18606
  enum: [
@@ -17532,7 +18622,9 @@ var native_spec_default = {
17532
18622
  "cta_label",
17533
18623
  "cta",
17534
18624
  "icon_url",
17535
- "blocked_capabilities"
18625
+ "blocked_capabilities",
18626
+ "reasoning",
18627
+ "impact_score"
17536
18628
  ],
17537
18629
  type: "object"
17538
18630
  },
@@ -17824,7 +18916,7 @@ var native_spec_default = {
17824
18916
  creatives: {
17825
18917
  items: {
17826
18918
  $ref: "#/components/schemas/AdCreative",
17827
- description: "The creatives used by this ad. The original/uncropped asset has a null format; square, vertical, and horizontal entries are its per-placement crops."
18919
+ description: "The creative assets used by this ad. The original asset has a null format; square, vertical, and horizontal entries are placement-specific variants."
17828
18920
  },
17829
18921
  type: "array"
17830
18922
  },
@@ -17837,6 +18929,7 @@ var native_spec_default = {
17837
18929
  enum: [
17838
18930
  "rejected",
17839
18931
  "in_review",
18932
+ "draft",
17840
18933
  "campaign_paused",
17841
18934
  "ad_group_paused",
17842
18935
  "paused",
@@ -17892,6 +18985,13 @@ var native_spec_default = {
17892
18985
  "null"
17893
18986
  ]
17894
18987
  },
18988
+ lead_form_id: {
18989
+ description: "The Meta lead form the ad uses. Set when the ad references an existing form via lead_form_id, or once a form built from lead_form has been created on Meta at launch.",
18990
+ type: [
18991
+ "string",
18992
+ "null"
18993
+ ]
18994
+ },
17895
18995
  leads: {
17896
18996
  description: "Whop pixel-attributed leads, last-click.",
17897
18997
  type: "number"
@@ -18104,6 +19204,7 @@ var native_spec_default = {
18104
19204
  "ad_campaign",
18105
19205
  "creatives",
18106
19206
  "lead_form",
19207
+ "lead_form_id",
18107
19208
  "social_accounts",
18108
19209
  "created_at",
18109
19210
  "updated_at",
@@ -18507,8 +19608,19 @@ var native_spec_default = {
18507
19608
  },
18508
19609
  AdCreative: {
18509
19610
  properties: {
19611
+ crop: {
19612
+ description: "The saved crop window for this creative, in source image pixels. Null for the original asset or a format that has not been cropped.",
19613
+ oneOf: [
19614
+ {
19615
+ $ref: "#/components/schemas/AdCreativeCrop"
19616
+ },
19617
+ {
19618
+ type: "null"
19619
+ }
19620
+ ]
19621
+ },
18510
19622
  format: {
18511
- description: "The placement crop this asset covers, or null for the original/uncropped asset.",
19623
+ description: "The placement variant this asset covers, or null for the original asset.",
18512
19624
  enum: [
18513
19625
  "square",
18514
19626
  "vertical",
@@ -18544,7 +19656,35 @@ var native_spec_default = {
18544
19656
  "id",
18545
19657
  "format",
18546
19658
  "url",
18547
- "media_type"
19659
+ "media_type",
19660
+ "crop"
19661
+ ],
19662
+ type: "object"
19663
+ },
19664
+ AdCreativeCrop: {
19665
+ properties: {
19666
+ height: {
19667
+ description: "Height of the crop window in source pixels.",
19668
+ type: "number"
19669
+ },
19670
+ width: {
19671
+ description: "Width of the crop window in source pixels.",
19672
+ type: "number"
19673
+ },
19674
+ x: {
19675
+ description: "Left edge of the crop window in source pixels.",
19676
+ type: "number"
19677
+ },
19678
+ y: {
19679
+ description: "Top edge of the crop window in source pixels.",
19680
+ type: "number"
19681
+ }
19682
+ },
19683
+ required: [
19684
+ "x",
19685
+ "y",
19686
+ "width",
19687
+ "height"
18548
19688
  ],
18549
19689
  type: "object"
18550
19690
  },
@@ -18729,6 +19869,7 @@ var native_spec_default = {
18729
19869
  enum: [
18730
19870
  "all_ads_rejected",
18731
19871
  "rejected",
19872
+ "draft",
18732
19873
  "no_ads",
18733
19874
  "campaign_paused",
18734
19875
  "paused",
@@ -19185,6 +20326,97 @@ var native_spec_default = {
19185
20326
  },
19186
20327
  LedgerActivity: {
19187
20328
  properties: {
20329
+ account: {
20330
+ description: "The viewer account that owns this row's ledger. Present only when the response aggregates owned accounts (include_owned_accounts=true); omitted otherwise.",
20331
+ oneOf: [
20332
+ {
20333
+ properties: {
20334
+ id: {
20335
+ description: "Account ID.",
20336
+ type: "string"
20337
+ },
20338
+ logo_url: {
20339
+ description: "Account logo URL.",
20340
+ type: [
20341
+ "string",
20342
+ "null"
20343
+ ]
20344
+ },
20345
+ object: {
20346
+ enum: [
20347
+ "account"
20348
+ ],
20349
+ type: "string"
20350
+ },
20351
+ route: {
20352
+ description: "Account route.",
20353
+ type: [
20354
+ "string",
20355
+ "null"
20356
+ ]
20357
+ },
20358
+ title: {
20359
+ description: "Account display name.",
20360
+ type: [
20361
+ "string",
20362
+ "null"
20363
+ ]
20364
+ }
20365
+ },
20366
+ required: [
20367
+ "object",
20368
+ "id",
20369
+ "title",
20370
+ "route",
20371
+ "logo_url"
20372
+ ],
20373
+ type: "object"
20374
+ },
20375
+ {
20376
+ properties: {
20377
+ id: {
20378
+ description: "User ID.",
20379
+ type: "string"
20380
+ },
20381
+ name: {
20382
+ description: "User display name.",
20383
+ type: [
20384
+ "string",
20385
+ "null"
20386
+ ]
20387
+ },
20388
+ object: {
20389
+ enum: [
20390
+ "user"
20391
+ ],
20392
+ type: "string"
20393
+ },
20394
+ profile_picture_url: {
20395
+ description: "User profile image URL.",
20396
+ type: [
20397
+ "string",
20398
+ "null"
20399
+ ]
20400
+ },
20401
+ username: {
20402
+ description: "User's username.",
20403
+ type: [
20404
+ "string",
20405
+ "null"
20406
+ ]
20407
+ }
20408
+ },
20409
+ required: [
20410
+ "object",
20411
+ "id",
20412
+ "name",
20413
+ "username",
20414
+ "profile_picture_url"
20415
+ ],
20416
+ type: "object"
20417
+ }
20418
+ ]
20419
+ },
19188
20420
  amount: {
19189
20421
  description: "Signed amount in the currency's smallest precision units.",
19190
20422
  type: "string"
@@ -19227,6 +20459,13 @@ var native_spec_default = {
19227
20459
  description: "Ledger activity ID.",
19228
20460
  type: "string"
19229
20461
  },
20462
+ ledger_account_id: {
20463
+ description: "The ledger account (a ldgr_ identifier) this row belongs to. Present only when the response aggregates owned accounts (include_owned_accounts=true); omitted otherwise. Pair it with `account` to scope drawers and dashboard links to the owning business.",
20464
+ type: [
20465
+ "string",
20466
+ "null"
20467
+ ]
20468
+ },
19230
20469
  line_type: {
19231
20470
  description: "Type of ledger activity.",
19232
20471
  type: "string"
@@ -21182,6 +22421,17 @@ var native_spec_default = {
21182
22421
  }
21183
22422
  ]
21184
22423
  },
22424
+ balance_history: {
22425
+ description: "The user's cumulative wallet balance over time (USD `{ t, v }` points plus last/min/max), for the balance chart. Opt-in and heavier: computed only on `GET /users/me` self-view when `include_balance_history=true` and the caller has balance-read scope; `null` otherwise. A migrated account that never transacted returns an empty series.",
22426
+ oneOf: [
22427
+ {
22428
+ $ref: "#/components/schemas/UserBalanceHistory"
22429
+ },
22430
+ {
22431
+ type: "null"
22432
+ }
22433
+ ]
22434
+ },
21185
22435
  bio: {
21186
22436
  description: "The user's biography",
21187
22437
  type: [
@@ -21228,6 +22478,7 @@ var native_spec_default = {
21228
22478
  "created_at",
21229
22479
  "profile_picture",
21230
22480
  "balance",
22481
+ "balance_history",
21231
22482
  "verification"
21232
22483
  ],
21233
22484
  type: "object"
@@ -21363,6 +22614,53 @@ var native_spec_default = {
21363
22614
  ],
21364
22615
  type: "object"
21365
22616
  },
22617
+ UserBalanceHistory: {
22618
+ properties: {
22619
+ data: {
22620
+ items: {
22621
+ $ref: "#/components/schemas/UserBalanceHistoryPoint",
22622
+ description: "Cumulative balance points over the requested window, oldest first."
22623
+ },
22624
+ type: "array"
22625
+ },
22626
+ last: {
22627
+ description: "Value of the most recent point, in USD.",
22628
+ type: "number"
22629
+ },
22630
+ max: {
22631
+ description: "Maximum value across the window, in USD.",
22632
+ type: "number"
22633
+ },
22634
+ min: {
22635
+ description: "Minimum value across the window, in USD.",
22636
+ type: "number"
22637
+ }
22638
+ },
22639
+ required: [
22640
+ "data",
22641
+ "last",
22642
+ "min",
22643
+ "max"
22644
+ ],
22645
+ type: "object"
22646
+ },
22647
+ UserBalanceHistoryPoint: {
22648
+ properties: {
22649
+ t: {
22650
+ description: "Point timestamp, in Unix seconds.",
22651
+ type: "integer"
22652
+ },
22653
+ v: {
22654
+ description: "Cumulative wallet balance at this point, in USD.",
22655
+ type: "number"
22656
+ }
22657
+ },
22658
+ required: [
22659
+ "t",
22660
+ "v"
22661
+ ],
22662
+ type: "object"
22663
+ },
21366
22664
  UserBalanceToken: {
21367
22665
  properties: {
21368
22666
  balance: {
@@ -25994,6 +27292,76 @@ var apps_spec_default = {
25994
27292
  }
25995
27293
  };
25996
27294
 
27295
+ // src/api/browser-links.ts
27296
+ import { confirm, isCancel } from "@clack/prompts";
27297
+
27298
+ // src/lib/open-browser.ts
27299
+ import { execFile } from "child_process";
27300
+ function openBrowser(url) {
27301
+ const ignore = () => {
27302
+ };
27303
+ if (process.platform === "darwin") {
27304
+ execFile("open", [url], ignore);
27305
+ } else if (process.platform === "win32") {
27306
+ execFile("cmd.exe", ["/c", "start", "", url], ignore);
27307
+ } else {
27308
+ execFile("xdg-open", [url], ignore);
27309
+ }
27310
+ }
27311
+
27312
+ // src/api/browser-links.ts
27313
+ var ACTION_URL_FIELDS = [
27314
+ "authorize_url",
27315
+ "session_url",
27316
+ "deposit_url"
27317
+ ];
27318
+ function findActionUrl(payload) {
27319
+ if (payload == null || typeof payload !== "object" || Array.isArray(payload)) {
27320
+ return null;
27321
+ }
27322
+ const rec = payload;
27323
+ for (const field of ACTION_URL_FIELDS) {
27324
+ const value = rec[field];
27325
+ if (typeof value === "string" && /^https?:\/\//i.test(value)) return value;
27326
+ }
27327
+ return null;
27328
+ }
27329
+ function actionUrlNotice(url, outcome) {
27330
+ switch (outcome) {
27331
+ case "opened":
27332
+ return `Opened your browser to complete this step:
27333
+ ${url}
27334
+ If it didn't open, visit the link above.`;
27335
+ case "manual":
27336
+ return `Complete this step in your browser:
27337
+ ${url}`;
27338
+ case "agent":
27339
+ return `Action required: open this link in the user's browser to complete this step:
27340
+ ${url}`;
27341
+ }
27342
+ }
27343
+ async function confirmOpenInBrowser(url) {
27344
+ const answer = await confirm({
27345
+ message: `This step needs to be completed in your browser. Open ${url} now?`
27346
+ });
27347
+ return !isCancel(answer) && answer === true;
27348
+ }
27349
+ async function announceActionUrl(url, {
27350
+ isTTY = process.stdout.isTTY === true && process.stdin.isTTY === true,
27351
+ confirmOpen = confirmOpenInBrowser,
27352
+ open = openBrowser,
27353
+ print = (text) => process.stderr.write(`${text}
27354
+ `)
27355
+ } = {}) {
27356
+ if (!isTTY) {
27357
+ print(actionUrlNotice(url, "agent"));
27358
+ return;
27359
+ }
27360
+ const shouldOpen = await confirmOpen(url);
27361
+ if (shouldOpen) open(url);
27362
+ print(actionUrlNotice(url, shouldOpen ? "opened" : "manual"));
27363
+ }
27364
+
25997
27365
  // src/auth/client.ts
25998
27366
  import { AuthenticationError, PermissionDeniedError, Whop } from "@whop/sdk";
25999
27367
  var DEFAULT_BASE_URL = "https://api.whop.com/api/v1";
@@ -26027,7 +27395,7 @@ import fs4 from "fs";
26027
27395
  import os4 from "os";
26028
27396
  import path4 from "path";
26029
27397
 
26030
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Cli.js
27398
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Cli.js
26031
27399
  var Cli_exports = {};
26032
27400
  __export(Cli_exports, {
26033
27401
  collectSkillCommands: () => collectSkillCommands,
@@ -26128,7 +27496,7 @@ function extractSegmentPart(segment, segmentTokenStart, segmentTokenCount, targe
26128
27496
  return segment.slice(charStart, charEnd);
26129
27497
  }
26130
27498
 
26131
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/helpers.js
27499
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/helpers.js
26132
27500
  function isRecord(value) {
26133
27501
  return typeof value === "object" && value !== null && !Array.isArray(value);
26134
27502
  }
@@ -26176,7 +27544,7 @@ function suggest(input, candidates) {
26176
27544
  return best;
26177
27545
  }
26178
27546
 
26179
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Completions.js
27547
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Completions.js
26180
27548
  function register(shell, name) {
26181
27549
  switch (shell) {
26182
27550
  case "bash":
@@ -26439,7 +27807,7 @@ let _incur_complete_${id} = {|spans|
26439
27807
  }`;
26440
27808
  }
26441
27809
 
26442
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Errors.js
27810
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Errors.js
26443
27811
  var BaseError = class extends Error {
26444
27812
  name = "Incur.BaseError";
26445
27813
  /** The short, human-readable error message (without details). */
@@ -26513,7 +27881,7 @@ function walk(error, fn) {
26513
27881
  return current;
26514
27882
  }
26515
27883
 
26516
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Fetch.js
27884
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Fetch.js
26517
27885
  var reservedFlags = /* @__PURE__ */ new Set(["method", "body", "data", "header"]);
26518
27886
  var reservedShort = { X: "method", d: "data", H: "header" };
26519
27887
  function parseArgv(argv) {
@@ -26649,7 +28017,7 @@ async function parseResponse(response) {
26649
28017
  };
26650
28018
  }
26651
28019
 
26652
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Filter.js
28020
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Filter.js
26653
28021
  function parse(expression) {
26654
28022
  const paths = [];
26655
28023
  const tokens = [];
@@ -27149,7 +28517,7 @@ function resolveOptions(options) {
27149
28517
  };
27150
28518
  }
27151
28519
 
27152
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/json.js
28520
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/json.js
27153
28521
  function stringify(value, space) {
27154
28522
  return JSON.stringify(value, (_key, value2) => {
27155
28523
  if (typeof value2 === "bigint")
@@ -27161,7 +28529,7 @@ function normalize(value) {
27161
28529
  return JSON.parse(stringify(value));
27162
28530
  }
27163
28531
 
27164
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/yaml.js
28532
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/yaml.js
27165
28533
  import { createRequire } from "module";
27166
28534
  var cached;
27167
28535
  async function load() {
@@ -27173,7 +28541,7 @@ function loadSync() {
27173
28541
  return cached;
27174
28542
  }
27175
28543
 
27176
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Formatter.js
28544
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Formatter.js
27177
28545
  function format2(value, fmt = "toon") {
27178
28546
  if (value == null)
27179
28547
  return "";
@@ -27281,7 +28649,7 @@ ${String(val)}`;
27281
28649
  return kvTable(obj);
27282
28650
  }
27283
28651
 
27284
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Parser.js
28652
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Parser.js
27285
28653
  function parse2(argv, options = {}) {
27286
28654
  const { args: argsSchema, options: optionsSchema, alias, defaults } = options;
27287
28655
  const optionNames = createOptionNames(optionsSchema, alias);
@@ -27525,8 +28893,65 @@ function coerce(value, name, schema) {
27525
28893
  if (typeName === "ZodBoolean" && typeof value === "string") {
27526
28894
  return value === "true";
27527
28895
  }
28896
+ if (isStructuredType(typeName) && typeof value === "string") {
28897
+ return coerceJsonObject(value, name) ?? value;
28898
+ }
28899
+ if (typeName === "ZodUnion" && typeof value === "string") {
28900
+ return coerceUnion(value, inner);
28901
+ }
28902
+ if (typeName === "ZodArray" && Array.isArray(value)) {
28903
+ return coerceArray(value, name, inner);
28904
+ }
27528
28905
  return value;
27529
28906
  }
28907
+ function isStructuredType(typeName) {
28908
+ return typeName === "ZodObject" || typeName === "ZodRecord";
28909
+ }
28910
+ function coerceArray(values, name, arraySchema) {
28911
+ const element = arraySchema.def?.element;
28912
+ const structured = element ? isStructuredType(unwrap2(element).constructor.name) : false;
28913
+ if (values.length === 1 && typeof values[0] === "string" && values[0].trim().startsWith("[")) {
28914
+ try {
28915
+ const parsed = JSON.parse(values[0]);
28916
+ if (Array.isArray(parsed))
28917
+ return parsed;
28918
+ } catch (error) {
28919
+ if (structured)
28920
+ throw invalidJsonError(name, error);
28921
+ }
28922
+ }
28923
+ if (!structured)
28924
+ return values;
28925
+ return values.map((item) => typeof item === "string" ? coerceJsonObject(item, name) ?? item : item);
28926
+ }
28927
+ function coerceUnion(value, union) {
28928
+ const members = union.def?.options;
28929
+ if (!members?.some((member) => isStructuredType(unwrap2(member).constructor.name)))
28930
+ return value;
28931
+ const trimmed = value.trim();
28932
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("["))
28933
+ return value;
28934
+ try {
28935
+ return JSON.parse(value);
28936
+ } catch {
28937
+ return value;
28938
+ }
28939
+ }
28940
+ function coerceJsonObject(value, name) {
28941
+ if (!value.trim().startsWith("{"))
28942
+ return void 0;
28943
+ try {
28944
+ return JSON.parse(value);
28945
+ } catch (error) {
28946
+ throw invalidJsonError(name, error);
28947
+ }
28948
+ }
28949
+ function invalidJsonError(name, error) {
28950
+ const detail = error instanceof Error ? error.message : String(error);
28951
+ return new ParseError({
28952
+ message: `Invalid JSON for --${name}: ${detail}`
28953
+ });
28954
+ }
27530
28955
  function parseGlobals(argv, schema, alias, options = {}) {
27531
28956
  const optionNames = createOptionNames(schema, alias);
27532
28957
  const rest = [];
@@ -27641,7 +29066,7 @@ function defaultEnvSource() {
27641
29066
  return {};
27642
29067
  }
27643
29068
 
27644
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/command.js
29069
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/command.js
27645
29070
  var sentinel = Symbol.for("incur.sentinel");
27646
29071
  async function execute(command, options) {
27647
29072
  const { argv, inputOptions, agent, format: format3, formatExplicit, name, path: path6, version, envSource = process.env, env: envSchema, globals = {}, vars: varsSchema, middlewares = [] } = options;
@@ -27888,7 +29313,7 @@ function findBuiltinSubcommand(builtin, token) {
27888
29313
  return builtin.subcommands?.find((sub) => sub.name === token || sub.aliases?.includes(token));
27889
29314
  }
27890
29315
 
27891
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Help.js
29316
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Help.js
27892
29317
  function formatRoot(name, options = {}) {
27893
29318
  const { aliases, configFlag, description, globals, version, commands = [], root = false } = options;
27894
29319
  const lines = [];
@@ -28174,7 +29599,7 @@ function redact(value) {
28174
29599
  return `****${value.slice(-4)}`;
28175
29600
  }
28176
29601
 
28177
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/cta.js
29602
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/cta.js
28178
29603
  function formatCtaBlock(name, block) {
28179
29604
  if (!block || block.commands.length === 0)
28180
29605
  return void 0;
@@ -28197,7 +29622,7 @@ function formatCta(name, cta) {
28197
29622
  return { command: cmd, ...cta.description ? { description: cta.description } : void 0 };
28198
29623
  }
28199
29624
 
28200
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/pm.js
29625
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/pm.js
28201
29626
  function detectRunner() {
28202
29627
  const userAgent = process.env.npm_config_user_agent ?? "";
28203
29628
  const execPath = process.env.npm_execpath ?? "";
@@ -28208,7 +29633,7 @@ function detectRunner() {
28208
29633
  return "npx";
28209
29634
  }
28210
29635
 
28211
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Schema.js
29636
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Schema.js
28212
29637
  function toJsonSchema(schema) {
28213
29638
  const result = external_exports.toJSONSchema(schema, {
28214
29639
  unrepresentable: "any",
@@ -28222,7 +29647,7 @@ function toJsonSchema(schema) {
28222
29647
  return result;
28223
29648
  }
28224
29649
 
28225
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Mcp.js
29650
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Mcp.js
28226
29651
  async function serve(name, version, commands, options = {}) {
28227
29652
  const stdio = importStdioModule();
28228
29653
  const mcp = await import("./dist-2MZJLO2W.js");
@@ -28391,7 +29816,7 @@ function buildToolSchema(args, options) {
28391
29816
  return { type: "object", properties };
28392
29817
  }
28393
29818
 
28394
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Openapi.js
29819
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Openapi.js
28395
29820
  var Openapi_exports = {};
28396
29821
  __export(Openapi_exports, {
28397
29822
  fromCli: () => fromCli,
@@ -28399,7 +29824,7 @@ __export(Openapi_exports, {
28399
29824
  resolve: () => resolve
28400
29825
  });
28401
29826
 
28402
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/dereference.js
29827
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/dereference.js
28403
29828
  function dereference(root) {
28404
29829
  const cache = /* @__PURE__ */ new Map();
28405
29830
  return walk2(root, root, cache);
@@ -28451,7 +29876,7 @@ function resolvePointer(root, pointer) {
28451
29876
  return current;
28452
29877
  }
28453
29878
 
28454
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Openapi.js
29879
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Openapi.js
28455
29880
  function fromCli(cli, options = {}) {
28456
29881
  const commands = toCommands.get(cli);
28457
29882
  if (!commands)
@@ -28970,7 +30395,7 @@ function coerceIfNeeded(schema) {
28970
30395
  return desc ? coerced.describe(desc) : coerced;
28971
30396
  }
28972
30397
 
28973
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Skill.js
30398
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Skill.js
28974
30399
  import { createHash } from "crypto";
28975
30400
  function index(name, commands, description) {
28976
30401
  const lines = [`# ${name}`];
@@ -29214,8 +30639,8 @@ function resolveTypeName2(prop) {
29214
30639
  return "unknown";
29215
30640
  }
29216
30641
 
29217
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/SyncMcp.js
29218
- import { execFile } from "child_process";
30642
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/SyncMcp.js
30643
+ import { execFile as execFile2 } from "child_process";
29219
30644
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
29220
30645
  import { homedir } from "os";
29221
30646
  import { dirname, join } from "path";
@@ -29343,7 +30768,7 @@ function splitCommand(input) {
29343
30768
  }
29344
30769
  function exec(cmd, args) {
29345
30770
  return new Promise((resolve3, reject) => {
29346
- execFile(cmd, args, (error, stdout, stderr) => {
30771
+ execFile2(cmd, args, (error, stdout, stderr) => {
29347
30772
  if (error) {
29348
30773
  const msg = stderr?.trim() || stdout?.trim() || error.message;
29349
30774
  reject(new Error(msg));
@@ -29353,13 +30778,13 @@ function exec(cmd, args) {
29353
30778
  });
29354
30779
  }
29355
30780
 
29356
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/SyncSkills.js
30781
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/SyncSkills.js
29357
30782
  import fsSync from "fs";
29358
30783
  import fs2 from "fs/promises";
29359
30784
  import os2 from "os";
29360
30785
  import path2 from "path";
29361
30786
 
29362
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/internal/agents.js
30787
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/internal/agents.js
29363
30788
  import * as fs from "fs";
29364
30789
  import * as os from "os";
29365
30790
  import * as path from "path";
@@ -29639,7 +31064,7 @@ function resolveParent(dir) {
29639
31064
  }
29640
31065
  }
29641
31066
 
29642
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/SyncSkills.js
31067
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/SyncSkills.js
29643
31068
  async function sync(name, commands, options = {}) {
29644
31069
  const { depth = 1, description, global = true } = options;
29645
31070
  const cwd = options.cwd ?? (global ? resolvePackageRoot() : process.cwd());
@@ -29800,7 +31225,7 @@ function readHash(name) {
29800
31225
  return readMeta(name)?.hash;
29801
31226
  }
29802
31227
 
29803
- // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+4b9ca91dc02472db944fb103984ffc4a13251b6f/node_modules/incur/dist/Cli.js
31228
+ // ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+fbe3f4dbf48f1bc780cb1bca476f7dade1fe12d3/node_modules/incur/dist/Cli.js
29804
31229
  var destructiveCommandHint = "Confirm with the user before executing this destructive command.";
29805
31230
  function create(nameOrDefinition, definition) {
29806
31231
  const name = typeof nameOrDefinition === "string" ? nameOrDefinition : nameOrDefinition.name;
@@ -32285,7 +33710,7 @@ import { createRequire as createRequire2 } from "module";
32285
33710
  // src/lib/build-info.ts
32286
33711
  var buildChannel = true ? "npm" : "dev";
32287
33712
  var buildTarget = typeof WHOP_CLI_TARGET === "string" ? WHOP_CLI_TARGET : null;
32288
- var buildVersion = true ? "0.6.0" : null;
33713
+ var buildVersion = true ? "0.7.0" : null;
32289
33714
  function isHomebrewPath(execPath, env = process.env) {
32290
33715
  if (/[/\\](Cellar|homebrew|linuxbrew)[/\\]/.test(execPath)) return true;
32291
33716
  const prefix = env.HOMEBREW_PREFIX?.trim();
@@ -32435,7 +33860,6 @@ function deleteSecret(name, env = process.env) {
32435
33860
 
32436
33861
  // src/auth/oauth.ts
32437
33862
  import { createHash as createHash2, randomBytes } from "crypto";
32438
- import { execFile as execFile2 } from "child_process";
32439
33863
  import { Whop as Whop2 } from "@whop/sdk";
32440
33864
 
32441
33865
  // src/auth/callback-server.ts
@@ -32580,7 +34004,7 @@ function startCallbackServer(expectedState) {
32580
34004
  }
32581
34005
 
32582
34006
  // src/auth/prompts.ts
32583
- import { isCancel, log, password, select, spinner } from "@clack/prompts";
34007
+ import { isCancel as isCancel2, log, password, select, spinner } from "@clack/prompts";
32584
34008
  var PromptCancelledError = class extends Error {
32585
34009
  constructor() {
32586
34010
  super("Prompt cancelled");
@@ -32588,7 +34012,7 @@ var PromptCancelledError = class extends Error {
32588
34012
  }
32589
34013
  };
32590
34014
  function ensure(value) {
32591
- if (isCancel(value)) throw new PromptCancelledError();
34015
+ if (isCancel2(value)) throw new PromptCancelledError();
32592
34016
  return value;
32593
34017
  }
32594
34018
  async function chooseAuthMethod() {
@@ -32617,14 +34041,15 @@ async function promptApiKey() {
32617
34041
  });
32618
34042
  return ensure(key).trim();
32619
34043
  }
32620
- async function selectAccount(accounts) {
34044
+ async function selectAccount(accounts, currentId) {
32621
34045
  const id = await select({
32622
34046
  message: "Which business account do you want to use?",
32623
34047
  options: accounts.map((account) => ({
32624
34048
  value: account.id,
32625
34049
  label: account.title,
32626
- hint: account.id
32627
- }))
34050
+ hint: account.id === currentId ? `${account.id} (current)` : account.id
34051
+ })),
34052
+ initialValue: currentId
32628
34053
  });
32629
34054
  const chosen = ensure(id);
32630
34055
  const match = accounts.find((account) => account.id === chosen);
@@ -32662,6 +34087,9 @@ var WHOP_SCOPES = [
32662
34087
  "access_pass:delete",
32663
34088
  "access_pass:stats:read",
32664
34089
  "access_pass:update",
34090
+ "ad_campaign:basic:read",
34091
+ "ad_campaign:create",
34092
+ "ad_campaign:update",
32665
34093
  "affiliate:basic:read",
32666
34094
  "affiliate:create",
32667
34095
  "affiliate:update",
@@ -32670,6 +34098,8 @@ var WHOP_SCOPES = [
32670
34098
  "ai_chat:read",
32671
34099
  "ai_chat:update",
32672
34100
  "ai_prompt:create",
34101
+ "audience:basic:read",
34102
+ "audience:update",
32673
34103
  "bounty:create",
32674
34104
  "chat:message:create",
32675
34105
  "chat:moderate",
@@ -32696,6 +34126,7 @@ var WHOP_SCOPES = [
32696
34126
  "custom_emoji:update",
32697
34127
  "developer:basic:read",
32698
34128
  "developer:create_app",
34129
+ "developer:logs:read",
32699
34130
  "developer:manage_builds",
32700
34131
  "developer:update_app",
32701
34132
  "dms:channel:manage",
@@ -32725,6 +34156,8 @@ var WHOP_SCOPES = [
32725
34156
  "livestream:delete",
32726
34157
  "livestream:manage_recording",
32727
34158
  "livestream:moderate",
34159
+ "media:generate",
34160
+ "media:read",
32728
34161
  "member:basic:read",
32729
34162
  "member:email:read",
32730
34163
  "member:journey:read",
@@ -32775,6 +34208,9 @@ var WHOP_SCOPES = [
32775
34208
  "promo_code:update",
32776
34209
  "shipment:basic:read",
32777
34210
  "shipment:create",
34211
+ "social_account:create",
34212
+ "social_account:delete",
34213
+ "social_account:read",
32778
34214
  "social_link:update",
32779
34215
  "stats:read",
32780
34216
  "support_chat:create",
@@ -32806,17 +34242,6 @@ function generateState() {
32806
34242
  function generateNonce() {
32807
34243
  return randomBytes(16).toString("base64url");
32808
34244
  }
32809
- function openBrowser(url) {
32810
- const ignore = () => {
32811
- };
32812
- if (process.platform === "darwin") {
32813
- execFile2("open", [url], ignore);
32814
- } else if (process.platform === "win32") {
32815
- execFile2("cmd.exe", ["/c", "start", "", url], ignore);
32816
- } else {
32817
- execFile2("xdg-open", [url], ignore);
32818
- }
32819
- }
32820
34245
  async function requestToken(params) {
32821
34246
  const res = await fetch(`${oauthBaseUrl()}/oauth/token`, {
32822
34247
  method: "POST",
@@ -32871,21 +34296,28 @@ var OAuthError = class extends Error {
32871
34296
  this.name = "OAuthError";
32872
34297
  }
32873
34298
  };
32874
- async function resolveOAuthAccount(accessToken, opts) {
34299
+ async function listOAuthAccounts(accessToken, opts = {}) {
32875
34300
  const whop = new Whop2({ apiKey: accessToken, baseURL: apiBaseUrl() });
32876
- const s = opts.agent ? null : startSpinner("Loading your business accounts\u2026");
32877
34301
  const MAX_ACCOUNTS = 1e3;
32878
34302
  const accounts = [];
34303
+ for await (const account of whop.companies.list({ first: 100 })) {
34304
+ accounts.push({
34305
+ id: account.id,
34306
+ title: account.title,
34307
+ route: account.route
34308
+ });
34309
+ if (opts.stopAtId && account.id === opts.stopAtId) break;
34310
+ if (accounts.length >= MAX_ACCOUNTS) break;
34311
+ }
34312
+ return accounts;
34313
+ }
34314
+ async function resolveOAuthAccount(accessToken, opts) {
34315
+ const s = opts.agent ? null : startSpinner("Loading your business accounts\u2026");
34316
+ let accounts;
32879
34317
  try {
32880
- for await (const account of whop.companies.list({ first: 100 })) {
32881
- accounts.push({
32882
- id: account.id,
32883
- title: account.title,
32884
- route: account.route
32885
- });
32886
- if (opts.accountId && account.id === opts.accountId) break;
32887
- if (accounts.length >= MAX_ACCOUNTS) break;
32888
- }
34318
+ accounts = await listOAuthAccounts(accessToken, {
34319
+ stopAtId: opts.accountId
34320
+ });
32889
34321
  } catch {
32890
34322
  s?.stop("Couldn't load your business accounts.");
32891
34323
  if (opts.accountId) {
@@ -33089,16 +34521,18 @@ function upsertProfile(input, env = process.env) {
33089
34521
  setSecret(input.name, secret);
33090
34522
  return profile;
33091
34523
  }
33092
- function setActiveProfileAccount(identity, env = process.env) {
34524
+ function setActiveProfileAccount(identity, profileName, env = process.env) {
33093
34525
  const config = readConfig(env);
34526
+ const target = profileName ?? config.activeProfile;
33094
34527
  const profile = config.profiles.find(
33095
- (candidate) => candidate.name === config.activeProfile
34528
+ (candidate) => candidate.name === target
33096
34529
  );
33097
- if (!profile) return;
34530
+ if (!profile) return false;
33098
34531
  profile.accountId = identity.id;
33099
34532
  profile.accountTitle = identity.title;
33100
34533
  profile.accountRoute = identity.route;
33101
34534
  writeConfig(config, env);
34535
+ return true;
33102
34536
  }
33103
34537
  function removeProfile(name, env = process.env) {
33104
34538
  const config = readConfig(env);
@@ -33141,6 +34575,8 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
33141
34575
  "patch",
33142
34576
  "trace"
33143
34577
  ]);
34578
+ var API_VERSION_HEADER = "Api-Version-Date";
34579
+ var API_VERSION_DATE = native_spec_default.info["x-api-version-date"];
33144
34580
  var HIDDEN_PARAMS = /* @__PURE__ */ new Set(["authorization", "api-version-date"]);
33145
34581
  var AUTO_FILLED_PARAMS = /* @__PURE__ */ new Set(["company_id", "account_id"]);
33146
34582
  function hiddenParamRefs(spec) {
@@ -33308,20 +34744,63 @@ function createWhopFetch() {
33308
34744
  const headers = new Headers(request.headers);
33309
34745
  headers.set("Authorization", `Bearer ${token}`);
33310
34746
  headers.set("Content-Type", "application/json");
34747
+ if (!headers.has(API_VERSION_HEADER)) {
34748
+ headers.set(API_VERSION_HEADER, API_VERSION_DATE);
34749
+ }
33311
34750
  const res = await fetch(target, { method: request.method, headers, body });
33312
- if (res.ok) return res;
34751
+ if (res.ok) {
34752
+ if (method === "POST" || method === "PATCH") {
34753
+ const text2 = await res.text();
34754
+ const actionUrl = findActionUrl(safeParse(text2));
34755
+ if (actionUrl) await announceActionUrl(actionUrl);
34756
+ return new Response(text2, { status: res.status, headers: res.headers });
34757
+ }
34758
+ return res;
34759
+ }
33313
34760
  const text = await res.text();
33314
34761
  const payload = safeParse(text);
34762
+ const errorActionUrl = findActionUrl(
34763
+ payload?.error
34764
+ );
34765
+ if (errorActionUrl) await announceActionUrl(errorActionUrl);
33315
34766
  let message = extractApiMessage(payload) ?? text ?? `HTTP ${res.status}`;
33316
- if (res.status === 403 && /not authorized for the .* scope/i.test(message)) {
33317
- message += " This resource requires an API-key login (`whop login --api-key`).";
34767
+ if (res.status === 403) {
34768
+ const scope = /not authorized for the (\S+) scope/i.exec(message)?.[1];
34769
+ if (scope) {
34770
+ message += WHOP_SCOPES.includes(scope) ? " Your login predates this scope \u2014 run `whop login` to re-authorize." : " This resource requires an API-key login (`whop login --api-key`).";
34771
+ }
33318
34772
  }
34773
+ message = withJourneyHint(message, payload);
33319
34774
  return Response.json(
33320
34775
  { message, error: payload ?? text },
33321
34776
  { status: res.status }
33322
34777
  );
33323
34778
  };
33324
34779
  }
34780
+ var JOURNEY_HINTS = [
34781
+ {
34782
+ pattern: /exactly one of ad_group_id or ad_group/i,
34783
+ hint: `Pass --ad_group_id for an existing ad group, or create the whole tree in one call: whop ads create --title "..." --creatives '[{"id":"file_x"}]' --ad_group '{"title":"...","conversion_location":"website","ad_campaign":{"title":"...","platform":"meta","objective":"sales","status":"draft","budget_amount":25,"budget_optimization":"ad_campaign"}}'`
34784
+ },
34785
+ {
34786
+ pattern: /connect an ads payment method/i,
34787
+ hint: 'Configure billing with `whop accounts update-preferences <account_id> --ads_payment_methods \'{"primary":{"type":"platform_balance"}}\'`, funding the balance first via `whop deposits create` if needed.'
34788
+ },
34789
+ {
34790
+ pattern: /payment method requires user authentication/i,
34791
+ hint: "Run `whop login` (browser OAuth) \u2014 API-key credentials can only reorder already-configured payment methods."
34792
+ }
34793
+ ];
34794
+ function withJourneyHint(message, payload) {
34795
+ const depositUrl = payload && typeof payload === "object" ? payload.error?.deposit_url ?? void 0 : void 0;
34796
+ if (depositUrl) return appendSentence(message, `Deposit at ${depositUrl}`);
34797
+ const hint = JOURNEY_HINTS.find(({ pattern }) => pattern.test(message))?.hint;
34798
+ return hint ? appendSentence(message, hint) : message;
34799
+ }
34800
+ function appendSentence(message, addition) {
34801
+ const trimmed = message.trim();
34802
+ return `${trimmed}${/[.!?]$/.test(trimmed) ? "" : "."} ${addition}`;
34803
+ }
33325
34804
  function safeParse(text) {
33326
34805
  try {
33327
34806
  return JSON.parse(text);
@@ -33349,9 +34828,11 @@ export {
33349
34828
  PromptCancelledError,
33350
34829
  chooseAuthMethod,
33351
34830
  promptApiKey,
34831
+ selectAccount,
33352
34832
  selectProfile,
33353
34833
  startSpinner,
33354
34834
  OAuthError,
34835
+ listOAuthAccounts,
33355
34836
  performOAuthLogin,
33356
34837
  getValidAccessToken,
33357
34838
  listProfiles,
@@ -33362,8 +34843,9 @@ export {
33362
34843
  removeProfile,
33363
34844
  removeAllProfiles,
33364
34845
  switchProfile,
34846
+ API_VERSION_DATE,
33365
34847
  filterSpecByTag,
33366
34848
  resolveActiveAccountId,
33367
34849
  createWhopFetch
33368
34850
  };
33369
- //# sourceMappingURL=chunk-GKKJXDPK.js.map
34851
+ //# sourceMappingURL=chunk-BSCOWFVU.js.map