E-commerce Subscription Store Data Model

Overview

An online store that sells the same products two ways — once, and on a schedule — modeled end to end. Traffic, sessions and pageviews describe how shoppers arrive and move through the storefront; the catalog describes what they browse; orders and order lines capture what they buy and what it earns; and a dedicated subscription layer captures the part that makes this business predictable: the contracts, the offers behind them, every charge and lifecycle change they go through, and where each subscriber stands at the end of every month.

The subscription layer is built around the two facts a recurring business lives on. First, that churn has two causes — a subscriber who decides to leave, and a subscriber whose card kept failing — and only one of them is recoverable. Second, that a skip or a pause is not a cancellation, and reporting that conflates them understates retention. Cancellation reasons, dunning retries, skips and pauses are therefore first-class, alongside the offer each contract runs on, so the discount the programme gives away can be weighed against the retention it buys. Advertising spend is unified on a daily grain and shares campaign naming with the storefront's traffic sources, which makes cost per subscriber answerable next to cost per order.

Example Questions

  • What share of revenue is recurring, how is it moving month over month, and which of new subscriptions, plan changes and cancellations is driving the change?
  • How do subscriber cohorts retain over three, six and twelve months, and which delivery cadence and acquisition channel produce the stickiest subscribers?
  • What does a new subscriber cost by channel, and how does that compare with the lifetime revenue they return — including the discount the subscription programme gives away?

Explore on canvas →

Ad Spend Data Mart

Ad Spend

Advertising spend, clicks and impressions from every paid platform the store runs, on one daily grain, down to the ad group and the account the money was spent from. Because it shares source, medium and campaign naming with the storefront's traffic sources, spend can be set against the sessions, orders and subscriptions it produced instead of being read on its own.

For a subscription business the interesting comparison is not cost per order but cost per subscriber, and the two diverge sharply by channel: a channel with expensive first orders can still be the cheapest source of long-lived subscribers.

Fields

ColumnTypeAliasDescription
ad_spend_idSTRINGSpend Record IDPK. Unique identifier of the daily spend record.
dateDATEDateDate the advertising activity occurred on.
sourceSTRINGPlatformAdvertising platform the spend occurred on. FK to Traffic Sources
mediumSTRINGMediumChannel type the spend belongs to, such as cost-per-click. FK to Traffic Sources
campaignSTRINGCampaignCampaign the spend belongs to. FK to Traffic Sources
ad_groupSTRINGAd GroupAd group within the campaign that the spend belongs to.
ad_accountSTRINGAd AccountAdvertising account the money was spent from.
spendFLOATSpendAmount spent on advertising on this date.
clicksINTEGERClicksNumber of clicks the advertising received.
impressionsINTEGERImpressionsNumber of times the advertising was displayed.
platform_conversionsFLOATPlatform-Claimed ConversionsHow many purchases the ad platform's own reporting credits to this campaign, set here so it can be read against Orders. It runs ahead of the store's own order count on purpose — 1.25x on Google Ads and Microsoft Ads, 1.40x on Meta Ads, 1.55x on TikTok Ads — because platforms count clicks up to 7 days old plus views up to 1 day old, stitch a purchase across a shopper's devices, and let more than one platform claim the same sale. The gap between this and actual orders is the attribution gap, not an error to reconcile away.
platform_conversion_valueFLOATPlatform-Claimed RevenueRevenue the platform attributes to the conversions it claims above. NULL for TikTok Ads by design — that platform's reporting includes a conversion count but no value, and that gap in what each platform can even tell you is itself worth stating rather than defaulting to zero.
currencySTRINGCurrencyThree-letter code of the currency the spend is reported in.

Relationships

Related data martOnCardinalityMeaning
Traffic Sourcessource = source, medium = medium, campaign = campaignN:NThe channel this spend was bought on.

Customer Value Data Mart

Customer Value

What each customer is worth today: revenue and units over the last twelve months, lifetime revenue, how recently they bought, the loyalty band that behaviour puts them in, and where they stand with the subscription programme. The session that first brought them in sits in the same row, which is what lets value be traced back to the channel that acquired it.

Subscription standing is explicit — never subscribed, active, paused, churned or reactivated — alongside the share of the customer's revenue that is recurring. That combination answers the question the programme exists to settle: whether subscribers are genuinely worth more than one-time buyers, and by how much.

Fields

ColumnTypeAliasDescription
customer_idSTRINGCustomer IDPK. Customer this value profile describes. FK to Customers
acquisition_session_idSTRINGAcquisition Session IDBrowsing session during which the customer was first acquired. FK to Sessions
net_revenue_last_12mFLOATNet Revenue Last 12mRevenue the customer generated over the last twelve months, after discounts and returns.
units_sold_last_12mINTEGERUnits Sold Last 12mNumber of individual units the customer bought over the last twelve months.
orders_last_12mINTEGEROrders Last 12mNumber of orders the customer placed over the last twelve months.
lifetime_net_revenueFLOATLifetime Net RevenueTotal revenue the customer has generated since their first order.
loyalty_segmentSTRINGLoyalty SegmentBehavioural band the customer falls into, such as New, Returning, Loyal, At risk or Lapsed.
subscriber_statusSTRINGSubscriber StatusWhere the customer stands with the subscription programme: Never subscribed, Active, Paused, Churned or Reactivated.
active_subscriptionsINTEGERActive SubscriptionsNumber of subscriptions the customer currently holds in an active state.
months_subscribedINTEGERMonths SubscribedNumber of months the customer has held at least one active subscription.
subscription_revenue_shareFLOATSubscription Revenue ShareShare of the customer's lifetime revenue that came from subscription orders, between zero and one.
first_order_atDATEFirst Order AtDate the customer placed their first order.
last_order_atDATELast Order AtDate the customer placed their most recent order.
recency_daysINTEGERRecency DaysNumber of days since the customer's most recent order.
acquisition_channel_groupingSTRINGAcquisition Channel GroupingChannel the customer was originally acquired through, such as Paid Search, Paid Social, Organic or Direct.

Relationships

Related data martOnCardinalityMeaning
Customerscustomer_id = customer_id1:1The customer this value profile is for.
Sessionsacquisition_session_id = session_idN:1The visit that first acquired the customer.

Customers Data Mart

Customers

Everyone who has bought from the store, with the channel that first brought them in, the market they buy from, their contact details for lifecycle marketing, and the behavioural type their buying history puts them in. This is the join point between acquisition and everything that follows: the same row explains how a customer was won and where they are today.

This mart stays a register of who the customer is, not of what they have bought: order history, value and loyalty band live in Customer Value, which joins one-to-one and is computed over the orders themselves. Marketing consent is explicit, because win-back and dunning campaigns can only address customers who allow it.

Fields

ColumnTypeAliasDescription
customer_idSTRINGCustomer IDPK. Unique identifier of the customer.
registered_atDATERegistered AtDate the customer account was created.
emailSTRINGEmailMost recent known email address of the customer.
phoneSTRINGPhoneMost recent known phone number of the customer.
citySTRINGCityCity the customer's latest order was shipped to.
countrySTRINGCountryCountry the customer's latest order was shipped to.
country_codeSTRINGCountry CodeTwo-letter code of the country the customer buys from.
acquisition_traffic_source_idSTRINGAcquisition Traffic Source IDTraffic source that first brought the customer to the store. FK to Traffic Sources
marketing_opt_inBOOLEANMarketing Opt InWhether the customer consented to receive marketing communication.

Relationships

Related data martOnCardinalityMeaning
Traffic Sourcesacquisition_traffic_source_id = traffic_source_idN:1The channel that acquired this customer.

Order Items Data Mart

Order Items

The order lines behind every order — one row per product bought, with quantity, the price actually paid, the cost of goods, and the revenue and profit that result. Because unit cost sits next to the price paid, margin is a property of the line rather than something reconstructed later, and the true cost of subscription discounting becomes visible at the product level.

Subscription lines are flagged apart from one-time lines, so the same product can be compared in both worlds: what it earns when bought once, and what it earns when it is delivered on a schedule at a standing discount.

Fields

ColumnTypeAliasDescription
order_item_idSTRINGOrder Item IDPK. Unique identifier of the order line.
order_idSTRINGOrder IDOrder this line belongs to. FK to Orders
product_idSTRINGProduct IDProduct bought on this line. FK to Products
quantityINTEGERQuantityNumber of units of the product on this line.
unit_priceFLOATUnit PricePrice paid per unit at the moment of purchase.
unit_costFLOATUnit CostCost to the business of one unit of the product.
line_discountFLOATLine DiscountDiscount applied to this line, including the subscription discount.
line_revenueFLOATLine RevenueGross revenue for the line, being quantity multiplied by the price paid.
line_net_revenueFLOATLine Net RevenueRevenue recognised for the line, counted only for completed orders.
line_costFLOATLine CostCost of goods on this line whatever became of the order — a cancelled or returned line still carries a cost here — so pairing it with line_net_revenue instead of line_net_cost mixes a booked population with a settled one and lands margin about 0.8 percentage points low.
line_net_costFLOATLine Net CostCost of goods for lines that actually sold — zero on a cancelled or returned order — so it is the column that pairs correctly with line_net_revenue and line_net_profit over that same settled population.
line_net_profitFLOATLine Net ProfitProfit for the line on completed orders, being net revenue less cost of goods.
is_subscription_itemBOOLEANIs Subscription ItemWhether the line was delivered on a subscription rather than bought one-time.

Relationships

Related data martOnCardinalityMeaning
Ordersorder_id = order_idN:1The order this line belongs to.
Productsproduct_id = product_idN:1The product sold on this line.

Orders Data Mart

Orders

One row per order — the header of the transaction, with the money on it and the reason it exists. Every order says whether it was a one-time purchase, the first order of a new subscription, or a recurring delivery, and recurring orders carry the subscription and the cycle they belong to. That single classification is what separates predictable revenue from the rest without leaving the order grain.

Gross sales, discounts, tax, shipping and net revenue all sit on the header, so the discount the subscription programme gives away is measurable rather than assumed. Retail and wholesale orders are flagged apart, and cancelled or returned orders keep their row, so booked and settled revenue never quietly merge.

Fields

ColumnTypeAliasDescription
order_idSTRINGOrder IDPK. Unique identifier of the order.
order_dateDATEOrder DateDate the order was placed.
order_timestampTIMESTAMPOrder TimestampExact moment the order was placed, in UTC.
customer_idSTRINGCustomer IDCustomer who placed the order. FK to Customers
session_idSTRINGSession IDBrowsing session the order was placed in. FK to Sessions
subscription_idSTRINGSubscription IDSubscription the order was generated by; empty on one-time orders. FK to Subscriptions
purchase_typeSTRINGPurchase TypeWhy the order exists: One-time, Subscription first order or Subscription recurring.
order_typeSTRINGOrder TypeWhether the order is Retail or Wholesale.
cycle_numberINTEGERCycle NumberWhich delivery cycle of the subscription this order fulfils; zero on one-time orders.
statusSTRINGStatusFulfilment state of the order: Completed, Cancelled or Returned.
gross_salesFLOATGross SalesValue of the order before discounts, tax and shipping.
discountsFLOATDiscountsTotal discount applied to the order, including the subscription discount.
taxFLOATTaxTotal tax charged on the order.
shippingFLOATShippingTotal shipping charged on the order.
net_revenueFLOATNet RevenueSettled revenue for the order — zero on a cancelled or returned order, so it never has to be filtered by status to be trusted. Booked revenue is not lost, it is simply a different number: gross_sales - discounts, carried on every row regardless of status.
applied_discount_codesSTRINGDiscount CodesPromotional codes the customer used at checkout.
loyalty_segmentSTRINGLoyalty SegmentLoyalty band the customer was in when the order was placed.
currencySTRINGCurrencyThree-letter code of the currency the order was placed in.
items_countINTEGERItems CountNumber of order lines on the order.

Relationships

Related data martOnCardinalityMeaning
Customerscustomer_id = customer_idN:1The customer who placed this order.
Sessionssession_id = session_idN:1The visit this order was placed in — absent on a recurring charge.
Subscriptionssubscription_id = subscription_idN:1The contract this order was billed under, where it is recurring.

Page Views Data Mart

Page Views

Every page view recorded on the storefront, in sequence within its session — which page, when, and where in the session the view sits. This is the finest grain in the model and the raw material for funnel analysis: the step-by-step path between arriving and buying, or between arriving and leaving.

Because the subscription management pages are part of the same page catalog, the same funnel logic covers both new sign-ups and existing subscribers going in to skip, swap or cancel — the behaviour that precedes churn is visible before the churn itself.

Fields

ColumnTypeAliasDescription
pageview_idSTRINGPageview IDPK. Unique identifier of the page view.
session_idSTRINGSession IDSession the page view belongs to. FK to Sessions
page_idSTRINGPage IDPage that was viewed. FK to Pages
dateDATEDateDate the page view occurred.
hit_numberINTEGERHit NumberPosition of the page view within its session, starting at one.
hit_timestampTIMESTAMPHit TimestampExact moment the page view was recorded, in UTC.
pageview_countINTEGERPageview CountAlways one, so page views can be summed without counting distinct identifiers.

Relationships

Related data martOnCardinalityMeaning
Pagespage_id = page_idN:1The page that was viewed.
Sessionssession_id = session_idN:1The visit this page view belongs to.

Pages Data Mart

Pages

The catalog of pages that make up the storefront — path, display title, and the function each page serves. It turns raw URL paths into something a business user can read, which is what makes funnel analysis by page type possible at all.

The subscription portal is a page type of its own, next to product, cart and checkout. That is deliberate: the pages where subscribers skip, swap or cancel are as load-bearing for a recurring business as the checkout is for a one-time one.

Fields

ColumnTypeAliasDescription
page_idSTRINGPage IDPK. Unique identifier of the page.
page_pathSTRINGPage PathURL path of the page relative to the domain root.
page_titleSTRINGPage TitleHuman-readable title of the page.
page_typeSTRINGPage TypeFunction the page serves, such as Home, Category, Product, Cart, Checkout, Subscription Portal, Blog or Account.
host_nameSTRINGHost NameDomain the page is served from.

Products Data Mart

Products

The catalog: what the store sells, at what price, at what unit cost, which brand and category it belongs to, whether it can be subscribed to, and which page on the site it lives on. Price and cost in the same row make unit margin a property of the product, which is the starting point for judging whether a product can carry a standing subscription discount at all.

Two naming columns are kept side by side on purpose: the name as it appears in the storefront, and a cleaned unified name that groups variants and inconsistent spellings of the same product. Reporting on the unified name is what stops one product from appearing as several.

Fields

ColumnTypeAliasDescription
product_idSTRINGProduct IDPK. Unique identifier of the product.
product_nameSTRINGProduct NameName of the product as shown in the storefront.
unified_product_nameSTRINGUnified Product NameCleaned product name that groups variants and inconsistent spellings of the same product.
product_brandSTRINGProduct BrandBrand the product is sold under.
product_categorySTRINGProduct CategoryCategory the product belongs to, such as Supplements, Skincare or Accessories.
skuSTRINGSKUStock keeping unit identifying the exact variant.
priceFLOATPriceCurrent one-time selling price of a single unit.
unit_costFLOATUnit CostCost to the business of producing or acquiring a single unit.
is_subscription_eligibleBOOLEANIs Subscription EligibleWhether the product can be bought on a subscription plan.
page_idSTRINGPage IDProduct detail page on the website. FK to Pages

Relationships

Related data martOnCardinalityMeaning
Pagespage_id = page_idN:1This product's page on the storefront.

Selling Plans Data Mart

Selling Plans

The subscription offers the store sells against — every cadence a customer can choose, the discount attached to it, and whether it is paid per delivery or upfront for several deliveries at once. Because the plan carries both the delivery rhythm and the discount, the cost of the subscription programme and the retention it buys can be judged offer by offer rather than as one blended number.

Two families of offer live here, and they behave differently in every report: pay-as-you-go ("subscribe & save"), where the customer is charged on each delivery, and prepaid, where a single payment covers a fixed number of future deliveries. Prepaid revenue arrives in one lump and its churn shows up much later, which is exactly why the plan type has to be explicit rather than inferred.

Fields

ColumnTypeAliasDescription
selling_plan_idSTRINGSelling Plan IDPK. Unique identifier of the subscription offer a customer can subscribe to.
plan_nameSTRINGPlan NameCustomer-facing name of the offer, such as Monthly Subscribe & Save or Prepaid 3-Month.
plan_typeSTRINGPlan TypeWhether the customer pays on every delivery (Pay-as-you-go) or upfront for several deliveries (Prepaid).
delivery_interval_unitSTRINGDelivery Interval UnitUnit the delivery rhythm is expressed in, such as week or month.
delivery_interval_countINTEGERDelivery Interval CountNumber of interval units between two deliveries, for example 2 with a unit of week means every two weeks.
delivery_interval_daysINTEGERDelivery Interval DaysDelivery rhythm normalised to days, so cadences expressed in weeks and months can be compared directly.
prepaid_cyclesINTEGERPrepaid CyclesNumber of deliveries covered by a single upfront payment; zero for pay-as-you-go offers.
discount_pctFLOATDiscount %Discount off the one-time price granted for subscribing on this plan, in percent.
is_skippableBOOLEANIs SkippableWhether the subscriber is allowed to skip an upcoming delivery instead of cancelling.
is_activeBOOLEANIs ActiveWhether the offer is currently available to new subscribers.

Sessions Data Mart

Sessions

Every browsing session on the storefront, with the device it happened on, the market it came from, the traffic source and campaign that produced it, the page it started on, and what it ended in. Sessions are the hinge of the model: advertising spend attaches on one side and orders on the other, which is what lets acquisition cost be weighed against the revenue it returns.

Conversions are recorded twice over on purpose — whether the session produced an order at all, and whether it started a subscription. Those are different outcomes worth very different amounts, and a channel that produces plenty of the first and none of the second is exactly what the distinction is there to expose.

Fields

ColumnTypeAliasDescription
session_idSTRINGSession IDPK. Unique identifier of the browsing session.
dateDATEDateDate the session took place. FK to Ad Spend
visitor_idSTRINGVisitor IDVisitor who ran the session. FK to Visitors
customer_idSTRINGCustomer IDCustomer the session belongs to, when the visitor was recognised.
traffic_source_idSTRINGTraffic Source IDTraffic source that produced the session. FK to Traffic Sources
landing_page_idSTRINGLanding Page IDFirst page of the session. FK to Pages
device_categorySTRINGDevice CategoryType of device used during the session, such as mobile, desktop or tablet.
countrySTRINGCountryCountry the session came from.
session_countINTEGERSession CountAlways one, so sessions can be summed without counting distinct identifiers.
pageview_countINTEGERPageview CountNumber of pages viewed during the session.
is_conversionBOOLEANIs ConversionWhether the session ended in an order of any kind.
is_subscription_conversionBOOLEANIs Subscription ConversionWhether a subscription was started during the session.
sourceSTRINGSourcePlatform or site the traffic came from, used to align sessions with advertising spend. FK to Ad Spend
mediumSTRINGMediumChannel type of the traffic, such as cost-per-click or organic. FK to Ad Spend
campaignSTRINGCampaignMarketing campaign that produced the session; empty for traffic that runs no campaign, such as organic, direct and referral. FK to Ad Spend

Relationships

Related data martOnCardinalityMeaning
Ad Spenddate = date, source = source, medium = medium, campaign = campaignN:NSpend on the same day and channel — a cohort match, not this visit's cost.
Pageslanding_page_id = page_idN:1The page the visit landed on.
Traffic Sourcestraffic_source_id = traffic_source_idN:1The channel that drove this visit.
Visitorsvisitor_id = visitor_idN:1The visitor who browsed.

Subscription Events Data Mart

Subscription Events

Everything that ever happened to a subscription, in order — created, charged, declined, retried, skipped, paused, resumed, swapped to another plan, changed in quantity, cancelled and reactivated. Each row carries the cycle it belongs to and what it did to recurring revenue, which is what makes a month-over-month recurring revenue movement explainable rather than merely visible.

Billing attempts live here alongside lifecycle changes on purpose. A declined charge never becomes an order, so without these rows the failed-payment half of churn would be invisible — and it is the half that is recoverable, because a retry that succeeds saves a subscriber who never intended to leave.

Fields

ColumnTypeAliasDescription
event_idSTRINGEvent IDPK. Unique identifier of the subscription event.
subscription_idSTRINGSubscription IDSubscription the event belongs to. FK to Subscriptions
event_dateDATEEvent DateCalendar date the event occurred on.
event_timestampTIMESTAMPEvent TimestampExact moment the event was recorded, in UTC.
event_typeSTRINGEvent TypeWhat happened: created, charge_success, charge_failed, charge_retry_success, skipped, paused, resumed, plan_swapped, quantity_changed, cancelled or reactivated.
event_categorySTRINGEvent CategoryWhether the event is a Billing attempt or a Lifecycle change, so the two can be reported apart.
cycle_numberINTEGERCycle NumberWhich delivery cycle of the subscription the event relates to, starting at one.
amountFLOATAmountAmount involved in the event; the charged amount for billing events and zero for lifecycle changes.
mrr_deltaFLOATMRR DeltaSigned change this event made to the subscription's monthly recurring value.
retry_numberINTEGERRetry NumberWhich dunning retry this charge attempt was; zero for a first attempt.
decline_reasonSTRINGDecline ReasonWhy a charge attempt was declined, such as Insufficient funds, Card expired or Card declined.
quantity_deltaINTEGERQuantity DeltaSigned change in the number of units per delivery, on events that changed the quantity.

Relationships

Related data martOnCardinalityMeaning
Subscriptionssubscription_id = subscription_idN:1The contract this event happened to.

Subscription Monthly Snapshot Data Mart

Subscription Monthly Snapshot

Where every subscriber stood at the end of each month: how many subscriptions they held, how much recurring and one-time revenue they produced, how many cycles were charged, skipped or declined, and whether that month was their first, their last, or a return after a break. Retention and recurring revenue become a single grouping rather than a window calculation.

The cohort the subscriber belongs to travels with every row, so month-three and month-twelve retention can be read straight off this mart and compared across cadences and acquisition channels. Recurring and one-time revenue are kept apart deliberately: a store that sells both ways cannot judge the health of its subscription programme from a blended total.

Fields

ColumnTypeAliasDescription
snapshot_idSTRINGSnapshot IDPK. Unique identifier of the subscriber-month record.
monthDATEMonthFirst day of the month the snapshot describes.
customer_idSTRINGCustomer IDSubscriber the snapshot describes. FK to Customers
primary_selling_plan_idSTRINGPrimary Selling Plan IDOffer that carried most of this subscriber's recurring revenue in the month. FK to Selling Plans
cohort_monthDATECohort MonthMonth the subscriber first subscribed in, used as the cohort anchor.
months_since_cohortINTEGERMonths Since CohortNumber of months between the cohort month and this snapshot month.
status_at_month_endSTRINGStatus At Month EndWhere the subscriber stood on the last day of the month: Active, Paused or Cancelled.
active_subscriptionsINTEGERActive SubscriptionsNumber of subscriptions the customer held in an active state at month end.
paused_subscriptionsINTEGERPaused SubscriptionsNumber of the customer's subscriptions that were paused at month end.
recurring_revenueFLOATRecurring RevenueRevenue the customer generated from subscription charges during the month.
one_time_revenueFLOATOne Time RevenueRevenue the customer generated from one-time orders during the month.
total_revenueFLOATTotal RevenueAll revenue the customer generated during the month, recurring and one-time together.
cycles_chargedINTEGERCycles ChargedNumber of subscription cycles successfully charged during the month.
failed_chargesINTEGERFailed ChargesNumber of charge attempts declined during the month.
skipped_cyclesINTEGERSkipped CyclesNumber of deliveries the subscriber chose to skip during the month.
is_new_subscriberBOOLEANIs New SubscriberWhether the customer's first ever subscription started in this month.
is_churnedBOOLEANIs ChurnedWhether the customer's last active subscription ended in this month.
is_reactivatedBOOLEANIs ReactivatedWhether the customer returned to an active subscription this month after a period without one.

Relationships

Related data martOnCardinalityMeaning
Customerscustomer_id = customer_idN:1The subscriber this month belongs to.
Selling Plansprimary_selling_plan_id = selling_plan_idN:1The offer the subscriber was mainly on that month.

Subscriptions Data Mart

Subscriptions

One row per subscription contract — who subscribed, to which product on which offer, how much it bills per cycle, how many cycles it has survived, and, when it ended, why. This is the centre of the recurring business: the active rows are the revenue base, and the ended rows are the entire churn story with its reason attached.

A contract distinguishes the two ways subscriptions die, which reporting that only counts cancellations cannot: a subscriber who decided to leave, and a subscriber whose card kept failing until the retries ran out. Pause and skip are held apart from cancellation too, so a subscriber taking a break is never counted as lost.

Fields

ColumnTypeAliasDescription
subscription_idSTRINGSubscription IDPK. Unique identifier of the subscription contract.
customer_idSTRINGCustomer IDCustomer who owns this subscription. FK to Customers
selling_plan_idSTRINGSelling Plan IDSubscription offer the contract was created on. FK to Selling Plans
product_idSTRINGProduct IDProduct being delivered on this subscription. FK to Products
statusSTRINGStatusCurrent state of the contract: Active, Paused or Cancelled.
started_atDATEStarted AtDate the subscription was created.
cohort_monthDATECohort MonthFirst day of the month the subscription started in, used for retention cohorts.
quantityINTEGERQuantityNumber of units delivered on each cycle.
unit_priceFLOATUnit PricePrice charged per unit on this contract, after the plan discount.
recurring_valueFLOATRecurring ValueAmount billed on each cycle, being quantity multiplied by the unit price.
monthly_recurring_valueFLOATMonthly Recurring ValueRecurring value normalised to a 30-day month, so cadences of different lengths can be summed into one recurring revenue figure.
billing_interval_daysINTEGERBilling Interval DaysNumber of days between two charges on this contract.
cycles_completedINTEGERCycles CompletedNumber of cycles successfully charged and delivered so far.
cycles_remainingINTEGERCycles RemainingDeliveries still owed on a prepaid contract; zero for pay-as-you-go.
next_charge_dateDATENext Charge DateDate the next charge is scheduled for, on active contracts.
last_charge_dateDATELast Charge DateDate of the most recent successful charge.
paused_atDATEPaused AtDate the subscriber paused the contract, when it is currently paused.
cancelled_atDATECancelled AtDate the contract ended, when it is no longer active.
cancel_reasonSTRINGCancel ReasonWhy the contract ended, such as Too much product, Too expensive, Product quality, Found alternative, No longer needed or Payment failure.
cancel_typeSTRINGCancel TypeWhether the ending was Voluntary, meaning the subscriber chose it, or Involuntary, meaning payment retries were exhausted.
failed_payment_countINTEGERFailed Payment CountNumber of charge attempts on this contract that were declined.
max_retries_reachedBOOLEANMax Retries ReachedWhether the dunning process ran out of retries on this contract.
is_prepaidBOOLEANIs PrepaidWhether the contract was paid upfront for several deliveries.
tenure_daysINTEGERTenure DaysNumber of days the contract has been alive, counted to its end date or to today.

Relationships

Related data martOnCardinalityMeaning
Customerscustomer_id = customer_idN:1The subscriber who signed this contract.
Productsproduct_id = product_idN:1The product shipped on schedule.
Selling Plansselling_plan_id = selling_plan_idN:1The offer this contract was signed on.

Traffic Sources Data Mart

Traffic Sources

Every source, medium and campaign combination that sends traffic to the storefront, down to the keyword and the creative, grouped into the channels the business actually reports on and flagged for whether the traffic was paid. It is the vocabulary that makes marketing comparable: the same grouping applies to sessions, to customers and to advertising spend.

Keeping the paid flag and the channel grouping here rather than deriving them per report is what stops the same channel from being named three different ways in three different places.

Fields

ColumnTypeAliasDescription
traffic_source_idSTRINGTraffic Source IDPK. Unique identifier of the source, medium and campaign combination.
sourceSTRINGSourcePlatform or site the traffic originated from.
mediumSTRINGMediumChannel type of the traffic, such as cost-per-click, organic or referral.
campaignSTRINGCampaignMarketing campaign the traffic belongs to.
keywordSTRINGKeywordSearch term or targeting keyword that triggered the visit.
ad_contentSTRINGAd ContentCreative or ad variant the visit came from.
channel_groupingSTRINGChannel GroupingReporting channel the combination rolls up to, such as Paid Search, Paid Social, Organic, Email or Direct.
is_paidBOOLEANIs PaidWhether the traffic was acquired through a paid channel.

Visitors Data Mart

Visitors

Everyone who has visited the storefront, whether they ever bought or not: when they first and last appeared, how many sessions they ran, the channel that originally acquired them, the month they belong to, and — where they later bought — the customer they became. This is where anonymous traffic and known customers meet.

Because the acquisition channel is recorded on the visitor rather than only on the session, every later order and subscription can be credited back to what first brought that person to the site, even when they returned through a different channel.

Fields

ColumnTypeAliasDescription
visitor_idSTRINGVisitor IDPK. Unique identifier of the website visitor.
linked_customer_idSTRINGLinked Customer IDCustomer account this visitor was later recognised as, when they bought.
first_seen_dateDATEFirst Seen DateDate the visitor first interacted with the site.
last_seen_dateDATELast Seen DateDate of the visitor's most recent interaction.
total_sessionsINTEGERTotal SessionsNumber of sessions the visitor has run in total.
acquisition_sourceSTRINGAcquisition SourcePlatform or site that originally referred the visitor.
acquisition_mediumSTRINGAcquisition MediumChannel type the visitor was originally acquired through.
acquisition_campaignSTRINGAcquisition CampaignMarketing campaign that originally brought the visitor to the site.
cohort_monthDATECohort MonthFirst day of the month of the visitor's first visit, used for retention analysis.
visitor_segmentSTRINGVisitor SegmentEngagement band the visitor falls into, such as One-off, Occasional or Frequent.
countrySTRINGCountryCountry the visitor browses from.

Apply to your project

  1. 1

    Install the Import Model plugin

    One plugin, installed once, in your own OWOX workspace.

    Get the plugin →

  2. 2

    Import this model

    Point it at this bundle and it creates every data mart above, joins and all.

    Open the model →

  3. 3

    Plug in your data and destinations

    Connect your own sources and send the results where your team already works.

    Browse connectors →

4. Optional — customize as you wish. Rename a column, drop a mart, add your own: once it is imported it is yours, and nothing here syncs back.