Marketplace Data Model

Marketplace Data Model

8 data marts66 fieldsVlad FlaksRus Obolonsky

Buyers and sellers meet through listings and search, with every order carrying gross merchandise value, take rate and seller payout, alongside the unmet searches, unsold listings and ratings that show where the match breaks down.

Overview

A two-sided online marketplace modeled end to end: independent buyers and independent sellers matched through listings and search, with every order carrying the full economics — gross merchandise value, the category take rate, the platform's cut and the seller's payout. Around that match sit the signals that tell you whether the two sides are actually clearing: what buyers searched for and failed to find, which listings never sold, which orders fell through before settling, and what the ratings say afterwards. Together they let you follow both sides of the flywheel — where demand goes unmet, and where supply gives up.

Example Questions

  • Where is liquidity weakest — which categories have buyers searching but too little live supply to fill the demand?
  • Is take-rate optimisation costing us supply, with sellers in our highest-commission categories going dormant faster than the rest?
  • How much of our booked GMV never settles, and do cancellations and complaints concentrate around the same sellers?

Explore on canvas →

Buyer Data Mart

Buyer

The demand side of the marketplace: one row per registered buyer, carrying how they were acquired, where they are, and how much they have transacted. Lifetime order count and a repeat flag make demand-side retention a first-class field — most buyers place a single order and never return, and the share who come back for a second is the health number every marketplace watches.

Fields

ColumnTypeAliasDescription
buyer_idSTRINGBuyer IDPK. Unique buyer identifier.
signup_dateDATESignup DateWhen the buyer first registered.
acquisition_channelSTRINGAcquisition ChannelMarketing source that brought the buyer in.
regionSTRINGRegionBuyer's geographic region.
segmentSTRINGSegmentBuyer segment (one-time, occasional, regular, power).
lifetime_ordersINTEGERLifetime OrdersTotal orders the buyer has placed to date.
is_repeatBOOLEANIs RepeatWhether the buyer has placed 2+ orders — demand-side retention.

Cancellations Data Mart

Cancellations

One row for every order that was cancelled — and only those. Each row records who pulled the plug (buyer, seller or platform), at which stage (pre-payment, pre-fulfilment or in-transit), the stated reason, and how much was refunded. Because refund magnitude scales with stage — near zero pre-payment, close to full once fulfilment is underway — this is where an ops or trust-and-safety lead finds the fixable concentration of fill-rate failures.

Fields

ColumnTypeAliasDescription
cancellation_idSTRINGCancellation IDPK. Unique cancellation identifier.
order_idSTRINGOrder IDOrder that was cancelled. FK to Orders
cancelled_atTIMESTAMPCancelled AtWhen the cancellation happened.
cancelled_bySTRINGCancelled ByWho cancelled: buyer, seller or platform.
stageSTRINGStageOrder stage at cancellation: pre-payment, pre-fulfilment or in-transit.
reasonSTRINGReasonStated cancellation reason.
refund_amountNUMERICRefund AmountAmount refunded to the buyer (never more than the order's gmv).

Relationships

Related data martOnCardinalityMeaning
Ordersorder_id = order_idN:1The order that was cancelled.

Category Data Mart

Category

The category tree every listing and order is filed under, and — crucially — the standard take rate the platform charges on sales in each category. Take rate is the biggest lever a category manager holds: raise it and revenue per order rises, but the sellers in that category feel the squeeze. Rates follow real marketplace norms — physical goods sit lower (8–15%), while services and premium or handmade categories carry a higher cut (15–22%).

Fields

ColumnTypeAliasDescription
category_idSTRINGCategory IDPK. Unique category identifier.
nameSTRINGNameDisplay name of the category.
parent_categorySTRINGParent CategoryParent grouping in the category tree (Goods, Media, Services).
take_rate_pctFLOATTake Rate %Platform's standard commission for the category, as a percent (e.g. 12.0 = 12%) — the take-rate optimisation lever.

Listings Data Mart

Listings

One row per listing, the unit of supply a buyer actually orders. Each listing belongs to a seller and a category and carries a price and an availability state. The count of live listings per seller is exactly that seller's active inventory, which makes this the backbone behind every order's price and category — and the first place to look when demand arrives and finds nothing to buy.

Fields

ColumnTypeAliasDescription
listing_idSTRINGListing IDPK. Unique listing identifier.
seller_idSTRINGSeller IDSeller that owns the listing. FK to Seller
created_atTIMESTAMPCreated AtWhen the listing was created.
category_idSTRINGCategory IDCategory the listing belongs to. FK to Category
priceNUMERICPriceListed price of the offer.
statusSTRINGStatusCurrent listing status: active, paused, sold_out or removed.
is_availableBOOLEANIs AvailableWhether the listing is live inventory — supply availability.

Relationships

Related data martOnCardinalityMeaning
Categorycategory_id = category_idN:1The category this listing is filed under.
Sellerseller_id = seller_idN:1The seller who owns this listing.

Orders Data Mart

Orders

The match at the heart of the marketplace: one row per order placed, tying a buyer to a seller's listing. It carries the full transaction economics — gross merchandise value, the category take rate, the platform's cut and the reciprocal seller payout. Revenue is recognised only on orders that settle: a cancelled order keeps its booked GMV for funnel analysis while its net GMV, platform revenue and seller payout all fall to zero, so gross and net are never confused.

Fields

ColumnTypeAliasDescription
order_idSTRINGOrder IDPK. Unique order identifier.
buyer_idSTRINGBuyer IDBuyer on the order. FK to Buyer
seller_idSTRINGSeller IDSeller on the order (always the listing's owner). FK to Seller
listing_idSTRINGListing IDListing that was purchased. FK to Listings
category_idSTRINGCategory IDCategory of the purchased listing, denormalised for slicing. FK to Category
ordered_atTIMESTAMPOrdered AtWhen the order was placed.
quantityINTEGERQuantityUnits ordered (gmv = listing price × quantity).
gmvNUMERICGMVGross merchandise value booked for the order.
take_rateFLOATTake RatePlatform's cut as a fraction of GMV (= category take_rate_pct / 100).
platform_revenueNUMERICPlatform RevenuePlatform's recognised revenue (gmv × take_rate; zero if cancelled).
seller_payoutNUMERICSeller PayoutSeller's take-home (gmv − platform_revenue; zero if cancelled).
net_gmvNUMERICNet GMVGMV net of cancellations (equal to gmv unless cancelled, then zero).
statusSTRINGStatusOrder status: pending, fulfilled or cancelled.
is_fulfilledBOOLEANIs FulfilledWhether the order was fulfilled.
fulfillment_minsFLOATFulfillment MinsOrder-to-fulfilment time in minutes — fill speed (null unless fulfilled).

Relationships

Related data martOnCardinalityMeaning
Buyerbuyer_id = buyer_idN:1The buyer who placed this order.
Categorycategory_id = category_idN:1The category this order is filed under.
Listingslisting_id = listing_idN:1The listing that was ordered.
Sellerseller_id = seller_idN:1The seller who fulfilled this order.

Reviews Data Mart

Reviews

One row per review left after a fulfilled order — the marketplace's trust signal. Only a minority of completed orders are ever reviewed, since reviewing is voluntary, and ratings follow the familiar J-shape: mostly five stars, a hard bump at one star, little in between. The reviewer role separates the buyer's rating of the seller from the seller's rating of the buyer, and the complaint flag — concentrated in the low ratings — marks where trust is breaking down.

Fields

ColumnTypeAliasDescription
review_idSTRINGReview IDPK. Unique review identifier.
order_idSTRINGOrder IDOrder the review relates to (always a fulfilled order). FK to Orders
reviewer_roleSTRINGReviewer RoleSide that left the review: buyer or seller.
ratingINTEGERRatingStar rating 1–5 for the order.
created_atTIMESTAMPCreated AtWhen the review was submitted.
has_complaintBOOLEANHas ComplaintWhether the review flags a complaint (concentrated in 1–2 star ratings).

Relationships

Related data martOnCardinalityMeaning
Ordersorder_id = order_idN:1The fulfilled order being reviewed.

Search Requests Data Mart

Search Requests

One row per search a buyer runs — the top of the demand funnel and the cleanest read on marketplace liquidity. Each request records the category searched, how many results came back, whether the buyer clicked, and whether the search converted into an order, along with the time it took to match. Searches that return nothing, or return results but never convert, are the "demand with no fill" signal a liquidity analyst hunts for.

Fields

ColumnTypeAliasDescription
request_idSTRINGRequest IDPK. Unique search request identifier.
buyer_idSTRINGBuyer IDBuyer who made the search. FK to Buyer
category_idSTRINGCategory IDCategory the search was scoped to. FK to Category
requested_atTIMESTAMPRequested AtWhen the search was made.
querySTRINGQueryRaw search text entered by the buyer.
results_countINTEGERResults CountNumber of results returned.
clickedBOOLEANClickedWhether the buyer clicked a result.
convertedBOOLEANConvertedWhether the search led to an order.
order_idSTRINGOrder IDOrder the search converted into, if any. FK to Orders
time_to_match_minsFLOATTime To Match MinsSearch → transaction latency in minutes (null unless converted).

Relationships

Related data martOnCardinalityMeaning
Buyerbuyer_id = buyer_idN:1The buyer who ran this search.
Categorycategory_id = category_idN:1The category searched in.
Ordersorder_id = order_idN:1The order this search led to, where it converted.

Seller Data Mart

Seller

The supply side: one row per seller, with the primary category they sell in, their buyer rating, how many listings they keep live, and — critically for supply-health work — when they last sold and whether they are still active. Supply is heavily concentrated: a small share of sellers drives most of the platform's GMV, so lifecycle status (active, dormant or churned, driven by sale recency) is where a supply manager looks first when GMV softens.

Fields

ColumnTypeAliasDescription
seller_idSTRINGSeller IDPK. Unique seller identifier.
onboarded_atDATEOnboarded AtWhen the seller joined the platform.
category_idSTRINGCategory IDPrimary category the seller sells in. FK to Category
regionSTRINGRegionSeller's geographic region.
ratingFLOATRatingAverage buyer rating of the seller (null until first review).
active_listingsINTEGERActive ListingsNumber of currently live listings.
is_activatedBOOLEANIs ActivatedWhether the seller has reached its first sale — supply activation.
fulfillment_typeSTRINGFulfillment TypeHow the seller fulfils orders.
last_sale_atDATELast Sale AtDate of the seller's most recent sale (null if never sold).
statusSTRINGStatusLifecycle state from sale recency: active, dormant or churned.

Relationships

Related data martOnCardinalityMeaning
Categorycategory_id = category_idN:1The seller's primary category.

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.