Variants

Retrieve Variant

Retrieves the details of an existing variant.

get/variants/{id}

Response

variant retrieved

adaptive_pricing_enabledboolean required

Whether adaptive pricing is enabled for this variant. Raw setting — does not check processor compatibility or feature flags.

attributesobject nullable required

Attribute values that distinguish this variant within its product, as a map of attribute name to value, e.g. {"color": "Blue", "size": "Large"}. Names are snake_case identifiers and come back in alphabetical order. Every attributed variant on a product carries the same attribute names and a distinct set of values; the product lists the full option set as variant_attributes. null when the variant has no attributes.

billing_periodnumber nullable required

Number of days between recurring charges, such as 30 for monthly or 365 for annual. null for one-time variants.

cancel_discount_intervalsnumber nullable required

Billing intervals the cancellation discount applies to (0 forever, 1 first payment, or a month count). null when none is offered or the actor lacks the plan:basic:read scope.

cancel_discount_percentagenumber nullable required

Cancellation discount as a whole-number percentage. null when none is offered or the actor lacks the plan:basic:read scope.

checkout_stylingobject nullable required

Variant-level checkout styling (background_color, button_color, font_family, border_style); null inherits the account default.

collect_taxboolean required

Whether tax is collected on purchases of this variant, based on the account's tax configuration.

created_atstring required

When the variant was created, as an ISO 8601 timestamp.

currencystring required

Three-letter ISO currency code for this variant's prices.

deletableboolean nullable required

Whether the variant can be deleted (it has no memberships or waitlist entries). null unless the actor has the plan:basic:read scope on the variant's account.

descriptionstring nullable required

Customer-visible variant description. Maximum 1000 characters. null if no description is set.

expiration_daysnumber nullable required

Access duration in days for expiration-based variants, such as 365 for a one-year pass. null for variants without an expiration.

formatted_pricestring required

Human-readable price for display (currency + interval), e.g. "$10 / month".

idstring required

Variant ID, prefixed plan_.

imageobject nullable required

Pricing-tier image (url, blurhash) shown on the product page; null when no image is set.

initial_pricenumber required

Initial purchase price in variant currency.

internal_notesstring nullable required

Private notes not shown to customers. null unless the actor has the plan:basic:read scope on the variant's account.

invoiceobject nullable required

Invoice this variant was generated for; null unless created for an invoice.

member_countnumber nullable required

Active memberships through this variant. null unless the actor has the plan:basic:read scope on the variant's account.

metadataobject nullable required

Custom key-value pairs stored on the variant. Included in webhook payloads for payment and membership events. Maximum 50 keys, 100 characters per key, 500 characters per value. The reserved keys custom_cta and custom_cta_url, when set, override the product's checkout call to action for this variant.

offer_cancel_discountboolean nullable required

Whether a cancellation discount is offered. null unless the actor has the plan:basic:read scope on the variant's account.

payment_method_configurationobject nullable required

Payment method configuration (enabled, disabled, include_platform_defaults); null when variant uses default settings.

plan_type'renewal' | 'one_time' required

Billing model for this variant.

productobject nullable required

Product this variant belongs to; null for standalone variants.

purchase_urlstring required

URL where customers can purchase this variant directly.

release_method'buy_now' | 'waitlist' required

Sales method for this variant.

renewal_pricenumber required

Recurring price charged every billing period.

skustring nullable required

Stock keeping unit, free text set by the seller (e.g. TSHIRT-LARGE-BLUE). Not enforced unique. null when unset.

split_pay_required_paymentsnumber nullable required

Installment payments required before the subscription pauses. Must be greater than 1. null if split pay is not configured.

stocknumber nullable required

Units available for purchase. null unless the actor has the plan:basic:read scope on the variant's account.

strike_through_initial_pricenumber nullable required

Original initial price shown with a strikethrough, in the variant's currency. null when no strikethrough is set.

strike_through_renewal_pricenumber nullable required

Original renewal price shown with a strikethrough, in the variant's currency. null when no strikethrough is set.

tax_type'inclusive' | 'exclusive' | 'unspecified' required

How tax is handled for this variant, including whether tax is included in the price, added at checkout, or not configured.

three_ds_level'mandate_challenge' | 'mandate_if_required' | 'frictionless_if_required' | 'null' nullable required

3D Secure behavior for supported on-session card payments. mandate_challenge requires a 3DS challenge before payment processing; mandate_if_required mandates a challenge only when the payment processor requires it; frictionless_if_required uses the regular frictionless 3DS flow. Payments of $1,000 or more use mandate_if_required unless mandate_challenge is selected. Risk and authentication recovery requirements can override the preference. null inherits the account default.

titlestring nullable required

Variant display name shown to customers. Maximum 30 characters. A variant created without one defaults to its attribute values joined with /. null if no title has been set.

trial_period_daysnumber nullable required

Free trial days before the first renewal charge. null if no trial is configured or the user has already used a trial for this variant.

unlimited_stockboolean required

Whether the variant has unlimited stock. When true, the stock field is ignored; waitlist variants always report true.

updated_atstring required

When the variant was last updated, as an ISO 8601 timestamp.

visibility'visible' | 'hidden' | 'archived' | 'quick_link' required

Controls where this variant can be seen. When hidden, the variant is reachable only by its direct link.

Example response

{
  "account": {
    "id": "biz_xxxxxxxxxxxxxx",
    "title": "Shine Time Auto Detailing"
  },
  "adaptive_pricing_enabled": true,
  "attributes": {
    "color": "Blue",
    "size": "Large"
  },
  "billing_period": 30,
  "cancel_discount_intervals": 3,
  "cancel_discount_percentage": 20,
  "checkout_styling": {
    "background_color": "#0f172a",
    "border_style": "rounded",
    "button_color": "#f59e0b",
    "font_family": "roboto"
  },
  "created_at": "2026-01-01T12:00:00.000Z",
  "currency": "usd",
  "custom_fields": [
    {
      "field_type": "text",
      "id": "field_xxxxxxxxxxxxxx",
      "name": "Vehicle make and model",
      "placeholder": "2021 Audi S5",
      "required": true
    }
  ],
  "deletable": true,
  "description": "Two hand washes a month, interior vacuum, and a quarterly sealant top-up.",
  "effective_payment_method_configuration": {
    "disabled": [
      "card"
    ],
    "enabled": [
      "card"
    ],
    "include_platform_defaults": true
  },
  "expiration_days": 365,
  "formatted_price": "$59.00 / month",
  "id": "plan_xxxxxxxxxxxxxx",
  "image": {
    "blurhash": "LA6bDXT$E3b:R6i+RibEIWbp%ej1",
    "url": "https://whop-assets-example.s3.amazonaws.com/uploads/image/2026-01-01/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  "initial_price_due": {
    "amount": "-1234.56",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "internal_notes": "Maintenance tier. Upsell the interior shampoo add-on at renewal.",
  "invoice": {
    "id": "inv_xxxxxxxxxxxxxx"
  },
  "metadata": {
    "custom_cta": "subscribe",
    "custom_cta_url": "https://shinetime.example/wash-club"
  },
  "offer_cancel_discount": true,
  "payment_method_configuration": {
    "disabled": [
      "crypto"
    ],
    "enabled": [
      "card"
    ],
    "include_platform_defaults": true
  },
  "plan_type": "renewal",
  "product": {
    "id": "prod_xxxxxxxxxxxxxx",
    "title": "Ceramic Coating Package"
  },
  "purchase_url": "https://whop.com/checkout/plan_xxxxxxxxxxxxxx",
  "release_method": "buy_now",
  "renewal_price": 59,
  "sku": "WASH-CLUB-TEE-LARGE-BLUE",
  "split_pay_required_payments": 4,
  "strike_through_initial_price": 99,
  "strike_through_renewal_price": 79,
  "tax_type": "unspecified",
  "three_ds_level": "frictionless_if_required",
  "title": "Unlimited Wash Club",
  "trial_period_days": 7,
  "updated_at": "2026-01-01T12:00:00.000Z",
  "visibility": "visible"
}

Changes

Changed in 1 of the 77 revisions of this API.1

Of the 77 revisions, 1 has no diff computed.