# Access Token Source: https://docs.whop.com/api-reference/access-tokens/access-token A short-lived access token used to authenticate API requests on behalf of a user. ```json Example theme={null} { "expires_at": "2023-12-01T05:00:00.401Z", "token": "" } ``` The timestamp after which this access token is no longer valid and must be refreshed. Example: `2023-12-01T05:00:00.401Z` The signed JWT access token string to include in API request Authorization headers. # Create access token Source: https://docs.whop.com/api-reference/access-tokens/create-access-token /openapi/api-v1-stable.json post /access_tokens Create a short-lived access token for authenticating API requests. When using API key authentication, provide company_id or user_id. When using OAuth, the user is derived from the token. Use this token with Whop's web and mobile embedded components. # Account Link Source: https://docs.whop.com/api-reference/account-links/account-link A temporary, time-limited URL that grants a user access to an external account management page. ```json Example theme={null} { "expires_at": "2023-12-01T05:00:00.401Z", "url": "https://whop.com/payouts/biz_xxxxxxxxx/verify" } ``` The timestamp after which this account link URL is no longer valid. Example: `2023-12-01T05:00:00.401Z` The temporary URL to redirect the user to for account access. Expires at the time specified by expires\_at. Example: `https://whop.com/payouts/biz_xxxxxxxxx/verify` # Create account link Source: https://docs.whop.com/api-reference/account-links/create-account-link /openapi/api-v1-stable.json post /account_links Generate a URL that directs a sub-merchant to their account portal, such as the hosted payouts dashboard or the KYC onboarding flow. # Ad Report Source: https://docs.whop.com/api-reference/ad-reports/ad-report An ads performance report. Always returns a summary. The `granularity` field contains a per-bucket time series when the `granularity` arg is set; the `breakdown` field contains per-entity rows when the `breakdown` arg is set. ```json Example theme={null} { "breakdown": [ { "granularity": [ { "bucket_start": "2023-12-01T05:00:00.401Z", "clicks": 42, "granularity": "hourly", "impressions": 42, "reach": 42, "result_count": 42, "result_label_key": null, "result_label_override": "", "spend": 6.9, "spend_currency": "usd", "stat_date": "2023-12-01T05:00:00.401Z", "stat_hour": 42 } ], "id": "", "level": "campaign", "name": "", "summary": { "click_through_rate": 6.9, "clicks": 42, "cost_per_click": 6.9, "cost_per_mille": 6.9, "cost_per_result": 6.9, "frequency": 6.9, "impressions": 42, "reach": 42, "result_count": 42, "result_label_key": "app_installs", "result_label_override": "", "return_on_ad_spend": 6.9, "spend": 6.9, "spend_currency": "usd" } } ], "granularity": [ { "bucket_start": "2023-12-01T05:00:00.401Z", "clicks": 42, "granularity": "hourly", "impressions": 42, "reach": 42, "result_count": 42, "result_label_key": "app_installs", "result_label_override": "", "spend": 6.9, "spend_currency": "usd", "stat_date": "2023-12-01T05:00:00.401Z", "stat_hour": 42 } ], "summary": { "click_through_rate": 6.9, "clicks": 42, "cost_per_click": 6.9, "cost_per_mille": 6.9, "cost_per_result": 6.9, "frequency": 6.9, "impressions": 42, "reach": 42, "result_count": 42, "result_label_key": "app_installs", "result_label_override": "", "return_on_ad_spend": 6.9, "spend": 6.9, "spend_currency": "usd" } } ``` Per-entity rows over the date range. `null` when the `breakdown` arg on `adReport` is omitted; otherwise contains one row per ad campaign, ad group, or ad inside the requested scope at the requested level. Per-bucket time series for this entity over the date range, ordered ascending by `bucketStart`. `null` when the `granularity` arg on `adReport` is omitted; otherwise contains rows at the requested grain (`daily` or `hourly`). The bucket's start time as a real UTC instant. `(statDate, statHour)` resolved in the ad account's reporting timezone — render this in the viewer's local timezone. Example: `2023-12-01T05:00:00.401Z` Clicks in this bucket. Example: `42` The bucket size of this row (`hourly`, `daily`, `weekly`, or `monthly`). Available options: `hourly`, `daily`, `weekly`, `monthly` Impressions in this bucket. Example: `42` Unique users reached in this bucket. Always `0` for hourly rows (Meta does not return reach at hourly grain). Example: `42` Count of the primary optimization result in this bucket. Example: `42` The type of optimization result represented by `resultCount`. Available options: `app_installs`, `messaging_conversations_started`, `post_engagement`, `event_responses`, `impressions`, `website_purchases`, `landing_page_views`, `leads`, `link_clicks`, `quality_calls`, `appointments_booked`, `messaging_purchases`, `page_likes`, `instagram_profile_visits`, `reach`, `reminders_set`, `new_subscribers`, `video_views`, `registrations`, `content_views`, `searches`, `adds_to_cart`, `adds_to_wishlist`, `adds_of_payment_info`, `checkouts_initiated`, `website_schedules`, `website_submit_applications`, `website_trials_started`, `website_subscriptions`, `website_contacts`, `website_donations`, `website_find_locations`, `website_product_customizations`, `custom` Advertiser-defined label for the result when `resultLabelKey` is `custom`. Charged spend in this bucket in the requested reporting currency — the amount billed including platform fees, not the platform-side net spend. Example: `6.9` Currency of the `spend` value. Available options: `usd`, `sgd`, `inr`, `aud`, `brl`, `cad`, `dkk`, `eur`, `nok`, `gbp`, `sek`, `chf`, `hkd`, `huf`, `jpy`, `mxn`, `myr`, `pln`, `czk`, `nzd`, `aed`, `eth`, `ape`, `cop`, `ron`, `thb`, `bgn`, `idr`, `dop`, `php`, `try`, `krw`, `twd`, `vnd`, `pkr`, `clp`, `uyu`, `ars`, `zar`, `dzd`, `tnd`, `mad`, `kes`, `kwd`, `jod`, `all`, `xcd`, `amd`, `bsd`, `bhd`, `bob`, `bam`, `khr`, `crc`, `xof`, `egp`, `etb`, `gmd`, `ghs`, `gtq`, `gyd`, `ils`, `jmd`, `mop`, `mga`, `mur`, `mdl`, `mnt`, `nad`, `ngn`, `mkd`, `omr`, `pyg`, `pen`, `qar`, `rwf`, `sar`, `rsd`, `lkr`, `tzs`, `ttd`, `uzs`, `rub`, `btc`, `cny`, `usdt`, `kzt`, `awg`, `whop_usd`, `xau` The date these stats cover (midnight UTC). For hourly rows, see `statHour` and `bucketStart`. Example: `2023-12-01T05:00:00.401Z` Hour of the day in the ad account's reporting timezone (0-23). `null` for daily rows. Example: `42` Tag of the entity (ad campaign, ad group, or ad). The entity level of this row — matches the `breakdown` arg. Available options: `campaign`, `ad_group`, `ad` Display name of the entity, when available. Aggregate totals and rates for this entity over the date range. Click-through rate (clicks / impressions). Example: `6.9` Total clicks over the date range. Example: `42` Cost per click in the requested reporting currency. Example: `6.9` Cost per thousand impressions in the requested reporting currency. Example: `6.9` Spend divided by `resultCount`. Null when there are no results. Example: `6.9` Average number of times each reached user saw an ad. Example: `6.9` Total impressions over the date range. Example: `42` Unique users reached, deduplicated by the external ad platform. Example: `42` Count of the campaign's primary optimization result (purchases, clicks, etc.) — see `resultLabelKey`. Example: `42` The type of optimization result represented by `resultCount`. Available options: `app_installs`, `messaging_conversations_started`, `post_engagement`, `event_responses`, `impressions`, `website_purchases`, `landing_page_views`, `leads`, `link_clicks`, `quality_calls`, `appointments_booked`, `messaging_purchases`, `page_likes`, `instagram_profile_visits`, `reach`, `reminders_set`, `new_subscribers`, `video_views`, `registrations`, `content_views`, `searches`, `adds_to_cart`, `adds_to_wishlist`, `adds_of_payment_info`, `checkouts_initiated`, `website_schedules`, `website_submit_applications`, `website_trials_started`, `website_subscriptions`, `website_contacts`, `website_donations`, `website_find_locations`, `website_product_customizations`, `custom` Advertiser-defined label for the result when `resultLabelKey` is `custom`. Alias for `purchaseReturnOnAdSpend` — return on ad spend for purchases, as reported by the external ad platform. Example: `6.9` Total spend over the date range in the requested reporting currency. Example: `6.9` Currency of the `spend` value. Matches the requested `currency` when set. Available options: `usd`, `sgd`, `inr`, `aud`, `brl`, `cad`, `dkk`, `eur`, `nok`, `gbp`, `sek`, `chf`, `hkd`, `huf`, `jpy`, `mxn`, `myr`, `pln`, `czk`, `nzd`, `aed`, `eth`, `ape`, `cop`, `ron`, `thb`, `bgn`, `idr`, `dop`, `php`, `try`, `krw`, `twd`, `vnd`, `pkr`, `clp`, `uyu`, `ars`, `zar`, `dzd`, `tnd`, `mad`, `kes`, `kwd`, `jod`, `all`, `xcd`, `amd`, `bsd`, `bhd`, `bob`, `bam`, `khr`, `crc`, `xof`, `egp`, `etb`, `gmd`, `ghs`, `gtq`, `gyd`, `ils`, `jmd`, `mop`, `mga`, `mur`, `mdl`, `mnt`, `nad`, `ngn`, `mkd`, `omr`, `pyg`, `pen`, `qar`, `rwf`, `sar`, `rsd`, `lkr`, `tzs`, `ttd`, `uzs`, `rub`, `btc`, `cny`, `usdt`, `kzt`, `awg`, `whop_usd`, `xau` Per-bucket time series over the date range, ordered ascending by `bucketStart`. `null` when the `granularity` arg on `adReport` is omitted; otherwise contains rows at the requested grain (`daily` or `hourly`). The bucket's start time as a real UTC instant. `(statDate, statHour)` resolved in the ad account's reporting timezone — render this in the viewer's local timezone. Example: `2023-12-01T05:00:00.401Z` Clicks in this bucket. Example: `42` The bucket size of this row (`hourly`, `daily`, `weekly`, or `monthly`). Available options: `hourly`, `daily`, `weekly`, `monthly` Impressions in this bucket. Example: `42` Unique users reached in this bucket. Always `0` for hourly rows (Meta does not return reach at hourly grain). Example: `42` Count of the primary optimization result in this bucket. Example: `42` The type of optimization result represented by `resultCount`. Available options: `app_installs`, `messaging_conversations_started`, `post_engagement`, `event_responses`, `impressions`, `website_purchases`, `landing_page_views`, `leads`, `link_clicks`, `quality_calls`, `appointments_booked`, `messaging_purchases`, `page_likes`, `instagram_profile_visits`, `reach`, `reminders_set`, `new_subscribers`, `video_views`, `registrations`, `content_views`, `searches`, `adds_to_cart`, `adds_to_wishlist`, `adds_of_payment_info`, `checkouts_initiated`, `website_schedules`, `website_submit_applications`, `website_trials_started`, `website_subscriptions`, `website_contacts`, `website_donations`, `website_find_locations`, `website_product_customizations`, `custom` Advertiser-defined label for the result when `resultLabelKey` is `custom`. Charged spend in this bucket in the requested reporting currency — the amount billed including platform fees, not the platform-side net spend. Example: `6.9` Currency of the `spend` value. Available options: `usd`, `sgd`, `inr`, `aud`, `brl`, `cad`, `dkk`, `eur`, `nok`, `gbp`, `sek`, `chf`, `hkd`, `huf`, `jpy`, `mxn`, `myr`, `pln`, `czk`, `nzd`, `aed`, `eth`, `ape`, `cop`, `ron`, `thb`, `bgn`, `idr`, `dop`, `php`, `try`, `krw`, `twd`, `vnd`, `pkr`, `clp`, `uyu`, `ars`, `zar`, `dzd`, `tnd`, `mad`, `kes`, `kwd`, `jod`, `all`, `xcd`, `amd`, `bsd`, `bhd`, `bob`, `bam`, `khr`, `crc`, `xof`, `egp`, `etb`, `gmd`, `ghs`, `gtq`, `gyd`, `ils`, `jmd`, `mop`, `mga`, `mur`, `mdl`, `mnt`, `nad`, `ngn`, `mkd`, `omr`, `pyg`, `pen`, `qar`, `rwf`, `sar`, `rsd`, `lkr`, `tzs`, `ttd`, `uzs`, `rub`, `btc`, `cny`, `usdt`, `kzt`, `awg`, `whop_usd`, `xau` The date these stats cover (midnight UTC). For hourly rows, see `statHour` and `bucketStart`. Example: `2023-12-01T05:00:00.401Z` Hour of the day in the ad account's reporting timezone (0-23). `null` for daily rows. Example: `42` Aggregate totals and rates over the date range. Click-through rate (clicks / impressions). Example: `6.9` Total clicks over the date range. Example: `42` Cost per click in the requested reporting currency. Example: `6.9` Cost per thousand impressions in the requested reporting currency. Example: `6.9` Spend divided by `resultCount`. Null when there are no results. Example: `6.9` Average number of times each reached user saw an ad. Example: `6.9` Total impressions over the date range. Example: `42` Unique users reached, deduplicated by the external ad platform. Example: `42` Count of the campaign's primary optimization result (purchases, clicks, etc.) — see `resultLabelKey`. Example: `42` The type of optimization result represented by `resultCount`. Available options: `app_installs`, `messaging_conversations_started`, `post_engagement`, `event_responses`, `impressions`, `website_purchases`, `landing_page_views`, `leads`, `link_clicks`, `quality_calls`, `appointments_booked`, `messaging_purchases`, `page_likes`, `instagram_profile_visits`, `reach`, `reminders_set`, `new_subscribers`, `video_views`, `registrations`, `content_views`, `searches`, `adds_to_cart`, `adds_to_wishlist`, `adds_of_payment_info`, `checkouts_initiated`, `website_schedules`, `website_submit_applications`, `website_trials_started`, `website_subscriptions`, `website_contacts`, `website_donations`, `website_find_locations`, `website_product_customizations`, `custom` Advertiser-defined label for the result when `resultLabelKey` is `custom`. Alias for `purchaseReturnOnAdSpend` — return on ad spend for purchases, as reported by the external ad platform. Example: `6.9` Total spend over the date range in the requested reporting currency. Example: `6.9` Currency of the `spend` value. Matches the requested `currency` when set. Available options: `usd`, `sgd`, `inr`, `aud`, `brl`, `cad`, `dkk`, `eur`, `nok`, `gbp`, `sek`, `chf`, `hkd`, `huf`, `jpy`, `mxn`, `myr`, `pln`, `czk`, `nzd`, `aed`, `eth`, `ape`, `cop`, `ron`, `thb`, `bgn`, `idr`, `dop`, `php`, `try`, `krw`, `twd`, `vnd`, `pkr`, `clp`, `uyu`, `ars`, `zar`, `dzd`, `tnd`, `mad`, `kes`, `kwd`, `jod`, `all`, `xcd`, `amd`, `bsd`, `bhd`, `bob`, `bam`, `khr`, `crc`, `xof`, `egp`, `etb`, `gmd`, `ghs`, `gtq`, `gyd`, `ils`, `jmd`, `mop`, `mga`, `mur`, `mdl`, `mnt`, `nad`, `ngn`, `mkd`, `omr`, `pyg`, `pen`, `qar`, `rwf`, `sar`, `rsd`, `lkr`, `tzs`, `ttd`, `uzs`, `rub`, `btc`, `cny`, `usdt`, `kzt`, `awg`, `whop_usd`, `xau` # Retrieve ad report Source: https://docs.whop.com/api-reference/ad-reports/retrieve-ad-report /openapi/api-v1-stable.json get /ad_reports Performance report for a company, ad campaigns, ad groups, or ads. Always returns aggregate `summary` totals summed across the scope. Set `granularity` to additionally get a time series, or set `breakdown` (`campaign`/`ad_group`/`ad`) to additionally get per-entity rows inside the requested scope. Exactly one of `companyId`, `adCampaignIds`, `adGroupIds`, or `adIds` must be provided. Required permissions: - `ad_campaign:stats:read` # Affiliate Source: https://docs.whop.com/api-reference/affiliates/affiliate An affiliate tracks a user's referral performance and commission earnings for a company, including retention rates, revenue metrics, and payout configurations. ```json Example theme={null} { "active_members_count": 42, "company": { "id": "biz_xxxxxxxxxxxxxx", "title": "" }, "created_at": "2023-12-01T05:00:00.401Z", "customer_retention_rate": "", "customer_retention_rate_ninety_days": "", "id": "aff_xxxxxxxxxxxxxx", "monthly_recurring_revenue_usd": "", "status": "active", "total_overrides_count": 42, "total_referral_earnings_usd": "", "total_referrals_count": 42, "total_revenue_usd": "", "updated_at": "2023-12-01T05:00:00.401Z", "user": { "id": "user_xxxxxxxxxxxxx", "name": "Jane Smith", "username": "janesmith" } } ``` The total active members of the affiliate Example: `42` The company attached to this affiliate The unique identifier for the company. Example: `biz_xxxxxxxxxxxxxx` The written name of the company. The datetime the affiliate was created. Example: `2023-12-01T05:00:00.401Z` The percentage of referred customers who are still active members The percentage of referred customers who remained active over the last 90 days The unique identifier for the affiliate. Example: `aff_xxxxxxxxxxxxxx` The monthly recurring revenue generated by this affiliate's referrals, formatted as a USD currency string The status of the affiliate Available options: `active`, `archived`, `deleted` The total count of all overrides for this affiliate Example: `42` The total commission earnings paid to this affiliate, formatted as a USD currency string The total referrals of the affiliate Example: `42` The total revenue generated from this affiliate's referrals, formatted as a USD currency string The datetime the affiliate was last updated. Example: `2023-12-01T05:00:00.401Z` The user attached to this affiliate The unique identifier for the user. Example: `user_xxxxxxxxxxxxx` The display name set on the user's Whop profile. Null if the user has not set a name. Example: `Jane Smith` The unique username chosen by the user for their Whop profile. Null if the user has not set a username. Example: `janesmith` # Archive affiliate Source: https://docs.whop.com/api-reference/affiliates/archive-affiliate /openapi/api-v1-stable.json post /affiliates/{id}/archive Archives an existing Affiliate Required permissions: - `affiliate:update` # Create affiliate Source: https://docs.whop.com/api-reference/affiliates/create-affiliate /openapi/api-v1-stable.json post /affiliates Creates or finds an affiliate for a company and user. Required permissions: - `affiliate:create` # Create override Source: https://docs.whop.com/api-reference/affiliates/create-override /openapi/api-v1-stable.json post /affiliates/{id}/overrides Creates a commission override for an affiliate. Required permissions: - `affiliate:create` # Delete override Source: https://docs.whop.com/api-reference/affiliates/delete-override /openapi/api-v1-stable.json delete /affiliates/{id}/overrides/{override_id} Deletes an affiliate override. Required permissions: - `affiliate:update` # List affiliates Source: https://docs.whop.com/api-reference/affiliates/list-affiliates /openapi/api-v1-stable.json get /affiliates Returns a paginated list of affiliates for the actor in context, with optional filtering by status, search, and sorting. Required permissions: - `affiliate:basic:read` # List overrides Source: https://docs.whop.com/api-reference/affiliates/list-overrides /openapi/api-v1-stable.json get /affiliates/{id}/overrides Returns a paginated list of overrides for an affiliate. Required permissions: - `affiliate:basic:read` # Retrieve affiliate Source: https://docs.whop.com/api-reference/affiliates/retrieve-affiliate /openapi/api-v1-stable.json get /affiliates/{id} Retrieves the details of an existing affiliate. Required permissions: - `affiliate:basic:read` # Retrieve override Source: https://docs.whop.com/api-reference/affiliates/retrieve-override /openapi/api-v1-stable.json get /affiliates/{id}/overrides/{override_id} Retrieves the details of a specific affiliate override. Required permissions: - `affiliate:basic:read` # Unarchive affiliate Source: https://docs.whop.com/api-reference/affiliates/unarchive-affiliate /openapi/api-v1-stable.json post /affiliates/{id}/unarchive Unarchives an existing Affiliate Required permissions: - `affiliate:update` # Update override Source: https://docs.whop.com/api-reference/affiliates/update-override /openapi/api-v1-stable.json patch /affiliates/{id}/overrides/{override_id} Updates an existing affiliate override. Required permissions: - `affiliate:update` # App Build Source: https://docs.whop.com/api-reference/app-builds/app-build A versioned build artifact for a Whop React Native App, submitted for review and deployment to a specific platform. ```json Example theme={null} { "checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "created_at": "2023-12-01T05:00:00.401Z", "file_url": "https://cdn.whop.com/builds/abc123.zip", "id": "apbu_xxxxxxxxxxxxx", "is_production": true, "platform": "ios", "review_message": "App crashes on launch. Please fix and resubmit.", "source_url": "https://cdn.whop.com/builds/abc123-source.zip", "status": "draft", "supported_app_view_types": ["hub"] } ``` A SHA-256 hash of the uploaded build file, generated by the client and used to verify file integrity. Example: `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7…` The datetime the app build was created. Example: `2023-12-01T05:00:00.401Z` A URL to download the app build as a .zip archive. Example: `https://cdn.whop.com/builds/abc123.zip` The unique identifier for the app build. Example: `apbu_xxxxxxxxxxxxx` Whether this build is the currently active production build for its platform. The target platform for this build. Available options: `ios`, `android`, `web` Feedback from the reviewer explaining why the build was rejected. Null if the build has not been reviewed or was approved. Example: `App crashes on launch. Please fix and resubmit.` A URL to download the compressed source code archive that produced this build. Null if the build was uploaded without a source archive. Example: `https://cdn.whop.com/builds/abc123-source.zip` The current review status of this build. Available options: `draft`, `pending`, `approved`, `rejected` The list of view types this build supports, as declared by the developer. Available options: `hub`, `discover`, `dash`, `dashboard`, `analytics`, `skills`, `openapi` # Create app build Source: https://docs.whop.com/api-reference/app-builds/create-app-build /openapi/api-v1-stable.json post /app_builds Upload a new build artifact for an app. The build must include a compiled code bundle for the specified platform. Required permissions: - `developer:manage_builds` # List app builds Source: https://docs.whop.com/api-reference/app-builds/list-app-builds /openapi/api-v1-stable.json get /app_builds Returns a paginated list of build artifacts for a given app, with optional filtering by platform, status, and creation date. Required permissions: - `developer:manage_builds` # Promote app build Source: https://docs.whop.com/api-reference/app-builds/promote-app-build /openapi/api-v1-stable.json post /app_builds/{id}/promote Promote an approved or draft app build to production so it becomes the active version served to users. Required permissions: - `developer:manage_builds` # Retrieve app build Source: https://docs.whop.com/api-reference/app-builds/retrieve-app-build /openapi/api-v1-stable.json get /app_builds/{id} Retrieves the details of an existing app build. Required permissions: - `developer:manage_builds` # App Source: https://docs.whop.com/api-reference/apps/app An app is an integration built on Whop. Apps can serve consumers as experiences within products, or serve companies as business tools. ```json Example theme={null} { "api_key": { "created_at": "2023-12-01T05:00:00.401Z", "id": "", "token": "" }, "app_type": "b2b_app", "base_url": "https://myapp.example.com", "company": { "id": "biz_xxxxxxxxxxxxxx", "title": "Pickaxe" }, "creator": { "id": "user_xxxxxxxxxxxxx", "name": "John Doe", "username": "johndoe42" }, "dashboard_path": "/experiences/[experienceId]", "default_api_key": { "id": "", "name": "", "obfuscated_secret_key": "", "secret_key": "" }, "description": "A comprehensive analytics dashboard for tracking revenue, members, and growth metrics.", "discover_path": "/experiences/[experienceId]", "domain_id": "ab1c2d3e4f5g6h7i8j9k", "experience_path": "/experiences/[experienceId]", "hosted_url": "https://myapp.whop.app", "icon": { "url": "https://media.whop.com/abc123/optimized.jpg" }, "id": "app_xxxxxxxxxxxxxx", "marketplace_status": "not_available", "name": "Courses", "oauth_client_type": "public", "openapi_path": "/experiences/[experienceId]", "origin": "", "product_id": "", "production_web_build": { "checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "file_url": "https://cdn.whop.com/builds/abc123.zip", "id": "apbu_xxxxxxxxxxxxx", "source_url": "https://cdn.whop.com/builds/abc123-source.zip", "status": "draft" }, "redirect_uris": [""], "requested_permissions": [ { "is_required": true, "justification": "", "permission_action": { "action": "", "name": "" } } ], "route": "myapp", "secrets": {}, "skills_path": "/experiences/[experienceId]", "stats": { "dau": 42, "mau": 42, "time_spent_last24_hours": 42, "wau": 42 }, "status": "live", "verified": true } ``` The API key used to authenticate requests on behalf of this app. Null if no API key has been generated. Requires the 'developer:manage\_api\_key' permission. The datetime the private api key was created. Example: `2023-12-01T05:00:00.401Z` The unique identifier for the private api key. This is the API key used to authenticate requests The target audience classification for this app (e.g., 'b2b\_app', 'b2c\_app', 'company\_app', 'component'). Available options: `b2b_app`, `b2c_app`, `company_app`, `component`, `website` The production base URL where the app is hosted. Null if no base URL is configured. Example: `https://myapp.example.com` The company that owns and publishes this app. The unique identifier for the company. Example: `biz_xxxxxxxxxxxxxx` The display name of the company shown to customers. Example: `Pickaxe` The user who created and owns the company that published this app. The unique identifier for the user. Example: `user_xxxxxxxxxxxxx` The user's display name shown on their public profile. Example: `John Doe` The user's unique username shown on their public profile. Example: `johndoe42` The URL path template for a specific view of this app, appended to the base domain (e.g., '/experiences/\[experienceId]'). Null if the specified view type is not configured. Example: `/experiences/[experienceId]` The app's default API key, used to authenticate requests on behalf of this app. Null if the app has no default key. Requires the 'developer:manage\_api\_key' permission. The unique identifier for the authorized api key. A user set name to identify an API key A masked version of the secret key used to authenticate requests. This is so that the owner can easily identify which key it is without being shown the full secret. The secret key used to authenticate requests. This is only available if the current actor would have been able to create this api key. A written description of what this app does, displayed on the app store listing page. Null if no description has been set. Example: `A comprehensive analytics dashboard for tracking revenue,…` The URL path template for a specific view of this app, appended to the base domain (e.g., '/experiences/\[experienceId]'). Null if the specified view type is not configured. Example: `/experiences/[experienceId]` The unique subdomain identifier for this app's proxied URL on the Whop platform. Forms the URL pattern https\://\{domain\_id}.apps.whop.com. Example: `ab1c2d3e4f5g6h7i8j9k` The URL path template for a specific view of this app, appended to the base domain (e.g., '/experiences/\[experienceId]'). Null if the specified view type is not configured. Example: `/experiences/[experienceId]` The full canonical URL where this app's hosted web build is served. Null if the app has not claimed a route. Example: `https://myapp.whop.app` The icon image for this app, displayed on the app store, product pages, checkout, and as the default icon for experiences using this app. A pre-optimized URL for rendering this attachment on the client. This should be used for displaying attachments in apps. Example: `https://media.whop.com/abc123/optimized.jpg` The unique identifier for the app. Example: `app_xxxxxxxxxxxxxx` The approval status of this app's product listing on the Whop app store. Null if the app has no associated product. Available options: `not_available`, `pending_review`, `live_marketplace` The display name of this app shown on the app store and in experience navigation. Maximum 30 characters. Example: `Courses` How this app authenticates when exchanging OAuth authorization and refresh grants. Available options: `public`, `confidential` The URL path template for a specific view of this app, appended to the base domain (e.g., '/experiences/\[experienceId]'). Null if the specified view type is not configured. Example: `/experiences/[experienceId]` The full origin URL for this app's proxied domain (e.g., '[https://myapp.apps.whop.com](https://myapp.apps.whop.com)'). Null if no proxy domain is configured. The approved app build currently served to users on web. Null if no production build is deployed for web. A SHA-256 hash of the uploaded build file, generated by the client and used to verify file integrity. Example: `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7…` A URL to download the app build as a .zip archive. Example: `https://cdn.whop.com/builds/abc123.zip` The unique identifier for the app build. Example: `apbu_xxxxxxxxxxxxx` A URL to download the compressed source code archive that produced this build. Null if the build was uploaded without a source archive. Example: `https://cdn.whop.com/builds/abc123-source.zip` The current review status of this build. Available options: `draft`, `pending`, `approved`, `rejected` The whitelisted OAuth callback URLs that users are redirected to after authorizing the app. The list of permissions this app requests when installed, including both required and optional permissions with justifications. Whether the action is required for the app to function. The reason for requesting the action. The action that the app will request off of users when a user installs the app. The identifier of the action. The human readable name of the action. The unique subdomain route where this app's hosted web builds are served, such as 'myapp' for myapp.whop.app. Null if the app has not claimed a route. Example: `myapp` The app's secrets as an object of string values. Encrypted at rest and injected into the app's hosted server runtime as environment bindings. Requires the 'developer:update\_app' permission. The URL path template for a specific view of this app, appended to the base domain (e.g., '/experiences/\[experienceId]'). Null if the specified view type is not configured. Example: `/experiences/[experienceId]` Aggregate usage statistics for this app, including daily, weekly, and monthly active user counts. The number of unique users who have spent time in this app in the last 24 hours. Returns 0 if no usage data is available. Example: `42` The number of unique users who have spent time in this app in the last 28 days. Returns 0 if no usage data is available. Example: `42` The total time, in seconds, that all users have spent in this app over the last 24 hours. Returns 0 if no usage data is available. Example: `42` The number of unique users who have spent time in this app in the last 7 days. Returns 0 if no usage data is available. Example: `42` The current visibility status of this app on the Whop app store. 'live' means publicly discoverable, 'unlisted' means accessible only via direct link, and 'hidden' means not visible anywhere. Available options: `live`, `unlisted`, `hidden` Whether this app has been verified by Whop. Verified apps are endorsed by Whop and displayed in the featured apps section of the app store. # Create app Source: https://docs.whop.com/api-reference/apps/create-app /openapi/api-v1-stable.json post /apps Register a new app on the Whop developer platform. Apps provide custom experiences that can be added to products. Required permissions: - `developer:create_app` - `developer:manage_api_key` - `developer:update_app` # List apps Source: https://docs.whop.com/api-reference/apps/list-apps /openapi/api-v1-stable.json get /apps Returns a paginated list of apps on the Whop platform, with optional filtering by company, type, view support, and search query. # Retrieve app Source: https://docs.whop.com/api-reference/apps/retrieve-app /openapi/api-v1-stable.json get /apps/{id} Retrieves the details of an existing app. Required permissions: - `developer:manage_api_key` - `developer:update_app` # Update app Source: https://docs.whop.com/api-reference/apps/update-app /openapi/api-v1-stable.json patch /apps/{id} Update the settings, metadata, or status of an existing app on the Whop developer platform. Required permissions: - `developer:update_app` - `developer:manage_api_key` # Update requested permissions Source: https://docs.whop.com/api-reference/apps/update-requested-permissions /openapi/api-v1-stable.json patch /apps/{app_id}/permissions Updates the permission requirements for an app Required permissions: - `developer:update_app_authorization` # Company Token Transaction Source: https://docs.whop.com/api-reference/company-token-transactions/company-token-transaction A token transaction records a credit or debit to a member's token balance within a company, including transfers between members. ```json Example theme={null} { "amount": 6.9, "company": { "id": "biz_xxxxxxxxxxxxxx", "route": "", "title": "" }, "created_at": "2023-12-01T05:00:00.401Z", "description": "Reward for completing onboarding", "id": "", "idempotency_key": "txn_reward_usr_123_2024", "linked_transaction_id": "", "member": { "id": "" }, "transaction_type": "add", "user": { "id": "user_xxxxxxxxxxxxx", "name": "John Doe", "username": "johndoe42" } } ``` The token amount for this transaction. Always a positive value regardless of transaction type. Example: `6.9` The company whose token balance this transaction affects. The unique identifier for the company. Example: `biz_xxxxxxxxxxxxxx` The slug/route of the company on the Whop site. The written name of the company. The datetime the company token transaction was created. Example: `2023-12-01T05:00:00.401Z` Free-text description explaining the reason for this token transaction. Null if no description was provided. Example: `Reward for completing onboarding` The unique identifier for the company token transaction. A unique key used to prevent duplicate transactions when retrying API requests. Null if no idempotency key was provided. Example: `txn_reward_usr_123_2024` The ID of the corresponding transaction on the other side of a transfer. Null if this is not a transfer transaction. The member whose token balance was affected by this transaction. The unique identifier for the company member. The direction of this token transaction (add, subtract, or transfer). Available options: `add`, `subtract`, `transfer` The user whose token balance was affected by this transaction. The unique identifier for the user. Example: `user_xxxxxxxxxxxxx` The user's display name shown on their public profile. Example: `John Doe` The user's unique username shown on their public profile. Example: `johndoe42` # Create company token transaction Source: https://docs.whop.com/api-reference/company-token-transactions/create-company-token-transaction /openapi/api-v1-stable.json post /company_token_transactions Create a token transaction to add, subtract, or transfer tokens for a member within a company. Required permissions: - `company_token_transaction:create` - `member:basic:read` - `company:basic:read` # List company token transactions Source: https://docs.whop.com/api-reference/company-token-transactions/list-company-token-transactions /openapi/api-v1-stable.json get /company_token_transactions Returns a paginated list of token transactions for a user or company, depending on the authenticated actor, with optional filtering by user and transaction type. Required permissions: - `company_token_transaction:read` - `member:basic:read` - `company:basic:read` # Retrieve company token transaction Source: https://docs.whop.com/api-reference/company-token-transactions/retrieve-company-token-transaction /openapi/api-v1-stable.json get /company_token_transactions/{id} Retrieves the details of an existing company token transaction. Required permissions: - `company_token_transaction:read` - `member:basic:read` - `company:basic:read` # Approve entry Source: https://docs.whop.com/api-reference/entries/approve-entry /openapi/api-v1-stable.json post /entries/{id}/approve Approve a pending waitlist entry, triggering the checkout process to grant the user access to the plan. Required permissions: - `plan:waitlist:manage` # Deny entry Source: https://docs.whop.com/api-reference/entries/deny-entry /openapi/api-v1-stable.json post /entries/{id}/deny Deny a pending waitlist entry, preventing the user from gaining access to the plan. Required permissions: - `plan:waitlist:manage` - `plan:basic:read` - `member:email:read` # Entry Source: https://docs.whop.com/api-reference/entries/entry An entry represents a user's signup for a waitlisted plan. ```json Example theme={null} { "created_at": "2023-12-01T05:00:00.401Z", "custom_field_responses": [ { "answer": "", "id": "cfrp_xxxxxxxxxxxxx", "question": "" } ], "id": "entry_xxxxxxxxxxxx", "plan": { "id": "plan_xxxxxxxxxxxxx" }, "product": { "id": "prod_xxxxxxxxxxxxx", "title": "Pickaxe Analytics" }, "status": "drafted", "user": { "email": "john.doe@example.com", "id": "user_xxxxxxxxxxxxx", "name": "John Doe", "username": "johndoe42" } } ``` The datetime the entry was created. Example: `2023-12-01T05:00:00.401Z` The list of responses collected from the user when submitting their waitlist entry. The response a user gave to the specific question or field. The unique identifier for the custom field response. Example: `cfrp_xxxxxxxxxxxxx` The question asked by the custom field The unique identifier for the entry. Example: `entry_xxxxxxxxxxxx` The waitlisted plan that this entry is a signup for. The unique identifier for the plan. Example: `plan_xxxxxxxxxxxxx` The product associated with this entry's waitlisted plan. Null if the plan is not tied to a product. The unique identifier for the product. Example: `prod_xxxxxxxxxxxxx` The display name of the product shown to customers on the product page and in search results. Example: `Pickaxe Analytics` The current status of the waitlist entry (e.g., drafted, pending, approved, denied). Available options: `drafted`, `pending`, `approved`, `denied`, `any` The user who submitted this waitlist entry. The user's email address. Requires the member:email:read permission to access. Null if not authorized. Example: `john.doe@example.com` The unique identifier for the user. Example: `user_xxxxxxxxxxxxx` The user's display name shown on their public profile. Example: `John Doe` The user's unique username shown on their public profile. Example: `johndoe42` # List entries Source: https://docs.whop.com/api-reference/entries/list-entries /openapi/api-v1-stable.json get /entries Returns a paginated list of waitlist entries for a company, with optional filtering by product, plan, status, and creation date. Required permissions: - `plan:waitlist:read` - `member:email:read` # Retrieve entry Source: https://docs.whop.com/api-reference/entries/retrieve-entry /openapi/api-v1-stable.json get /entries/{id} Retrieves the details of an existing waitlist entry. Required permissions: - `plan:waitlist:read` - `member:email:read` # Create file Source: https://docs.whop.com/api-reference/files/create-file /openapi/api-v1-stable.json post /files Create a new file record and receive a presigned URL for uploading content to S3. # File Source: https://docs.whop.com/api-reference/files/file A file that has been uploaded or is pending upload. ```json Example theme={null} { "content_type": "image/jpeg", "filename": "document.pdf", "id": "file_xxxxxxxxxxxxx", "size": "123.45", "upload_status": "pending", "url": "", "visibility": "public" } ``` The MIME type of the uploaded file (e.g., image/jpeg, video/mp4, audio/mpeg). Example: `image/jpeg` The original filename of the uploaded file, including its file extension. Example: `document.pdf` The unique identifier for the file. Example: `file_xxxxxxxxxxxxx` The file size in bytes. Null if the file has not finished uploading. Example: `123.45` The current upload status of the file (e.g., pending, ready). Available options: `pending`, `processing`, `ready`, `failed` The URL for accessing the file. For public files, this is a permanent CDN URL. For private files, this is a signed URL that expires. Null if the file has not finished uploading. Whether the file is publicly accessible or requires authentication. Available options: `public`, `private` # Retrieve file Source: https://docs.whop.com/api-reference/files/retrieve-file /openapi/api-v1-stable.json get /files/{id} Retrieves the details of an existing file. # Create webhook Source: https://docs.whop.com/api-reference/webhooks/create-webhook /openapi/api-v1-stable.json post /webhooks Creates a new webhook Required permissions: - `developer:manage_webhook` # Delete webhook Source: https://docs.whop.com/api-reference/webhooks/delete-webhook /openapi/api-v1-stable.json delete /webhooks/{id} Deletes a webhook Required permissions: - `developer:manage_webhook` # List deliveries Source: https://docs.whop.com/api-reference/webhooks/list-deliveries /openapi/api-v1-stable.json get /webhooks/{webhook_id}/deliveries Returns a paginated list of delivery attempts for a webhook, ordered by most recent first. Includes the request payload, response body, response code, and timing for each attempt. Required permissions: - `developer:manage_webhook` # List webhooks Source: https://docs.whop.com/api-reference/webhooks/list-webhooks /openapi/api-v1-stable.json get /webhooks Returns a paginated list of webhook endpoints configured for a company, ordered by most recently created. Required permissions: - `developer:manage_webhook` # Retrieve webhook Source: https://docs.whop.com/api-reference/webhooks/retrieve-webhook /openapi/api-v1-stable.json get /webhooks/{id} Retrieves the details of an existing webhook. Required permissions: - `developer:manage_webhook` # Send test event Source: https://docs.whop.com/api-reference/webhooks/send-test-event /openapi/api-v1-stable.json post /webhooks/{id}/test Tests a webhook Required permissions: - `developer:manage_webhook` # Update webhook Source: https://docs.whop.com/api-reference/webhooks/update-webhook /openapi/api-v1-stable.json patch /webhooks/{id} Updates a webhook Required permissions: - `developer:manage_webhook` # Webhook Source: https://docs.whop.com/api-reference/webhooks/webhook A webhook endpoint that receives event notifications for a company via HTTP POST. ```json Example theme={null} { "api_version": "v1", "api_version_date": "", "child_resource_events": true, "created_at": "2023-12-01T05:00:00.401Z", "enabled": true, "events": ["invoice.created"], "id": "hook_xxxxxxxxxxxxx", "resource_id": "", "testable_events": ["invoice.created"], "url": "https://example.com/path", "webhook_secret": "whsec_abc123def456" } ``` The API version used to format payloads sent to this webhook endpoint. Available options: `v1`, `v2`, `v5` The dated API version (Api-Version-Date) that v1 payloads for this endpoint are pinned to: events serialize exactly like a REST read at this version (the native serializer where the resource has one). Null when unpinned — legacy (v2/v5) webhooks, and v1 webhooks on the legacy payload shape. Whether events are sent for child resources. For example, if the webhook is on a company, enabling this sends events only from the company's sub-merchants (child companies). The datetime the webhook was created. Example: `2023-12-01T05:00:00.401Z` Whether this webhook endpoint is currently active and receiving events. The list of event types this webhook is subscribed to. Available options: `invoice.created`, `invoice.marked_uncollectible`, `invoice.paid`, `invoice.past_due`, `invoice.voided`, `membership.activated`, `membership.deactivated`, `membership.trial_ending_soon`, `entry.created`, `entry.approved`, `entry.denied`, `entry.deleted`, `export.completed`, `export.failed`, `setup_intent.requires_action`, `setup_intent.succeeded`, `setup_intent.canceled`, `ledger_account.funds_available`, `swap.completed`, `deposit.succeeded`, `transfer.created`, `transfer.completed`, `withdrawal.created`, `withdrawal.updated`, `card_transaction.created`, `card_transaction.updated`, `card_transaction.completed`, `card_transaction.declined`, `card_transaction.reversed`, `card.created`, `card.updated`, `card.frozen`, `card.canceled`, `card_application.created`, `card_application.updated`, `card_application.approved`, `card_application.denied`, `course_lesson_interaction.completed`, `payout_method.created`, `verification.succeeded`, `identity_profile.approved`, `identity_profile.rejected`, `identity_profile.needs_action`, `identity_profile.updated`, `payout_account.status_updated`, `resolution_center_case.created`, `resolution_center_case.updated`, `resolution_center_case.decided`, `product.created`, `product.updated`, `product.deleted`, `product.published`, `product.unpublished`, `plan.created`, `plan.updated`, `plan.deleted`, `shipment.created`, `shipment.updated`, `member.created`, `chat.message.created`, `chat.reaction.created`, `payment.created`, `payment.succeeded`, `payment.failed`, `payment.pending`, `dispute.created`, `dispute.updated`, `refund.created`, `refund.updated`, `dispute_alert.created`, `membership.cancel_at_period_end_changed` The unique identifier for the webhook. Example: `hook_xxxxxxxxxxxxx` The ID of the resource (company or product) this webhook is attached to. The subset of subscribed event types that support sending test payloads. Available options: `invoice.created`, `invoice.marked_uncollectible`, `invoice.paid`, `invoice.past_due`, `invoice.voided`, `membership.activated`, `membership.deactivated`, `membership.trial_ending_soon`, `entry.created`, `entry.approved`, `entry.denied`, `entry.deleted`, `export.completed`, `export.failed`, `setup_intent.requires_action`, `setup_intent.succeeded`, `setup_intent.canceled`, `ledger_account.funds_available`, `swap.completed`, `deposit.succeeded`, `transfer.created`, `transfer.completed`, `withdrawal.created`, `withdrawal.updated`, `card_transaction.created`, `card_transaction.updated`, `card_transaction.completed`, `card_transaction.declined`, `card_transaction.reversed`, `card.created`, `card.updated`, `card.frozen`, `card.canceled`, `card_application.created`, `card_application.updated`, `card_application.approved`, `card_application.denied`, `course_lesson_interaction.completed`, `payout_method.created`, `verification.succeeded`, `identity_profile.approved`, `identity_profile.rejected`, `identity_profile.needs_action`, `identity_profile.updated`, `payout_account.status_updated`, `resolution_center_case.created`, `resolution_center_case.updated`, `resolution_center_case.decided`, `product.created`, `product.updated`, `product.deleted`, `product.published`, `product.unpublished`, `plan.created`, `plan.updated`, `plan.deleted`, `shipment.created`, `shipment.updated`, `member.created`, `chat.message.created`, `chat.reaction.created`, `payment.created`, `payment.succeeded`, `payment.failed`, `payment.pending`, `dispute.created`, `dispute.updated`, `refund.created`, `refund.updated`, `dispute_alert.created`, `membership.cancel_at_period_end_changed` The destination URL where webhook payloads are delivered via HTTP POST. Example: `https://example.com/path` The secret key used to sign webhook payloads for verification. Include this in your HMAC validation logic. Returned on the create response and to interactive dashboard sessions; empty for API-key and OAuth callers on later reads. Example: `whsec_abc123def456` # Getting started Source: https://docs.whop.com/developer/api/getting-started Start programmatically accepting payments, paying other people, and building businesses. # Use cases 1. Create a checkout configuration 2. Onboard sub-merchants 3. Verify your platform account 4. Programmatically pay out users 5. Generate payout onboarding links for your sub-merchants ```bash Typescript theme={null} pnpm install @whop/sdk ``` ```bash Python theme={null} pip install whop-sdk ``` ```bash Ruby theme={null} gem install whop_sdk ``` Before you begin, follow the [Quickstart](/developer/api/quickstart#create-an-api-key) to create an API key. Debug authentication failures, permission errors, retryable responses, and sandbox/production mismatches. ```python Python theme={null} from whop_sdk import Whop, BadRequestError import random client = Whop( api_key="YOUR_API_KEY", ) your_company_id = "YOUR_COMPANY_ID" # 1. Create a checkout configuration checkout = client.checkout_configurations.create( currency="usd", plan={ "initial_price": 10.0, "plan_type": "one_time", "company_id": your_company_id, "currency": "usd", "payment_method_configuration": { "enabled": [ "crypto", # low fees "us_bank_transfer", # very low fees "apple_pay", # standard cc rates ], "disabled": [ "acss_debit", "affirm", "afterpay_clearpay", "alipay", "alma", "amazon_pay", ], }, }, metadata={ "order_id": "order_12345", }, ) checkout_link = f"https://whop.com/checkout/{checkout.plan.id}" print(f"\n✅ Checkout created → {checkout_link}\n (redirect customers here to pay or embed it)") input("\nPress Enter to continue...") # 2. Onboard sub-merchants to pay them out sub_merchant = client.companies.create( email="merchant@example.com", parent_company_id=your_company_id, title="Acme Merchant Store #" + str(random.randint(1, 200)), # logo=FileAttachment("https://example.com/logo.png"), metadata={ "internal_user_id": "user_12345", "seller_tier": "gold", }, ) print(f"\n✅ Sub-merchant onboarded → {sub_merchant.id}") # 2.5 Verify your platform account (skip if already done) # Your account must be verified to send transfers. print(f"\n🔐 Verify your platform account:\n https://whop.com/payouts/{your_company_id}/verify/") input("\nPress Enter when done...") # 3. Programmatically pay out users while True: try: transfer = client.transfers.create( amount=1.0, currency="usd", origin_id=your_company_id, destination_id=sub_merchant.id, metadata={"reason": "creator_payout"}, ) print(f"\n✅ Transfer complete → {transfer.id}") break except BadRequestError as e: print(f"\n❌ Transfer failed: {e}") input("\nFix the issue above, then press Enter to retry...") # 4. Generate a payout onboarding link for your sub-merchant # Short-lived URL — send to the sub-merchant to complete identity verification and payout setup. account_link = client.account_links.create( company_id=sub_merchant.id, refresh_url="https://yourapp.com/onboarding/refresh", return_url="https://yourapp.com/onboarding/complete", use_case="account_onboarding", ) print(f"\n✅ Send to sub-merchant for payout setup:\n {account_link.url}") ``` ```typescript Typescript theme={null} import Whop from "@whop/sdk"; import * as readline from "node:readline/promises"; const client = new Whop({ apiKey: "YOUR_API_KEY", }); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); const yourCompanyId = "YOUR_COMPANY_ID"; // 1. Create a checkout configuration const checkout = await client.checkoutConfigurations.create({ currency: "usd", plan: { initial_price: 10.0, plan_type: "one_time", company_id: yourCompanyId, currency: "usd", payment_method_configuration: { enabled: [ "crypto", // low fees "us_bank_transfer", // very low fees "apple_pay", // standard cc rates ], disabled: [ "acss_debit", "affirm", "afterpay_clearpay", "alipay", "alma", "amazon_pay", ], }, }, metadata: { order_id: "order_12345", }, }); const checkoutLink = `https://whop.com/checkout/${checkout.plan.id}`; console.log(`\n✅ Checkout created → ${checkoutLink}\n (redirect customers here to pay or embed it)`); await rl.question("\nPress Enter to continue..."); // 2. Onboard sub-merchants to pay them out const subMerchant = await client.companies.create({ email: "merchant@example.com", parent_company_id: yourCompanyId, title: `Acme Merchant Store #${Math.floor(Math.random() * 200) + 1}`, // logo: new File([...], "logo.png"), metadata: { internal_user_id: "user_12345", seller_tier: "gold", }, }); console.log(`\n✅ Sub-merchant onboarded → ${subMerchant.id}`); // 2.5 Verify your platform account (skip if already done) // Your account must be verified to send transfers. console.log(`\n🔐 Verify your platform account:\n https://whop.com/payouts/${yourCompanyId}/verify/`); await rl.question("\nPress Enter when done..."); // 3. Programmatically pay out users while (true) { try { const transfer = await client.transfers.create({ amount: 1.0, currency: "usd", origin_id: yourCompanyId, destination_id: subMerchant.id, metadata: { reason: "creator_payout" }, }); console.log(`\n✅ Transfer complete → ${transfer.id}`); break; } catch (err) { if (err instanceof Whop.BadRequestError) { console.log(`\n❌ Transfer failed: ${err.message}`); await rl.question("\nFix the issue above, then press Enter to retry..."); continue; } throw err; } } // 4. Generate a payout onboarding link for your sub-merchant // Short-lived URL — send to the sub-merchant to complete identity verification and payout setup. const accountLink = await client.accountLinks.create({ company_id: subMerchant.id, refresh_url: "https://yourapp.com/onboarding/refresh", return_url: "https://yourapp.com/onboarding/complete", use_case: "account_onboarding", }); console.log(`\n✅ Send to sub-merchant for payout setup:\n ${accountLink.url}`); rl.close(); ``` ```ruby Ruby theme={null} require "whop_sdk" whop = WhopSDK::Client.new( api_key: "YOUR_API_KEY", ) your_company_id = "YOUR_COMPANY_ID" # 1. Create a checkout configuration checkout = whop.checkout_configurations.create( currency: "usd", plan: { initial_price: 10.0, plan_type: "one_time", company_id: your_company_id, currency: "usd", payment_method_configuration: { enabled: [ "crypto", # low fees "us_bank_transfer", # very low fees "apple_pay", # standard cc rates ], disabled: [ "acss_debit", "affirm", "afterpay_clearpay", "alipay", "alma", "amazon_pay", ], }, }, metadata: { order_id: "order_12345", }, ) checkout_link = "https://whop.com/checkout/#{checkout.plan.id}" puts "\n✅ Checkout created → #{checkout_link}\n (redirect customers here to pay or embed it)" print "\nPress Enter to continue..." gets # 2. Onboard sub-merchants to pay them out sub_merchant = whop.companies.create( email: "merchant@example.com", parent_company_id: your_company_id, title: "Acme Merchant Store ##{rand(1..200)}", metadata: { internal_user_id: "user_12345", seller_tier: "gold", }, ) puts "\n✅ Sub-merchant onboarded → #{sub_merchant.id}" # 2.5 Verify your platform account (skip if already done) # Your account must be verified to send transfers. puts "\n🔐 Verify your platform account:\n https://whop.com/payouts/#{your_company_id}/verify/" print "\nPress Enter when done..." gets # 3. Programmatically pay out users loop do begin transfer = whop.transfers.create( amount: 1.0, currency: "usd", origin_id: your_company_id, destination_id: sub_merchant.id, metadata: { reason: "creator_payout" }, ) puts "\n✅ Transfer complete → #{transfer.id}" break rescue WhopSDK::Errors::BadRequestError => e puts "\n❌ Transfer failed: #{e.message}" print "\nFix the issue above, then press Enter to retry..." gets end end # 4. Generate a payout onboarding link for your sub-merchant # Short-lived URL — send to the sub-merchant to complete identity verification and payout setup. account_link = whop.account_links.create( company_id: sub_merchant.id, refresh_url: "https://yourapp.com/onboarding/refresh", return_url: "https://yourapp.com/onboarding/complete", use_case: "account_onboarding", ) puts "\n✅ Send to sub-merchant for payout setup:\n #{account_link.url}" ``` # API Keys Use Account API keys when you only want to fetch data or perform actions for your own Account and [connected accounts](/supported-business-models/platforms). 1. Follow the [Quickstart API key steps](/developer/api/quickstart#create-an-api-key) and open **Account API Keys**. 2. Click the "Create" button in the "Account API Keys" section 3. Give your api key a name. For example "Data pipeline" or "GHL Integration" 4. Select a role or a custom set of permissions. (You can always update this later and add more if you need) 5. Create the api key, and copy it from the modal. Use app API keys when you are building an app and need to access data on companies that have installed your app. 1. Follow the [Quickstart API key steps](/developer/api/quickstart#create-an-api-key) and open **Apps**. 2. Click the **Create app** button and give your app a name. *You can change this name later.* 3. Your API key is the hidden text after `WHOP_API_KEY` in the `Environment variables` section. Use the reveal button to show the key, copy it and keep it in a safe place. You will need it to make API calls. Use OAuth tokens when you want users to sign in with their Whop account and grant your app permission to act on their behalf. Unlike API keys which use your app's permissions, OAuth tokens are scoped to what each individual user can access. Common use cases: * "Sign in with Whop" authentication * Accessing a user's memberships, purchases, or profile * Performing actions as a specific user (not as your app) OAuth tokens are obtained through the OAuth 2.1 + PKCE flow: 1. Redirect users to Whop's authorization page 2. User logs in and approves your requested scopes 3. Exchange the authorization code for access and refresh tokens 4. Use the access token as your API key in SDK calls or the `Authorization` header See the [OAuth guide](/developer/guides/oauth) for full implementation details. # Making API calls Our public api is available at `https://api.whop.com/api/v1` You can test the api by using curl to fetch your public user profile data: ```bash theme={null} # replace "j" with your own whop username curl https://api.whop.com/api/v1/users/j ``` To make authenticated requests you need to include your API key in the `Authorization` header using the `Bearer` scheme: ```bash theme={null} # replace "YOUR_API_KEY" with your real API key curl https://api.whop.com/api/v1/payments?company_id=biz_xxxxxxxxxxx \ -H "Authorization: Bearer YOUR_API_KEY" ``` # SDK Reference * [Typescript / Javascript](https://npmjs.com/package/@whop/sdk) / [Docs](https://github.com/whopio/whopsdk-typescript) * [Python](https://pypi.org/project/whop-sdk) / [Docs](https://github.com/whopio/whopsdk-python) * [Ruby](https://rubygems.org/gems/whop-sdk) / [Docs](https://github.com/whopio/whopsdk-ruby) ## MCP You can also access the API via our mcp server available at `https://mcp.whop.com/mcp` (cursor) or `https://mcp.whop.com/sse` (claude) [Learn more here](/developer/guides/ai_and_mcp) # Quickstart Source: https://docs.whop.com/developer/api/quickstart Create your Whop account, find the dashboard, get an API key, make your first SDK call, and test a webhook. Use this page the first time you connect Whop to your app or backend. You'll sign up, open the dashboard, create an API key, install the SDK, make your first call, and watch a webhook land on your server. Keep `WHOP_API_KEY` on your server. Do not put Account API keys in browser code, mobile apps, or public repositories. ## Set up your account Go to [whop.com/new](https://whop.com/new) and create your Whop account. The onboarding flow creates your first business, which is the Account that owns API keys, products, webhooks, and payments. After onboarding, open [whop.com/dashboard](https://whop.com/dashboard). If you have more than one business, choose the one you want to build against from the business switcher. Click **Dashboard ↗** in the top-right corner of these docs to open your developer dashboard directly. ## Create an API key For the quickest path, create an Account API key. Use this when your server acts on behalf of your own business. Building a Whop App? Learn when to use [App API keys](/developer/api/getting-started#app-api-keys) and [OAuth tokens](/developer/guides/oauth). In **Account API Keys**, click **Create**. Name the key something you can recognize later, like `Local development` or `Production payments`. For the first SDK call below, use the Admin role or grant the read permissions listed on [Retrieve Requesting Account](/api-reference/beta/accounts/retrieve-requesting-account). For production, switch to a narrower custom permission set once you know exactly which endpoints you use. Copy the key when Whop shows it. Store it in your local `.env` file as `WHOP_API_KEY`. Whop dashboard Account API Keys section showing a key name, masked value, and Create button ## Install the SDK ```bash TypeScript theme={null} pnpm add @whop/sdk ``` ```bash Python theme={null} pip install whop-sdk ``` ```bash Ruby theme={null} gem install whop_sdk ``` Add your credentials to `.env`: ```bash theme={null} WHOP_API_KEY=whop_xxxxxxxxxxxxxxxxx ``` ## Make your first call Retrieve the Account tied to your API key. This confirms your key and permissions are wired correctly and prints your Account ID, which starts with `biz_`. ```typescript TypeScript theme={null} import Whop from "@whop/sdk"; const apiKey = process.env.WHOP_API_KEY; if (!apiKey) { throw new Error("Set WHOP_API_KEY"); } const client = new Whop({ apiKey, }); const account = await client.accounts.me(); console.log(account.id); ``` ```python Python theme={null} import os from whop_sdk import Whop client = Whop( api_key=os.environ["WHOP_API_KEY"], ) account = client.accounts.me() print(account.id) ``` ```ruby Ruby theme={null} require "whop_sdk" whop = WhopSDK::Client.new( api_key: ENV.fetch("WHOP_API_KEY"), ) account = whop.accounts.me puts account.id ``` ## See a webhook Whop sends a webhook to your server when something happens in your business, like `payment.succeeded` or `membership.activated`. Add a `POST` endpoint in your app and expose it with ngrok, Cloudflare Tunnel, or another HTTPS tunnel while developing. Open **Developer > Webhooks**, then click **Create webhook**. Whop Developer Webhooks page with a Create webhook button Paste your HTTPS endpoint, keep the API version on `v1`, and select the events you want to receive. Create webhook form showing the endpoint URL and API version fields Create webhook form showing payment_succeeded selected in the events list Use the webhook row actions to send a test event. When your server logs the request, your setup is complete. Whop dashboard test webhook menu showing Send event ## Next steps Create checkout links or embedded checkout flows. Verify signatures and handle payment events safely. Explore endpoints, SDK examples, and required permissions. # CLI Source: https://docs.whop.com/developer/cli Install the Whop CLI, sign in, and choose or create the business you want to manage from your terminal. The Whop CLI (`whop`) lets you build and manage your Whop business from the terminal. Deploy apps, create products, set pricing, get shareable checkout links, run ads, and pull your stats — every command also works non-interactively for scripts and AI agents. ## Install ```bash macOS / Linux theme={null} curl -fsSL https://whop.com/install.sh | sh ``` ```bash Homebrew theme={null} brew install whopio/tap/whop ``` ```bash npm theme={null} npm install -g @whop/cli ``` Prebuilt binaries cover macOS and Linux. On other platforms, install via npm (requires Node.js 22 or later). Confirm it works: ```bash theme={null} whop --version ``` ## Get started Run the CLI with no arguments: ```bash theme={null} whop ``` That's it — it signs you in through your browser and lets you choose or create the business the CLI should use. Run `whop quickstart` later to select a different business or create another one. Then use `whop --help` to choose a workflow, such as deploying an app with `whop apps deploy` or managing products and pricing directly. ## Everyday commands ```bash theme={null} whop --help # all commands whop products list # what you're selling whop plans create --help # options for any command whop checkout-configurations create --plan_id plan_xxx # shareable checkout link whop stats time_series # your numbers whop accounts get --account_id jordan # retrieve a business by route ``` Every command takes `--format json` for structured output, and most groups follow the same shape: `whop list|get|create|update`. Account-scoped commands use the selected business by default. Pass another business's `biz_` ID or public route with `--account_id`. | Command group | What it manages | | ------------------------------------- | ----------------------------------------------------------- | | `products`, `plans` | The things you sell and their pricing | | `checkout-configurations` | Shareable, prefilled checkout links | | `members`, `memberships` | Who bought from you, and the access they hold | | `payouts`, `transfers`, `ledgers` | Moving money and reading balances | | `disputes`, `resolution-center-cases` | Chargebacks and buyer–merchant cases | | `stats`, `exports` | Financial time series, and CSV dumps of any dashboard table | | `notifications` | The user's feed, and sends from your app | | `apps` | Fully-hosted web apps on `*.whop.app` | | `ads`, `ad-campaigns`, `ad-groups` | Paid acquisition | | `auth` | Profiles, switching accounts, API keys | ## Deploy an app ```bash theme={null} whop apps deploy ``` One command verifies the current directory is a Whop-ready Vite app — offering to scaffold a new one or link an existing app if not — then builds, typechecks, uploads, and promotes the build to production. Pass `--skip_promote` to upload a preview build and `whop apps builds promote ` to ship it later. After a deploy, read your app's server logs — every `console.log`, uncaught exception, and failed request, kept for 7 days: ```bash theme={null} whop apps logs # recent logs for the linked app whop apps logs --level error --since 1h whop apps logs --query "checkout" ``` ## Use it with AI agents The CLI is self-describing, so agents can discover and drive every command: ```bash theme={null} whop --llms # machine-readable manifest of all commands whop mcp add # automatically register with supported coding agents whop skills add # generate agent skills ``` For non-interactive use — CI, scripts, or headless agents — set `WHOP_API_KEY` instead of logging in. For API commands, it takes precedence over any saved CLI profile for that invocation. Create a key under **Developer → API keys** in your [dashboard](https://whop.com/dashboard). ```bash theme={null} WHOP_API_KEY=whop_xxx whop products list --format json ``` ## Update The CLI keeps itself up to date in the background. To update immediately: ```bash theme={null} whop upgrade ``` # Accept payments Source: https://docs.whop.com/developer/guides/accept-payments Accept one-time and recurring payments across 195 countries with 100+ payment methods