Creating a Product
Click Add Product in the Products list to open the quick-create modal. Enter the essential fields (Title, Code, Type, Classification, Price) and click Create product. You are automatically taken to the full Product Detail Page to complete configuration.Product Detail Page
Navigate to the Product Detail Page by clicking any product code or title in the Products list. The page uses a persistent tab layout. Changes are saved by clicking Save in the top toolbar.General Tab
Core product identity, titles, images, descriptions, category assignment, and SEO metadata.| Field | Description |
|---|---|
| Type | Physical, Digital, or Service |
| Code | Unique identifier used in buy links (read-only after creation) |
| Classification | Main, Upsell, Downsell, Bump, or Bonus |
| Status | Active, Draft, or Archived |
| Title | Primary display name |
| Checkout Title | Overrides Title at checkout (optional) |
| Product Image | Primary product image — upload directly from this tab |
| Gallery | Additional product images — upload files directly or remove existing images via the visual thumbnail picker |
| Short Description | Brief summary for product cards and search results |
| Full Description | Rich text or plain text description |
| Category / Subcategory | Assign from brand-level product categories |
| SEO Title | Page title for search engines |
| SEO Slug | URL slug for storefront product pages |
| SEO Description | Meta description (max 160 chars) |
Pricing Tab
Selling price, retail (compare-at) price, currency, and tax settings.| Field | Description |
|---|---|
| Retail Price | Compare-at price shown as strikethrough |
| Discounted Price | Actual selling price |
| Currency | 3-letter currency code (e.g. USD) |
| Tax Exempt | When enabled, no tax is calculated at checkout |
| Tax Category | TaxJar TIC or Avalara tax code |
Subscription Tab
Visible only when This is a subscription product is enabled. See Subscriptions Overview for full billing documentation.| Field | Description |
|---|---|
| Is Subscription | Toggle to enable recurring billing |
| Build-a-Box | Customers select multiple items for their subscription box |
| Billing Frequency | How often to bill (e.g. 1) |
| Frequency Unit | Day / Week / Month / Year |
| Trial Days | Free trial days before first charge |
| First Charge Free | Customer pays shipping only on first order |
| Subscription Tiers | Multiple billing frequencies at different prices (toggle to enable) |
| Subscribe & Save (%) | Discount when customer chooses subscription over one-time purchase |
| Stepped Pricing | Different prices at specific billing cycles (toggle to enable) |
| Prepaid Options | 3, 6, 12-month prepaid discounts |
Fulfillment Tab
Warehousing, inventory, cost breakdown, SKU categorisation, product specifications, and shipping profile.| Section | Fields |
|---|---|
| Identity & Structure | SKU, Barcode, Units per Package, Weight (oz), Dimensions (L/W/H cm) |
| Integration | Fulfillment Integration override, Multiply SKU toggle |
| Inventory | Stock Quantity, Out-of-Stock Policy (continue/deny) |
| Cost Breakdown | Product Cost, Fulfillment Cost, Packaging Cost, Avg. Shipping, Fuel Surcharge, Auto-calculated COGS |
| SKU Categorisation | SKU Category, SKU Subcategory (for internal reporting) |
| Product Specifications | Repeater: Name / Value / Unit pairs (e.g. Dimensions: 10×5×3 cm) |
| Shipping Profile | Assign a brand-level shipping profile |
Merchants Tab
Configure product identifiers per payment gateway integration. For each active payment gateway (NMI, Stripe, BuyGoods, ClickBank, etc.) enter the product ID used on that gateway. These are exposed asproduct | merchantPriceId:'stripe' in templates.
Bonuses Tab
Assign bonus products that customers receive when purchasing this product. Select from products withclassification = bonus.
Files Tab
Visible when product type is Digital or classification is Bonus. Add one or more downloadable files:- Purpose — Digital or Bonus
- Title — File display name
- Description — Optional description
- Image — Thumbnail image
- File — Upload or URL
- Primary — Mark as primary file for this purpose
Courses Tab
Assign courses that customers are automatically enrolled in after purchase.Attributes Tab
Fill in values for brand-level Product Attributes defined under Settings → Products → Product Attributes. Supports all field types: text, textarea, rich text, number, boolean, date, select, multiselect, color, image URL, file URL, and JSON. Attributes withapplies_to = variant are managed per variant in the Variants tab, not here.
Custom Attributes Tab
Legacy unstructured key/value pairs for ad-hoc product metadata (e.g. a download URL or custom flag).Note: For structured, typed attributes, use the Attributes tab with Product Attribute definitions instead. Custom Attributes are a legacy system.
Variants Tab
Define product variants (e.g. Color, Size) with individual pricing.- Select variant options — Check which brand-level variant options apply to this product (managed under Settings → Variant Options)
- Add variants — Each row shows one field per selected option plus Code and Price
Template Reference
All product data is available in ElasticFunnels templates via data functions and filters. Functions are called with{% set x = FunctionName(args) %} or inline. Filters are applied with {{ value | filterName:arg }}.
Product Object Shape
Every product returned by a data function has the following fields:| Field | Type | Description |
|---|---|---|
id | number | Unique product ID |
brand_id | number | Brand this product belongs to |
title | string | Display title — uses checkout_title when set, otherwise title |
checkout_title | string | null | Raw checkout title (before effective resolution) |
code | string | Unique product code used in buy links |
type | "physical" | "digital" | "service" | Product type |
classification | "main" | "upsell" | "downsell" | "bump" | "bonus" | Role in the funnel |
status | "active" | "draft" | "archived" | Visibility status |
price | number | Selling price |
retail_price | number | null | Compare-at (strikethrough) price |
currency | string | null | 3-letter currency code (e.g. "USD"); null = brand default |
sku | string | null | Stock-keeping unit |
barcode | string | null | UPC / EAN barcode |
units | number | null | Package quantity |
physical_units_per_product | number | null | Individual units inside one package (for per-unit pricing) |
description | string | null | Full product description (HTML) |
short_description | string | null | Brief summary |
image | string | null | Primary image CDN URL |
gallery | string[] | Additional image CDN URLs — always an array, never null |
has_gallery | boolean | true when gallery.length > 0 |
has_description | boolean | true when description is non-empty |
in_stock | boolean | true when inventory_quantity is null or > 0 |
inventory_quantity | number | null | Current stock count; null = unlimited |
inventory_policy | "continue" | "deny" | Behaviour when out of stock |
is_subscription | boolean | Whether recurring billing is enabled |
subscription_frequency | number | null | Billing interval value (e.g. 1) |
subscription_frequency_unit | "day" | "week" | "month" | "year" | null | Billing interval unit |
subscription_trial_days | number | null | Free trial days before first charge |
subscription_first_charge_free | boolean | First order ships free (customer pays shipping only) |
is_build_a_box | boolean | Build-a-Box subscription mode |
seo_title | string | null | SEO page title |
seo_slug | string | null | URL slug for storefront product pages |
seo_description | string | null | Meta description |
product_category_id | number | null | Assigned category ID |
product_subcategory_id | number | null | Assigned subcategory ID |
category_name | string | null | Category display name (denormalised) |
subcategory_name | string | null | Subcategory display name (denormalised) |
product_files | ProductFile[] | All attached files |
digital_files | ProductFile[] | Subset: digital download files |
bonus_files | ProductFile[] | Subset: bonus files |
primary_download_url | string | null | URL of the primary digital file |
merchant_product_ids | Record<string, string> | Gateway → merchant product ID map (e.g. { stripe: "price_xxx" }) |
ProductFile shape
Each item inproduct_files, digital_files, and bonus_files:
| Field | Type | Description |
|---|---|---|
url | string | CDN URL of the file |
title | string | null | File display name |
description | string | null | File description |
image | string | null | Thumbnail image URL |
purpose | "digital" | "bonus" | Whether this is a digital or bonus file |
kind | "audio" | "video" | "document" | "image" | "archive" | "file" | Inferred from MIME type |
mime_type | string | null | MIME type |
size | number | null | File size in bytes |
extension | string | null | File extension (e.g. "pdf") |
is_primary | boolean | Whether this is the primary file for its purpose |
sort_order | number | Display order |
Data Functions
GetProduct(code)
Loads a single product by its code for the current brand. Also pre-loads structured attribute values so the attr and attrLabel filters work immediately on the returned object.
ProductObject | null
GetProducts(filters?)
Returns all active products for the brand, with optional filters.
| Filter key | Type | Description |
|---|---|---|
type | string | "physical", "digital", or "service" |
classification | string | "main", "upsell", "downsell", "bump", or "bonus" |
codes | string | Comma-separated list of product codes |
category_id | number | string | Filter by product category ID |
subcategory_id | number | string | Filter by subcategory ID |
ProductObject[]
GetAllProducts()
Returns every product for the brand without filters. Fastest when you need to iterate all products and filter in the template.
ProductObject[]
GetProductCategories(filters?)
Returns product categories. By default returns a full tree ordered by position, then name, with a depth field.
| Filter key | Type | Description |
|---|---|---|
top_level | boolean | Only root categories (no parent) |
parent_id | number | string | Only direct children of this category |
flat | boolean | Return flat list instead of tree |
tree | boolean | Set false to force flat list |
{ id, name, position, parent_id, depth? }
CategoryObject[]
ProductDownloads(product)
Flattens all downloadable files attached to a product into a single deduplicated array. Useful for rendering download lists on digital product pages.
{ url, title, kind, purpose, extension, mime_type, size, is_primary, sort_order }
Returns: DownloadObject[]
ProductSavings(product)
Returns a structured savings breakdown comparing retail_price to price. Returns null if there is no saving.
{ amount: number, percent: number, amountFormatted: string, percentFormatted: string } | null
SubscriptionSummary(product)
Generates a human-readable billing summary string for a subscription product (e.g. "7-day free trial · Every 1 month").
string
GetProductAttributes(filters?)
Returns the brand’s structured attribute definitions. See Product Attributes for details on attribute types and scoping.
| Filter key | Type | Description |
|---|---|---|
visible | boolean | Only attributes with visible_on_product_page = true |
filterable | boolean | Only attributes marked as filterable |
applies_to | "product" | "variant" | Filter by scope |
{ id, name, slug, type, applies_to, options, filterable, visible_on_product_page, required }
Returns: AttributeDefinition[]
GetProductAttributeValues(product)
Returns all attribute values for a product as a { slug: value } map.
Record<string, string | number | boolean>
Filters
formatPrice
Formats a numeric price using the brand’s active currency locale.
savings
Computes the saving between retail_price and price and returns a formatted string.
| Format | Example output |
|---|---|
| (default) | "Save $20" |
'percent' | "Save 25%" |
'both' | "Save $20 (25% off)" |
"" when retail_price is not set or not greater than price.
compareAt
Formats retail_price as a “Was $X” string.
"" when retail_price is not set.
pricePerUnit
Divides price by physical_units_per_product to give the per-unit price. Useful for “per bottle” or “per capsule” displays.
string (float formatted to 2 decimal places)
subscriptionLabel
Short-form billing label. Returns trial info if present, otherwise the billing frequency.
"" for non-subscription products.
merchantPriceId
Looks up the merchant-specific product identifier from merchant_product_ids (configured in the Merchants tab).
attr
Returns the value of a structured attribute by its slug. Only works on products loaded via GetProduct (which pre-loads attribute values).
"" when the attribute is not set.
attrLabel
Returns the human-readable label (name) of a structured attribute definition by slug.
Gallery
product.gallery is a string[] — an array of CDN image URLs. It is always an array (never null or a JSON string). product.has_gallery is true when the array has at least one entry.