openapi: 3.0.3
info:
title: Whop REST API (v1)
description: >-
The Whop REST API (v1) is the current primary REST surface for the Whop
digital-products / memberships / creator-commerce platform. It lets
applications manage memberships and access, products (access passes) and
their pricing plans, take payments and issue refunds, manage users and
companies, build checkout flows, pay out users via transfers, and register
webhooks. All requests are authenticated with a Bearer token
(`Authorization: Bearer <API_KEY>`); a Company/Account API key and an App
API key are the two key types, with OAuth tokens used when acting on behalf
of a signed-in Whop user.
Grounding notes: base URLs, the Bearer scheme, the `List memberships` and
`List payments` query parameters and response fields, and the resource /
operation catalog are taken from Whop's published documentation at
docs.whop.com (see the docs `llms.txt` index). Individual action sub-paths
(for example the cancel / pause / resume membership actions) are modeled
from the documented operation names; verify exact path segments against the
live reference on reconciliation.
version: '1.0'
contact:
name: API Evangelist
email: kin@apievangelist.com
url: https://apievangelist.com
license:
name: API documentation - Whop Terms of Service
url: https://whop.com/terms-of-service/
servers:
- url: https://api.whop.com/api/v1
description: Production
- url: https://sandbox-api.whop.com/api/v1
description: Sandbox
security:
- bearerAuth: []
tags:
- name: Memberships
description: A user's access to a product; lifecycle and access management.
- name: Products
description: Products (access passes) that companies sell.
- name: Plans
description: Pricing plans attached to products.
- name: Payments
description: Charges, refunds, retries, and voids.
- name: Users
description: Whop users and their access checks.
- name: Companies
description: Seller companies (whops) and sub-merchant onboarding.
- name: Checkout Configurations
description: Reusable checkout / payment flow configurations.
- name: Transfers
description: Programmatic payouts to users and connected accounts.
- name: Webhooks
description: Webhook endpoint registration for platform events.
- name: Promo Codes
description: Discount / promo codes applied at checkout.
paths:
/memberships:
get:
operationId: listMemberships
tags: [Memberships]
summary: List memberships
description: >-
Returns a cursor-paginated list of memberships. `company_id` is required
when authenticating with an API key.
parameters:
- { name: after, in: query, schema: { type: string }, description: Cursor for forward pagination. }
- { name: before, in: query, schema: { type: string }, description: Cursor for backward pagination. }
- { name: first, in: query, schema: { type: integer }, description: Return the first n elements. }
- { name: last, in: query, schema: { type: integer }, description: Return the last n elements. }
- { name: company_id, in: query, schema: { type: string }, description: Filter by company; required for API keys. }
- { name: direction, in: query, schema: { type: string, enum: [asc, desc] }, description: Sort direction. }
- name: order
in: query
schema: { type: string, enum: [id, created_at, status, canceled_at, date_joined, total_spend] }
description: Sort field.
- { name: product_ids, in: query, schema: { type: array, items: { type: string } }, description: Filter by product identifiers. }
- { name: plan_ids, in: query, schema: { type: array, items: { type: string } }, description: Filter by plan identifiers. }
- { name: user_ids, in: query, schema: { type: array, items: { type: string } }, description: Filter by user identifiers. }
- { name: statuses, in: query, schema: { type: array, items: { type: string } }, description: Filter by membership status. }
- { name: cancel_options, in: query, schema: { type: array, items: { type: string } }, description: Filter by cancellation reason. }
- { name: promo_code_ids, in: query, schema: { type: array, items: { type: string } }, description: Filter by applied promo codes. }
- { name: created_before, in: query, schema: { type: string, format: date-time } }
- { name: created_after, in: query, schema: { type: string, format: date-time } }
responses:
'200':
description: A page of memberships.
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: { $ref: '#/components/schemas/Membership' }
page_info: { $ref: '#/components/schemas/PageInfo' }
'401': { $ref: '#/components/responses/Unauthorized' }
/memberships/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string }, description: The membership ID. }
get:
operationId: retrieveMembership
tags: [Memberships]
summary: Retrieve a membership
responses:
'200':
description: A membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
'401': { $ref: '#/components/responses/Unauthorized' }
'404': { $ref: '#/components/responses/NotFound' }
post:
operationId: updateMembership
tags: [Memberships]
summary: Update a membership
description: Update mutable fields on a membership (for example metadata).
requestBody:
content: { application/json: { schema: { type: object, additionalProperties: true } } }
responses:
'200':
description: The updated membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
'401': { $ref: '#/components/responses/Unauthorized' }
/memberships/{id}/add_free_days:
post:
operationId: addFreeDaysMembership
tags: [Memberships]
summary: Add free days to a membership
description: >-
Extends the current renewal period by a number of free days. Path
segment modeled from the documented `add-free-days` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
requestBody:
content: { application/json: { schema: { type: object, properties: { days: { type: integer } }, required: [days] } } }
responses:
'200':
description: The updated membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
/memberships/{id}/cancel:
post:
operationId: cancelMembership
tags: [Memberships]
summary: Cancel a membership
description: Cancels a membership immediately or at period end. Path segment modeled from the documented `cancel` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The canceled membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
/memberships/{id}/uncancel:
post:
operationId: uncancelMembership
tags: [Memberships]
summary: Uncancel a membership
description: Reverses a scheduled cancellation. Path segment modeled from the documented `uncancel` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
/memberships/{id}/pause:
post:
operationId: pauseMembership
tags: [Memberships]
summary: Pause a membership
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The paused membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
/memberships/{id}/resume:
post:
operationId: resumeMembership
tags: [Memberships]
summary: Resume a membership
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The resumed membership.
content: { application/json: { schema: { $ref: '#/components/schemas/Membership' } } }
/products:
get:
operationId: listProducts
tags: [Products]
summary: List products
parameters:
- { name: company_id, in: query, schema: { type: string }, description: Filter by company; required for API keys. }
- { name: after, in: query, schema: { type: string } }
- { name: before, in: query, schema: { type: string } }
- { name: first, in: query, schema: { type: integer } }
responses:
'200':
description: A page of products.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Product' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createProduct
tags: [Products]
summary: Create a product
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Product' } } }
responses:
'201':
description: The created product.
content: { application/json: { schema: { $ref: '#/components/schemas/Product' } } }
/products/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string }, description: The product ID. }
get:
operationId: retrieveProduct
tags: [Products]
summary: Retrieve a product
responses:
'200':
description: A product.
content: { application/json: { schema: { $ref: '#/components/schemas/Product' } } }
'404': { $ref: '#/components/responses/NotFound' }
post:
operationId: updateProduct
tags: [Products]
summary: Update a product
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Product' } } }
responses:
'200':
description: The updated product.
content: { application/json: { schema: { $ref: '#/components/schemas/Product' } } }
delete:
operationId: deleteProduct
tags: [Products]
summary: Delete a product
responses:
'204': { description: The product was deleted. }
/plans:
get:
operationId: listPlans
tags: [Plans]
summary: List plans
parameters:
- { name: company_id, in: query, schema: { type: string } }
- { name: product_ids, in: query, schema: { type: array, items: { type: string } } }
responses:
'200':
description: A page of plans.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Plan' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createPlan
tags: [Plans]
summary: Create a plan
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Plan' } } }
responses:
'201':
description: The created plan.
content: { application/json: { schema: { $ref: '#/components/schemas/Plan' } } }
/plans/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrievePlan
tags: [Plans]
summary: Retrieve a plan
responses:
'200':
description: A plan.
content: { application/json: { schema: { $ref: '#/components/schemas/Plan' } } }
post:
operationId: updatePlan
tags: [Plans]
summary: Update a plan
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Plan' } } }
responses:
'200':
description: The updated plan.
content: { application/json: { schema: { $ref: '#/components/schemas/Plan' } } }
delete:
operationId: deletePlan
tags: [Plans]
summary: Delete a plan
responses:
'204': { description: The plan was deleted. }
/plans/{id}/calculate_tax:
post:
operationId: calculateTax
tags: [Plans]
summary: Calculate tax for a plan
description: Estimates tax for a plan at a given billing address. Path segment modeled from the documented `calculate-tax` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
requestBody:
content: { application/json: { schema: { type: object, additionalProperties: true } } }
responses:
'200':
description: Tax calculation result.
content: { application/json: { schema: { type: object, additionalProperties: true } } }
/payments:
get:
operationId: listPayments
tags: [Payments]
summary: List payments
parameters:
- { name: after, in: query, schema: { type: string } }
- { name: before, in: query, schema: { type: string } }
- { name: first, in: query, schema: { type: integer } }
- { name: last, in: query, schema: { type: integer } }
- { name: company_id, in: query, schema: { type: string } }
- { name: direction, in: query, schema: { type: string, enum: [asc, desc] } }
- { name: order, in: query, schema: { type: string, enum: [final_amount, created_at, paid_at] } }
- { name: product_ids, in: query, schema: { type: array, items: { type: string } } }
- { name: plan_ids, in: query, schema: { type: array, items: { type: string } } }
- { name: statuses, in: query, schema: { type: array, items: { type: string } } }
- { name: substatuses, in: query, schema: { type: array, items: { type: string } } }
- { name: billing_reasons, in: query, schema: { type: array, items: { type: string } } }
- { name: currencies, in: query, schema: { type: array, items: { type: string } } }
- { name: created_before, in: query, schema: { type: string, format: date-time } }
- { name: created_after, in: query, schema: { type: string, format: date-time } }
- { name: query, in: query, schema: { type: string }, description: Search by user ID, email, name, or username. }
- { name: include_free, in: query, schema: { type: boolean }, description: Include zero-amount payments. }
responses:
'200':
description: A page of payments.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Payment' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createPayment
tags: [Payments]
summary: Create a payment
description: Charge a saved payment method off-session for a member.
requestBody:
content: { application/json: { schema: { type: object, additionalProperties: true } } }
responses:
'201':
description: The created payment.
content: { application/json: { schema: { $ref: '#/components/schemas/Payment' } } }
/payments/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrievePayment
tags: [Payments]
summary: Retrieve a payment
responses:
'200':
description: A payment.
content: { application/json: { schema: { $ref: '#/components/schemas/Payment' } } }
/payments/{id}/refund:
post:
operationId: refundPayment
tags: [Payments]
summary: Refund a payment
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The refunded payment.
content: { application/json: { schema: { $ref: '#/components/schemas/Payment' } } }
/payments/{id}/retry:
post:
operationId: retryPayment
tags: [Payments]
summary: Retry a failed payment
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The payment.
content: { application/json: { schema: { $ref: '#/components/schemas/Payment' } } }
/payments/{id}/void:
post:
operationId: voidPayment
tags: [Payments]
summary: Void a payment
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: The voided payment.
content: { application/json: { schema: { $ref: '#/components/schemas/Payment' } } }
/users:
get:
operationId: listUsers
tags: [Users]
summary: List users
parameters:
- { name: company_id, in: query, schema: { type: string } }
- { name: after, in: query, schema: { type: string } }
- { name: first, in: query, schema: { type: integer } }
responses:
'200':
description: A page of users.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/User' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
/users/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrieveUser
tags: [Users]
summary: Retrieve a user
responses:
'200':
description: A user.
content: { application/json: { schema: { $ref: '#/components/schemas/User' } } }
post:
operationId: updateUser
tags: [Users]
summary: Update a user
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/User' } } }
responses:
'200':
description: The updated user.
content: { application/json: { schema: { $ref: '#/components/schemas/User' } } }
/users/{id}/check_access:
get:
operationId: checkUserAccess
tags: [Users]
summary: Check user access
description: >-
Checks whether a user has access to a given access pass / experience.
Path segment modeled from the documented `check-user-access` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: access_pass_id, in: query, schema: { type: string } }
- { name: experience_id, in: query, schema: { type: string } }
responses:
'200':
description: Access check result.
content:
application/json:
schema:
type: object
properties:
has_access: { type: boolean }
access_level: { type: string }
/companies:
get:
operationId: listCompanies
tags: [Companies]
summary: List companies
responses:
'200':
description: A page of companies.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Company' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createCompany
tags: [Companies]
summary: Create a company
description: Onboard a sub-merchant company under a platform account.
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Company' } } }
responses:
'201':
description: The created company.
content: { application/json: { schema: { $ref: '#/components/schemas/Company' } } }
/companies/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrieveCompany
tags: [Companies]
summary: Retrieve a company
responses:
'200':
description: A company.
content: { application/json: { schema: { $ref: '#/components/schemas/Company' } } }
post:
operationId: updateCompany
tags: [Companies]
summary: Update a company
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Company' } } }
responses:
'200':
description: The updated company.
content: { application/json: { schema: { $ref: '#/components/schemas/Company' } } }
/companies/{id}/api_keys:
post:
operationId: createChildCompanyApiKey
tags: [Companies]
summary: Create a child company API key
description: Mints an API key for a sub-merchant company. Path segment modeled from the documented `create-child-company-api-key` operation.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'201':
description: The created API key.
content:
application/json:
schema:
type: object
properties:
id: { type: string }
api_key: { type: string }
/checkout_configurations:
get:
operationId: listCheckoutConfigurations
tags: [Checkout Configurations]
summary: List checkout configurations
responses:
'200':
description: A page of checkout configurations.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/CheckoutConfiguration' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createCheckoutConfiguration
tags: [Checkout Configurations]
summary: Create a checkout configuration
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/CheckoutConfiguration' } } }
responses:
'201':
description: The created checkout configuration.
content: { application/json: { schema: { $ref: '#/components/schemas/CheckoutConfiguration' } } }
/checkout_configurations/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrieveCheckoutConfiguration
tags: [Checkout Configurations]
summary: Retrieve a checkout configuration
responses:
'200':
description: A checkout configuration.
content: { application/json: { schema: { $ref: '#/components/schemas/CheckoutConfiguration' } } }
delete:
operationId: deleteCheckoutConfiguration
tags: [Checkout Configurations]
summary: Delete a checkout configuration
responses:
'204': { description: The checkout configuration was deleted. }
/transfers:
get:
operationId: listTransfers
tags: [Transfers]
summary: List transfers
responses:
'200':
description: A page of transfers.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Transfer' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createTransfer
tags: [Transfers]
summary: Create a transfer
description: Programmatically pay out a user or connected ledger account.
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Transfer' } } }
responses:
'201':
description: The created transfer.
content: { application/json: { schema: { $ref: '#/components/schemas/Transfer' } } }
/transfers/{id}:
get:
operationId: retrieveTransfer
tags: [Transfers]
summary: Retrieve a transfer
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: A transfer.
content: { application/json: { schema: { $ref: '#/components/schemas/Transfer' } } }
/webhooks:
get:
operationId: listWebhooks
tags: [Webhooks]
summary: List webhooks
responses:
'200':
description: A page of webhooks.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Webhook' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createWebhook
tags: [Webhooks]
summary: Create a webhook
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Webhook' } } }
responses:
'201':
description: The created webhook.
content: { application/json: { schema: { $ref: '#/components/schemas/Webhook' } } }
/webhooks/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrieveWebhook
tags: [Webhooks]
summary: Retrieve a webhook
responses:
'200':
description: A webhook.
content: { application/json: { schema: { $ref: '#/components/schemas/Webhook' } } }
post:
operationId: updateWebhook
tags: [Webhooks]
summary: Update a webhook
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/Webhook' } } }
responses:
'200':
description: The updated webhook.
content: { application/json: { schema: { $ref: '#/components/schemas/Webhook' } } }
delete:
operationId: deleteWebhook
tags: [Webhooks]
summary: Delete a webhook
responses:
'204': { description: The webhook was deleted. }
/promo_codes:
get:
operationId: listPromoCodes
tags: [Promo Codes]
summary: List promo codes
responses:
'200':
description: A page of promo codes.
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/PromoCode' } }
page_info: { $ref: '#/components/schemas/PageInfo' }
post:
operationId: createPromoCode
tags: [Promo Codes]
summary: Create a promo code
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/PromoCode' } } }
responses:
'201':
description: The created promo code.
content: { application/json: { schema: { $ref: '#/components/schemas/PromoCode' } } }
/promo_codes/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
operationId: retrievePromoCode
tags: [Promo Codes]
summary: Retrieve a promo code
responses:
'200':
description: A promo code.
content: { application/json: { schema: { $ref: '#/components/schemas/PromoCode' } } }
post:
operationId: updatePromoCode
tags: [Promo Codes]
summary: Update a promo code
requestBody:
content: { application/json: { schema: { $ref: '#/components/schemas/PromoCode' } } }
responses:
'200':
description: The updated promo code.
content: { application/json: { schema: { $ref: '#/components/schemas/PromoCode' } } }
delete:
operationId: deletePromoCode
tags: [Promo Codes]
summary: Delete a promo code
responses:
'204': { description: The promo code was deleted. }
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: Whop API key
description: >-
Bearer token authentication. Use a Company/Account API key or an App API
key in the `Authorization: Bearer <API_KEY>` header. OAuth access tokens
are used when acting on behalf of a signed-in Whop user.
responses:
Unauthorized:
description: Missing or invalid API key.
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }
NotFound:
description: The requested resource was not found.
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }
schemas:
PageInfo:
type: object
description: Cursor pagination metadata.
properties:
has_next_page: { type: boolean }
has_previous_page: { type: boolean }
start_cursor: { type: string, nullable: true }
end_cursor: { type: string, nullable: true }
Error:
type: object
properties:
error: { type: string }
message: { type: string }
Membership:
type: object
description: A user's access to a product. Fields taken from the documented List memberships response.
properties:
id: { type: string }
status:
type: string
description: Lifecycle state (for example active, trialing, past_due, canceled).
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
joined_at: { type: string, format: date-time, nullable: true }
canceled_at: { type: string, format: date-time, nullable: true }
renewal_period_start: { type: string, format: date-time, nullable: true }
renewal_period_end: { type: string, format: date-time, nullable: true }
cancel_at_period_end: { type: boolean }
currency: { type: string }
license_key: { type: string, nullable: true }
manage_url: { type: string, nullable: true }
checkout_configuration_id: { type: string, nullable: true }
metadata: { type: object, additionalProperties: true }
user: { type: object, additionalProperties: true }
member: { type: object, additionalProperties: true }
company: { type: object, additionalProperties: true }
product: { type: object, additionalProperties: true }
plan: { type: object, additionalProperties: true }
Product:
type: object
description: A product (access pass) sold by a company. Fields modeled from the documented Product object.
properties:
id: { type: string }
title: { type: string }
description: { type: string, nullable: true }
route: { type: string, nullable: true }
visibility: { type: string }
member_count: { type: integer }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
company: { type: object, additionalProperties: true }
metadata: { type: object, additionalProperties: true }
Plan:
type: object
description: A pricing plan attached to a product.
properties:
id: { type: string }
product_id: { type: string }
plan_type: { type: string, description: 'For example one_time or renewal.' }
base_currency: { type: string }
initial_price: { type: number }
renewal_price: { type: number, nullable: true }
billing_period: { type: integer, nullable: true, description: Billing period length in days. }
trial_period_days: { type: integer, nullable: true }
visibility: { type: string }
created_at: { type: string, format: date-time }
Payment:
type: object
description: A payment. Fields taken from the documented List payments (PaymentListItem) response.
properties:
id: { type: string }
status: { type: string }
substatus: { type: string, nullable: true }
created_at: { type: string, format: date-time }
updated_at: { type: string, format
# --- truncated at 32 KB (34 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/whop/refs/heads/main/openapi/whop-openapi.yml