# The subscription plan model

Source: https://developers.swell.is/backend-api/subscription-plans/subscriptionp-model

A subscription product is achieved by creating a product with a defined subscription purchase option.

## Fields

- `id` (objectId): Unique identifier for the product.
- `name` (string, required): Human-friendly name of the product.
- `purchase_options` (object): Configuration of one or more purchase options for the product. Can be `standard` for one-time purchases or `subscription` for a subscription plan. Products can support both purchase options simultaneously.
  - `standard` (object): Designates purchase option as a one-time purchase.
    - `id` (objectId): ID of the purchase option.
    - `name` (string, required): The name of the purchase option.
    - `description` (string): A long-form description of the product. May contain HTML or other markup languages.
    - `active` (boolean): Indicates whether the purchase option is available for customers to purchase. Inactive products will not be returned on the [Frontend](https://developers.swell.is/frontend-api/introduction). Default: `false`.
    - `price` (currency): List price used when `sale=false` or `sale_price` is not defined.
    - `sale` (boolean): Indicates whether the product option is on sale. If `true`, the `sale_price` will be used by default when the product is added to a cart.
    - `sale_price` (currency): Sale price used by default when `sale=true`, overriding `price`. Overrides product sale price.
    - `prices` (array of object): Price rules determined by cart quantity or customer account group. Overrides `price` and `sale_price` when conditions match.
      - `price` (currency, required): Price applied when conditions are met.
      - `account_group` (string): Customer account group as a condition to apply price.
      - `quantity_max` (int): Maximum quantity as a condition to apply price.
      - `quantity_min` (int): Minimum quantity as a condition to apply price.
    - `account_groups` (array of string): Array of account groups that are eligible to access the purchase option within the storefront.
  - `subscription` (object): Designates purchase option for a subscription plan.
    - `id` (objectId, auto): ID of the subscription plan purchase option.
    - `name` (string, required): Name of the subscription plan purchase option.
    - `description` (string): A long-form description of the purchase option. May contain HTML or other markup languages.
    - `active` (boolean): Indicates whether the purchase option is available for customers to purchase. Inactive products will not be returned on the [Frontend](https://developers.swell.is/frontend-api/introduction). Default: `false`.
    - `account_groups` (array of string): Array of `account_group` names for which the purchase option is available.
    - `plans` (array of plans): Array defining subscription plans and their respective configurations.
      - `id` (objectId): ID of the purchase option subscription plan.
      - `name` (string, required): Name of the subscription plan.
      - `description` (string): A long-form description of the subscription plan. May contain HTML or other markup languages.
      - `active` (boolean): Indicates whether the subscription plan is available for customers to purchase. Inactive products will not be returned on the [Frontend](https://developers.swell.is/frontend-api/introduction). Default: `false`.
      - `price` (currency): List price used when `sale=false` or `sale_price` is not defined.
      - `prices` (array of object): Price rules determined by cart quantity or customer account group. Overrides `price` and `sale_price` when conditions match.
        - `price` (currency, required): Price applied when conditions are met.
        - `account_group` (string): Customer account group as a condition to apply price.
        - `quantity_max` (int): Maximum quantity as a condition to apply price.
        - `quantity_min` (int): Minimum quantity as a condition to apply price.
      - `billing_schedule` (object, required): Determines the billing schedule for the subscription plan.
        - `interval` (enum): Subscription plan billing interval. Can be `daily`, `weekly`, `monthly`, or `yearly`. Possible values: `daily`, `weekly`, `monthly`, `yearly`. Default: `monthly`.
        - `interval_count` (int, required): Multiplier for billing interval. For example, to make the billing cycle once every two weeks, set `interval=weekly` and `interval_count=2`. Default: `1`.
        - `limit` (int): Specifies a limit to the number of billing cycles for the subscription plan. For example, `limit=10` would stop billing the customer after the tenth billing cycle. Default: `∞`.
        - `trial_days` (int): Number of days offered as a free trial on the subscription plan before the customer is billed. If a subscription is canceled by the last day of the trial period, an invoice won't be issued.
- `subscription_interval` (enum): The default billing interval when this product is used as a subscription plan. Can be `monthly`, `yearly`, `weekly`, or `daily`. Possible values: `monthly`, `daily`, `weekly`, `yearly`.
- `subscription_interval_count` (int): Multiplier when combined with `subscription_interval`. For example, to make a subscription bill every two weeks, set `subscription_interval=weekly` and `subscription_interval_count=2`.
- `subscription_trial_days` (int): Number of days offered as a free trial before the customer is billed. If a subscription is canceled by the last day of the trial period, an invoice won't be issued.
- `active` (boolean): Indicates whether the product is active and available in the storefront. Default: `false`.
- `attributes` (object): An object containing custom attribute values, keyed by each attribute's `id`. A value can be a single value or an array.
- `bundle` (boolean): Indicates whether the product is a bundle of other products.
- `bundle_items` (array of object): List of products sold as a bundle. Applicable only when `bundle=true`.
  - `id` (objectId, auto): Unique identifier for the bundle item.
  - `product_id` (objectId, required): ID of the bundled product.
  - `product` (product): Expandable link to the bundled product.
  - `quantity` (int): Quantity of the bundled product. Defaults to 1. Default: `1`.
  - `variant_id` (objectId): ID of the bundled variant, if applicable.
  - `variant` (variant): Expandable link to the bundled product variant, if applicable.
  - `product_name` (string): This field is a copy of the item's `product.name`. Default: `{"$formula": "if(product_id, product.name, null)"}`.
- `category` (Category): Expandable link to the primary category.
- `category_id` (objectId): Primary category, commonly used as a navigation anchor.
- `categories` (Category): Expandable link to all related product categories.
- `category_index` (object): Index of categories used for fast lookup operations.
  - `id` (array of child_scalar): List of related product category IDs.
  - `sort` (object): Index of category IDs and their respective sort positions.
- `code` (string): Unique code to identify the gift card product.
- `cost` (currency): Cost of goods (COGS) used to calculate gross margins.
- `cross_sells` (array of object): List of products to display as cross-sells on a shopping cart page.
  - `id` (objectId, auto): Unique identifier for the cross-sell object.
  - `product_id` (objectId, required): ID of the cross-sell product.
  - `product` (product): Expandable link to the cross-sell product.
  - `discount_type` (enum): Type of discount to apply, either `fixed` or `percent`. Possible values: `fixed`, `percent`.
  - `discount_amount` (currency): Discount to apply as a fixed amount. Applicable only when `discount_type=fixed`.
  - `discount_percent` (float): Discount to apply as a percentage. Applicable only when `discount_type=percent`.
- `currency` (string): Three-letter ISO currency code in uppercase. Defaults to your store's base currency.
- `customizable` (boolean): Indicates whether the product has custom options enabled.
- `date_created` (date, auto): Date and time the product was created.
- `date_updated` (date, auto): Date and time the product was last updated.
- `delivery` (enum, auto): Method of fulfillment automatically assigned based on `type`:

  - `shipment` means the product will be physically shipped to a customer.
  - `subscription` means the product will be fulfilled as a [subscription ](https://developers.swell.is/backend-api/subscriptions/the-subscription-model)when an order is placed. `giftcard` delivery means the product will be fulfilled as a [gift card](https://developers.swell.is/backend-api/pages/the-pages-model) when an order is placed.
  - `null` means the product will not be fulfilled by one of the above methods.

  *Note: A bundle has its child products fulfilled individually; each product in the bundle must have its own fulfillment method.* Possible values: `shipment`, `subscription`, `giftcard`.
- `description` (string): A long-form description of the product. May contain HTML or other markup languages.
- `discontinued` (boolean): Indicates whether the product has been discontinued.
- `images` (array of object): List of images depicting the bundle.
  - `id` (objectId, auto): Unique identifier for the image.
  - `caption` (string): A brief description of the image, intended for display as a caption or alt text.
  - `file` (object): An object representing the image's source file.
    - `id` (objectId): Unique identifier for the file.
    - `filename` (string): Optional file name.
    - `data` (filedata): A reference to the raw file data.
    - `content_type` (string): MIME content type of the file.
    - `date_uploaded` (date): Date the file was uploaded.
    - `height` (int): Image height in pixels, if applicable.
    - `length` (int): Size of the file in bytes.
    - `metadata` (object): A set of arbitrary data that is typically used to store custom values.
    - `md5` (string): An MD5 hash of the file contents. This can be used to uniquely identify the file for caching purposes.
    - `private` (boolean): Indicates whether the file is private.
    - `url` (string): A public URL to reference the file. Updated automatically if file content changes.
    - `width` (int): Image width in pixels, if applicable.
- `meta_title` (string): Page title used to override product name in storefronts.
- `meta_keywords` (string): Page keywords used for search engine optimization purposes.
- `meta_description` (string): Page description used for search engine optimization purposes.
- `options` (array of object): Options that allow for variations of the base product. If the option is part of a variant or `required=true`, an option value must be set for the product to be added to a cart.
  - `id` (objectId, auto): Unique identifier for the object.
  - `name` (string, required): Human-friendly name of the option.
  - `input_hint` (string): Some brief hint text to help the user understand this option.
  - `input_type` (enum): Type of user input to display for this option in a storefront. The *select* type is ideal for dropdown or radio selections, *toggle* can be used either to show another option or as a price modifier, and *text* fields can capture user input like a message. Possible values: `select`, `toggle`, `short_text`, `long_text`, `toggle`.
  - `parent_id` (objectId): Specifies another option ID that affects visibility of this option. The option will only appear when one of the `parent_value_ids` is selected.
  - `parent_value_ids` (array of child_scalar): IDs of parent option values that will make the option appear if selected.
  - `price` (currency): Extra price for the option, added to the product's `price`/`sale_price`. If the option is part of a variant, the variant's `price`/`sale_price` will override this value.
  - `required` (boolean): Indicates whether the option requires a value when the product is added to a cart. Default: `{"$formula":"if(input_type == 'toggle', false, true)"}`.
  - `subscription` (boolean): Indicates whether the option specifies the billing interval of a subscription plan.
  - `values` (array of object): List of possible values for this option.
    - `id` (objectId, auto): Unique identifier for the object.
    - `name` (string, required): Human-friendly name of the option value.
    - `color` (string): Name of the product color.
    - `description` (string): A brief description of the option value, intended for displaying to customers.
    - `price` (currency): Extra price added to the product's `price`/`sale_price` if the option value is selected. Overrides option `price`.
    - `shipment_weight` (float): Extra weight added to the product's `shipment_weight` if the option value is selected. The unit should match the store's default as configured in general settings.
    - `subscription_interval` (enum): When product `type=subscription`, this is the billing interval used when this option value is selected. Can be `monthly`, `yearly`, `weekly`, or `daily`. Possible values: `monthly`, `daily`, `weekly`, `yearly`.
    - `subscription_interval_count` (int): When product `type=subscription`, this number multiplies `subscription_interval` to determine the billing frequency when this option is selected. For example, to make a subscription bill every two weeks, set `subscription_interval=weekly` and `subscription_interval_count=2`.
    - `subscription_trial_days` (int): When product `type=subscription`, refers to a number of days offered as a trial before an invoice is issued.
    - `image` (object): Image depicting the product.
      - `id` (objectId): Unique identifier for the object.
      - `data` (filedata): A reference to the raw file data.
      - `date_uploaded` (date): Date the file was uploaded.
      - `length` (int): Size of the file in bytes.
      - `md5` (string): An MD5 hash of the file contents. This can be used to uniquely identify the file for caching purposes.
      - `filename` (string): Optional file name.
      - `content_type` (string): MIME content type of the file.
      - `metadata` (object): Arbitrary data
      - `private` (boolean)
      - `url` (string)
      - `width` (int)
      - `height` (int)
  - `attribute_id` (string): Unique identifier for the attribute.
  - `active` (boolean): Indicates the options are active. Default: `true`.
  - `input_multi` (boolean): Indicates there are multiple selections for options.
- `orig_price` (currency): Reflects the non-sale price of the product
- `price` (currency): List price used when `sale=false` or `sale_price` is not defined. This value is intended for use via the frontend. See the `purchase_options` array to manage a product's price. Default: `0`.
- `prices` (array of price): Price rules determined by cart quantity or customer account group. Overrides `price` and `sale_price` when conditions match.
  - `price` (currency, required): Price applied when conditions are met.
  - `account_group` (string): Customer account group as a condition to apply price.
  - `quantity_max` (int): Maximum quantity as a condition to apply price.
  - `quantity_min` (int): Minimum quantity as a condition to apply price.
- `quantity_min` (int): Minimum quantity of the product that can be sold at once.
- `quantity_inc` (int): Specifies a quantify multiple the product must be sold in.
- `related_product_ids` (array of child_scalar): Array of related product IDs.
- `sale` (boolean): Indicates whether the product is on sale. If `true`, the `sale_price` will be used by default when the product is added to a cart.
- `sale_price` (currency): Sale price used to override list price when `sale=true`.
- `shipment_dimensions` (object): Product dimensions when packed for shipping. Typically used by third-party carriers in box packing algorithms to optimize shipping costs.
  - `length` (float, required): Length of the product in `unit`.
  - `width` (float, required): Width of the product in `unit`.
  - `height` (float, required): Height of the product in `unit`.
  - `unit` (enum, required): Either `in`(inches) or `cm`(centimeters). Possible values: `in`, `cm`. Default: `"in"`.
- `shipment_location` (string): ID of location from `/settings/shipping/locations`. If specified, shipping is calculated from this location. Otherwise, the store's default location will be used.
- `shipment_package_quantity` (float): If specified, shipping is calculated using this as the maximum number of items per package. Otherwise, Swell assumes any quantity fits into a single package.
- `shipment_prices` (array of object): Product shipping price rules to override default shipping rules.
  - `service` (string, required): Shipping service required for this rule to apply.
  - `account_group` (string): Customer group required for this rule to apply.
  - `country` (string): Shipping country required for this rule to apply.
  - `fee_amount` (currency): Fixed amount to add when rule is applied. Only applicable when `fee_type=fixed`.
  - `fee_percent` (float): Percentage of the shipping price to add when rule is applied. Only applicable when `fee_type=percent`.
  - `fee_type` (enum): Type of fee to apply in addition to `price`, either `fixed` or `percent`. Possible values: `fixed`, `percent`.
  - `package_quantity` (int): Maximum package quantity when rule is applied.
  - `price` (currency): Shipping price when rule is applied.
  - `state` (string): Shipping state required for this rule to apply.
  - `total_max` (currency): Maximum order subtotal for this rule to apply.
  - `total_min` (currency): Minimum order subtotal for this rule to apply.
  - `weight_max` (float): Maximum order item weight for this rule to apply.
  - `weight_min` (float): Minimum order item weight for this rule to apply.
  - `zip` (string): Shipping zip/postal code required for this rule to apply.
- `shipment_weight` (float): If specified, shipping is calculated using this weight. Otherwise, Swell assumes 1 lb/oz/kg—depending on the store's default weight unit.
- `sku` (string): Stock keeping unit (SKU) used to track inventory in a warehouse.
- `slug` (string, required): Lowercase, hyphenated identifier typically used in URLs. When creating a product, a `slug` will be generated automatically from the `name`. Maximum length of 1,000 characters. Default: `{"$formula":"slug(name)"}`.
- `stock` (array of Stock): Expandable list of stock adjustments for the product.
- `stock_backorder` (boolean): Indicates whether the product can be backordered if out of stock.
- `stock_level` (int, auto): Quantity of the product currently in stock (including all variants), based on the sum of the stock entries. Includes positive quantities, excluding variants that have negative stock values.
- `stock_level_in_locations` (int): Quantity of the product in stock across inventory locations, if the product has no variants.
- `stock_level_min` (int, auto): Minimum stock value including all variants. May represent negative variant stock levels.
- `stock_level_total` (int, auto): Sum total of all product stock values.
- `stock_locations` (object): Stock distributed over inventory locations, if multi-location inventory is enabled.
- `available_locations` (array of location): List of custom inventory locations for this product.
  - `id` (string): Location identifier.
  - `name` (string): Location name.
- `stock_preorder` (boolean): Indicates whether the product can be purchased as a preorder.
- `stock_purchasable` (boolean): Indicates whether the product's stock is purchasable.
- `stock_status` (enum, auto): String indicating the product's stock status for the purpose of ordering. When `stock_purchasable=true`, an order can be placed for this product regardless of current stock status. Otherwise an order submission will be blocked unless stock status is `available`, `preorder`, or `backorder`. Possible values: `discontinued`, `preorder`, `backorder`, `out_of_stock`, `in_stock`.
- `stock_tracking` (boolean): Indicates whether the product has stock tracking enabled.
- `summary` (string): A brief product summary.
- `tags` (array of child_scalar): Array of searchable tags to aid in search discoverability.
- `tax_class` (string): Indicates the tax class for the product.
- `tax_code` (string): Product tax code for tracking with Avalara, TaxJar, etc.
- `theme_template` (string): ID of an alternate theme template used to render this product in a storefront, if applicable.
- `type` (string): Implies the ordering and fulfillment options available for the product. Can be `standard`, `subscription`, `bundle`, or `giftcard`. A `standard` product is a physical item that will be shipped to a customer. Default: `"standard"`.
- `up_sells` (array of object): List of products to display as up-sells on a product detail page.
  - `id` (objectId, auto): Unique identifier for the up-sell.
  - `product_id` (objectId, required): ID of the up-sell product.
  - `product` (product): Expandable link to the up-sell product.
- `variable` (boolean): Indicates whether the product has variant generation enabled.
- `variants` (array of Variants): Expandable list of variants representing unique variations of the product. Each variant is a combination of one or more `options`. For example, Size and Color.
- `virtual` (boolean): Indicates whether the product is virtual.

## Example response

```json
{
  "purchase_options": {
    "standard": {
      "active": true,
      "price": 75,
      "sale": true,
      "sale_price": 60,
      "prices": [
        {
          "account_group": "vip",
          "price": 65,
          "quantity_max": null,
          "quantity_min": null,
          "$locale": {
            "en-US": {
              "description": ""
            },
            "ja": {
              "description": ""
            }
          }
        }
      ]
    },
    "subscription": {
      "active": true,
      "plans": [
        {
          "name": "Monthly",
          "description": null,
          "price": 75,
          "billing_schedule": {
            "interval": "monthly",
            "interval_count": 1,
            "limit": null,
            "trial_days": 1
          },
          "id": "62b1e30767145000197b2bc0",
          "active": true,
          "$locale": {
            "en-US": {
              "description": null,
              "name": "Monthly"
            },
            "ja": {
              "description": ""
            }
          }
        }
      ]
    }
  },
  "name": "Skooma",
  "sku": "0004E0A9",
  "active": true,
  "images": [
    {
      "file": {
        "id": "62b1e2b34bf1a70019cbf610",
        "date_uploaded": "2022-06-21T15:24:35.166Z",
        "length": 7024,
        "md5": "4b39c328dc2652792c048d0fd3f8a426",
        "filename": null,
        "content_type": "image/png",
        "metadata": null,
        "url": "https://cdn.schema.io/launch-storefront/62b1e2b34bf1a70019cbf610/4b39c328dc2652792c048d0fd3f8a426",
        "width": 64,
        "height": 64
      },
      "id": "62b1e30767145000197b2bc1",
      "$locale": {
        "en-US": {
          "file": {
            "id": "62b1e2b34bf1a70019cbf610",
            "date_uploaded": "2022-06-21T15:24:35.166Z",
            "length": 7024,
            "md5": "4b39c328dc2652792c048d0fd3f8a426",
            "filename": null,
            "content_type": "image/png",
            "metadata": null,
            "url": "https://cdn.schema.io/launch-storefront/62b1e2b34bf1a70019cbf610/4b39c328dc2652792c048d0fd3f8a426",
            "width": 64,
            "height": 64
          }
        }
      }
    }
  ],
  "cost": 60,
  "variable": false,
  "description": "​Damage Intelligence 2 pts<br>Drain Agility 60 pts for 20 secs<br>Fortify Speed and Strength 60 pts for 20 secs​",
  "tags": [],
  "meta_title": null,
  "meta_description": "Several skooma dealers can be found in and around Cyrodiil, usually in hidden and out of sight spots, such as Shady Sam and Nordinor. A skooma den can also be found right above Carandial's house in Bravil. There is also a skooma smuggling ring led by Dulfish gro-Orum that can be uncovered in Cheydinhal through investigation by the player.",
  "slug": "skooma",
  "attributes": {
    "rooms": [
      "Kitchen"
    ],
    "room_usage": [
      "Kitchen",
      "Dining room",
      "Bedroom",
      "Bathroom",
      "Ballroom"
    ]
  },
  "delivery": "shipment",
  "bundle": null,
  "price": 75,
  "stock_tracking": false,
  "options": [],
  "currency": "USD",
  "type": "standard",
  "tax_class": "standard",
  "date_created": "2022-06-21T15:25:59.518Z",
  "stock_status": null,
  "category_index": {
    "sort": {
      "628bb55d499bba0019b1ab91": 0
    },
    "id": [
      "628bb55d499bba0019b1ab91"
    ]
  },
  "date_updated": "2023-07-22T15:27:54.751Z",
  "popularity": 41,
  "prices": [
    {
      "account_group": "vip",
      "price": 65,
      "quantity_max": null,
      "quantity_min": null,
      "$locale": {
        "en-US": {
          "description": ""
        },
        "ja": {
          "description": ""
        }
      }
    }
  ],
  "sale": true,
  "sale_price": 60,
  "stock_level": -1,
  "engraving": "To my dearest Caedmon, you shall always be the greatest blacksmith",
  "magic_level": 660,
  "your_engraving": "To my dearest Caedmon, you shall always be the greatest blacksmith",
  "content": {
    "your_engraving": "To my dearest Caedmon, you shall always be the greatest blacksmith",
    "enchanted": "nope"
  },
  "cuztomization": {
    "engraving": true,
    "engraving_text": "Get stuffed Mariel"
  },
  "cross_sells": [
    {
      "id": "63628888adb6305fff690058",
      "product_id": "628ba4811869c10019b41f62",
      "discount_type": "fixed",
      "discount_amount": null
    }
  ],
  "up_sells": [
    {
      "id": "63628882adb6305fff690057",
      "product_id": "628ba701499bba0019b1a9bb"
    }
  ],
  "things": [
    {
      "date": "2023-04-13T17:00:00.000Z",
      "log": "Something happened",
      "id": "6437102e171326001374f584"
    }
  ],
  "id": "62b1e30767145000197b2bbf",
  "$locale": {
    "en-US": {
      "name": "Skooma",
      "description": "​Damage Intelligence 2 pts<br>Drain Agility 60 pts for 20 secs<br>Fortify Speed and Strength 60 pts for 20 secs​",
      "tags": [],
      "meta_title": null,
      "meta_description": "Several skooma dealers can be found in and around Cyrodiil, usually in hidden and out of sight spots, such as Shady Sam and Nordinor. A skooma den can also be found right above Carandial's house in Bravil. There is also a skooma smuggling ring led by Dulfish gro-Orum that can be uncovered in Cheydinhal through investigation by the player."
    }
  }
}
```
