Skip to main content
The MarketplaceService class (accessed via client.marketplace) is the entry point for building a multi-merchant marketplace storefront — one shopfront where many independent merchants are aggregated into a single shopping experience, a single cart can span several merchants, and one payment is automatically split to each merchant. If you’re building a normal single-store storefront, you don’t need this service at all — use products, cart, orders, etc. directly. This page is for marketplace deployments.

Before you start: how a marketplace works in Tybrite

A few concepts make everything else click.
  • Marketplace vs. merchant. A marketplace aggregates many merchants (each is an independent store with its own catalog, pricing, and inventory). The marketplace operator sets commission and branding; merchants keep full control of their own products.
  • The operator key. A marketplace storefront authenticates with a single marketplace operator key (a publishable key, tybrite_pk_..., minted by the operator). You use this one key for everything the storefront does: browsing the aggregated catalog, rendering a single merchant’s shop page, signing shoppers in, previewing carts, and checking out. You do not juggle per-merchant keys.
  • Aggregated reads. When you call the normal catalog endpoints (products, taxonomy, search) with the operator key, they automatically return results across every active merchant, and each product/result is stamped with the merchant_store_id it came from. Pass storeId to narrow any of them to one merchant.
  • One shopper, every merchant. A shopper signs up once and can buy from any merchant. Their identity is marketplace-wide; per-merchant relationships are created automatically the first time they buy from a merchant. getMarketplaceCustomer returns the unified picture.
  • Unified split checkout. A single cart may contain items from several merchants. One marketplaceCheckout call creates one payment for the whole basket; after the shopper pays, each merchant is paid their share (gross minus commission) automatically. You never move money yourself.
Use the marketplace operator key for everything on this page (and for aggregated products/taxonomy/search reads). It’s a publishable key, safe for the browser. Merchant-side setup (a merchant connecting their payout account) and operator back-office (payout reports) are not part of this API — they happen in the admin apps.

The typical integration flow

A marketplace storefront usually wires up in this order:
  1. Identify the marketplacegetMarketplaceInfo() to get the name, logo, colors, and which capabilities are on.
  2. Browseclient.products.listProducts(), client.taxonomy.listCategories(), client.search.searchProducts() with the operator key for the aggregated catalog.
  3. Shop a single merchant (optional) — pass storeId to the reads above + getMarketplaceInfo({ storeId }) for that merchant’s shop page.
  4. Sign the shopper inclient.authentication.register / login (operator key) → you get a shopper session token.
  5. Build a cart client-side — collect line items, each tagged with its merchant_store_id.
  6. Check outmarketplaceCheckout() → returns a client_secret; complete the payment with Stripe.js on the storefront.
  7. Order confirmation / account — the order finalizes automatically on payment success; getMarketplaceCustomer() shows the shopper’s cross-merchant history.

Methods

getMarketplaceInfo

Read information about the marketplace. This is usually the first call your storefront makes. It has two modes, controlled by whether you pass storeId:

Mode 1 — Marketplace identity & branding (no storeId)

Returns the marketplace’s own name, branding, contact details, and which capabilities are enabled. Use it to render your storefront chrome (logo, colors, name) and to feature-detect (e.g. only show the fee line if commission_enabled).

Mode 2 — One merchant’s full store context (storeId)

Returns the same comprehensive payload as client.system.getStoreInfo, but for a single merchant inside the marketplace. This is what you render on a merchant’s shop page header — their business info, a catalog summary with a small sample of products, payment methods, shipping, CMS content, and feature flags — in one call. It’s also ideal as context for an AI shopping agent describing one merchant.
The catalog block returns counts plus a small sample of products (each with a few fields: id, name, category, price, image). It is intentionally not the full catalog — use client.products.listProducts({ storeId }) to actually browse and paginate a merchant’s products.
Parameters Responses

marketplaceCheckout

Check out a cart that may contain items from multiple merchants in one call. Each line item names the merchant it belongs to. Tybrite validates the items against the live marketplace catalog, resolves commission per merchant, and creates one payment for the entire basket. The response gives you a client_secret to complete the payment on the storefront (with Stripe.js) and a per-merchant merchant_breakdown (gross, discount, commission, net) you can display. You can also apply discounts. Pass an optional discounts array to apply a merchant’s own promotion or gift card to that merchant’s portion of the basket — each entry names a merchant_store_id and an optional promotion_id and/or gift_card_code, and the discount reduces only that merchant’s subtotal. Marketplace-wide promotions run by the operator apply automatically — you don’t pass them. The response then reports discount_total, the operator_funded_discount (the share the operator funded), a per-merchant discount_breakdown, and discount_amount + merchant_gross on each merchant_breakdown entry.
Once the payment succeeds, the order finalizes automatically — Tybrite creates each merchant’s order, splits the funds, reduces stock, and links the shopper to each merchant. You do not make any follow-up API call.
Stock is reserved at checkout. When you call marketplaceCheckout, the items are held against each merchant’s inventory immediately (so two shoppers can’t buy the last unit at once), and the hold is converted to a real stock reduction when payment succeeds. If an item can’t be held, the call fails with 400 insufficient_stock and no order or payment is created. Holds expire automatically (a short window) if the payment is never completed, returning the stock to availability — so an abandoned checkout never permanently locks inventory.
You don’t resolve commission separately. The merchant_breakdown in this response already contains the per-merchant gross/commission/net. (If you need to show fees on the cart page before checkout, compute them from your own displayed prices, or call checkout when the shopper is ready — there is no separate public commission endpoint.)
Request body Response (201)
Responses

getMarketplaceCustomer

Return a shopper’s unified marketplace profile — their identity, the merchants they’ve shopped with, and their cross-merchant order history — in one response. Use it for the shopper’s account page. This requires the shopper’s session token (from sign-in) in the X-Customer-Token header, in addition to the operator key.
Response (200)
Responses

Aggregated reads (the marketplace catalog)

You don’t use MarketplaceService for browsing — you use the normal services with the operator key, and they automatically aggregate across every active merchant. Each product/result carries its source merchant_store_id.

Single merchant “shop page”

To render one merchant’s storefront inside the marketplace, pass storeId (the merchant’s id) to the aggregated reads. Everything narrows to that one (active) merchant:

Reading a product’s reviews on the marketplace

With the operator key, you can read approved reviews for a product, but you must say which merchant owns it via storeId (required for operator keys). Submitting, deleting, or voting on reviews is still done with a shopper session, not the operator key.
storeId only narrows results when you use an operator key. With a single-store key it’s ignored (you’re already scoped to one store). On reviews, an operator key requires storeId and may only read approved reviews.

Returns on the marketplace

A return always belongs to one merchant — the merchant whose order is being returned. So with the operator key, every client.returns shopper action takes a required storeId (the merchant from the order) alongside the shopper’s session. A shopper’s returns are therefore per-merchant: to show “all my returns” across the marketplace, fetch each merchant the shopper ordered from and merge the lists in your storefront.
The same storeId applies to getReturn, acceptReturnCredit, and requestReturnRefund. The storeId must be an active merchant. See the Returns reference for the full method set and the store-credit flow.
This is a shopper acting on their own returns at one merchant. There is no cross-merchant “all returns” feed or store-credit-owed summary in the API — operator oversight of returns is a back-office concern, handled in the operator’s admin, not through the SDK.

Curated collections (homepage merchandising)

A marketplace operator can curate merchandising sections for the storefront — for example “Trending now”, “Featured shops”, or a seasonal promotion rail. Each section groups products, merchants, or promotions the operator hand-picked (or auto-curated) to merchandise the storefront. Use them to build your homepage. Two operator-key methods cover this: listMarketplaceCollections returns the sections, and getMarketplaceCollection returns one section’s resolved members. Curating the sections themselves is an operator back-office task in the Super Admin app — not part of this API.

listMarketplaceCollections — the storefront’s curated sections

Response

getMarketplaceCollection — one section’s members

Response

Blending curated collections with sponsored + organic

Curated collections, sponsored placements, and organic recommendations are complementary — a typical homepage interleaves all three. Fetch them together:

Advertising / sponsored placements

A marketplace storefront can show placements in named slots (a hero banner, a category strip, a search-results rail), blended in with your organic listings or recommendations. A slot returns two kinds of placement:
  • Sponsored (sponsored: true) — paid spots that promote a merchant’s products or shop. These must be rendered with their disclosure_label.
  • Curated fallback (curated: true, sponsored: false) — placements the marketplace operator hand-picks to fill a slot when no paid placement is available. These are not labelled as sponsored.
Two operator-key methods cover the whole storefront side: getAdSlot fetches what to show in a slot, and logAdEvent reports impressions and clicks. Booking placements, setting rates, and managing slot inventory are operator back-office tasks done in the Super Admin app — they’re not part of this API.
Paid placements carry a disclosure_label (for example "Sponsored"), and advertising-disclosure rules in most jurisdictions require it to be rendered wherever sponsored is true, so a shopper can distinguish it from an organic result. Curated fallback placements (sponsored: false) are not paid advertising and do not carry the label.

getAdSlot — what to show in a slot

Response
For a 'promotion' placement (or a promotion item in a curated collection), the payload gives you a promotion_id and a merchant_store_id. Fetch the promotion’s detail — and the products it features — with client.promotions.getPromotion({ id: promotion_id, storeId: merchant_store_id }). See PromotionsService → Getting the products in a promotion for how each promotion type (percentage / fixed / bundle / bogo) resolves its products.

Blending with organic recommendations

Sponsored placements sit alongside organic results, not in place of them. A common pattern is to fetch both and interleave:

logAdEvent — impression & click beacons

Fire one impression per placement when it becomes visible, and a click when the shopper clicks it. Beacons are fire-and-forget.
The response is { recorded: true, billable }. billable tells you whether the event counted toward billing after de-duplication and invalid-traffic filtering — it’s informational, so you don’t need to act on it.

What is NOT in this API

These are deliberately not SDK methods, because they’re administrative, not storefront actions:
  • A merchant connecting their payout account (Stripe Connect onboarding) — the merchant does this from their own admin/POS, not over the storefront API.
  • Running or viewing operator payout reports — the operator does this from the Super Admin app.
  • Setting commission rules / marketplace branding — configured by the operator in the Super Admin app; you only read the resulting branding via getMarketplaceInfo.
So the public marketplace surface is exactly: getMarketplaceInfo, marketplaceCheckout, getMarketplaceCustomer, listMarketplaceCollections, getMarketplaceCollection, getAdSlot, logAdEvent, plus the operator-key behavior of the catalog/search/auth/reviews/recommendations reads.

Putting it together — a minimal storefront


Error handling

All marketplace methods follow the standard response-code contract and throw a typed ApiError: