Marketplace

The marketplace is where your finished product is discovered and subscribed to. As a builder you publish a listing for your package, describe and categorize it, gather reviews from the orgs that use it, and rely on a set of public, cached endpoints to bootstrap your client apps before anyone signs in. This page covers how to create and manage a listing, how reviews and subscriptions work, and the public discovery surface that powers your storefront.

Pro The marketplace is part of the SaaS Builder, included with the Backbuild Pro build-and-ship platform. See pricing.

The Publishing screen for a package. Callout 1 marks the current publish status with the Unpublish control. Callout 2 marks the requirements checklist (pricing plan, custom domain, branding, marketing page) that must be satisfied to publish and list the product.
Publishing gates a package behind a requirements checklist, then lists it for discovery. Unpublishing removes it from discovery without dropping existing tenants.

Two halves: public browse and managed listings

The marketplace has a deliberately split surface. One half is public and unauthenticated: the browse, plan, and bootstrap endpoints that prospects and running clients hit before they have a session. The other half is the authenticated management surface where you, the builder, create and edit your listing, and where subscribers post reviews and start subscriptions.

SurfaceAuthUsed by
Browse & discovery (GET /v1/marketplace/listings, /packages, /plans)None (rate-limited per IP)Prospects, marketing pages, plan pickers
Client bootstrap (GET /v1/marketplace/app-config, /build-config, /resolve-domain)None (cached)Your running apps before login
Listing management (POST/PATCH/DELETE /v1/marketplace/listings)Required + permissionYou, the builder
Reviews & subscriptionsRequired + permissionSubscribing organizations

Because the public half is open to anyone, it is rate-limited per client IP and validates every query parameter strictly; unknown parameters are rejected. You do not need to do anything special to benefit from this; it is on by default for the discovery surface.

Creating a listing

A listing is the public-facing entry for your product on the marketplace. It points at a template you own and carries the marketing metadata a shopper sees: title, description, category, tags, pricing summary, and screenshots. Create one with a POST; the listing is created under your organization and starts in a non-public state until you publish it.

POST /v1/marketplace/listings
Authorization: Bearer <token>
Content-Type: application/json

{
  "template_id": "019d3f6a-...-...",
  "title": "Acme Field Service",
  "description": "Scheduling, dispatch, and invoicing for field teams.",
  "category": "operations",
  "tags": ["scheduling", "dispatch", "invoicing"],
  "pricing_type": "subscription",
  "price_cents": 4900,
  "currency": "USD",
  "screenshots": [
    { "url": "https://cdn.example.com/shots/dashboard.png", "alt": "Dashboard" },
    { "url": "https://cdn.example.com/shots/dispatch.png", "alt": "Dispatch board" }
  ]
}

# Response (201)
{ "success": true, "data": { "...listing..." } }
FieldRequiredNotes
template_idyesThe template this listing publishes. Must be one your org owns.
titleyesDisplay title, 1–500 characters.
descriptionnoLong-form description, up to 10,000 characters.
categorynoA category key for filtering and grouping (up to 100 chars).
tagsnoUp to 50 free-form tags used for search and discovery.
pricing_typenoOne of free, one_time, or subscription.
price_centsnoHeadline price in the smallest currency unit (cents).
currencynoThree-letter ISO currency code, e.g. USD.
screenshotsnoUp to 50 screenshot entries shown in the listing gallery.

The headline pricing_type and price_cents are the summary a shopper sees on the listing card. The full set of purchasable tiers comes from your pricing plans, served separately through the public plans endpoint described below.

Listing status and publishing

A listing moves through a lifecycle: draft while you prepare it, pending_review once submitted, published when it is live and discoverable, and suspended if it is taken down. You move the listing forward by updating its status on the PATCH endpoint.

PATCH /v1/marketplace/listings/<listingId>
Content-Type: application/json

{
  "description": "Updated copy with the new dispatch features.",
  "tags": ["scheduling", "dispatch", "invoicing", "routing"],
  "status": "published"
}

Only published listings appear on the public browse surface. Updates take only the fields you want to change; at least one field is required.

Managing your own listings

To see your listings, including drafts and unpublished ones, use the management list. The public browse endpoint only ever returns published listings; the management endpoint defaults to showing all of your own listings across every status so you can find your drafts.

# Your listings (all statuses by default)
GET /v1/marketplace/listings/manage?status=draft&page=1&page_size=50

# Narrow to published only
GET /v1/marketplace/listings/manage?mine_only=false

To inspect a single listing by ID, supply the publisher organization it belongs to:

GET /v1/marketplace/listings/<listingId>?publisher_org_id=<yourOrgId>

Descriptions, screenshots, and categories

The descriptive metadata on a listing is what makes it findable and convincing. A few practical notes:

  • Description is long-form copy (up to 10,000 characters). Use it for the value proposition, key features, and who the product is for.
  • Screenshots populate the listing gallery. Each entry is a hosted image you point at by URL; provide a handful of representative views of the product in use.
  • Category places the listing in a single bucket used by the browse filter, while tags are a broader set of keywords that also feed search. A shopper can filter the browse list by category and sort the results.

The public browse endpoint accepts a free-text search, a category filter, and a sort of rating, newest, or downloads, so choosing accurate categories and tags directly affects where your product shows up.

# Public browse: published listings only
GET /v1/marketplace/listings?search=field+service&category=operations&sort=rating

Reviews

Organizations that use a product can leave a review: a 1-to-5 rating and optional text. Reviews are a discovery signal: the browse endpoint can sort by rating, so accumulated reviews influence your placement. A review is posted against a specific listing and its publisher organization.

POST /v1/marketplace/reviews
Content-Type: application/json

{
  "listing_id": "019d5c02-...-...",
  "publisher_org_id": "019d3f6a-...-...",
  "rating": 5,
  "review_text": "Cut our dispatch time in half."
}

As a builder you can list the reviews relevant to your organization, with an optional filter to a single listing:

GET /v1/marketplace/reviews?listing_id=<listingId>&page=1&page_size=50

Subscriptions

A marketplace subscription records that one organization has subscribed to a published listing. This is the lightweight marketplace-level subscription used for listing discovery and access, distinct from the metered, Stripe-backed plan subscriptions your tenants hold (covered under Tenants & Subscriptions and Payments).

POST /v1/marketplace/subscriptions
Content-Type: application/json

{
  "listing_id": "019d5c02-...-...",
  "expires_at": "2027-01-01T00:00:00Z"
}

The subscribing organization is taken from the authenticated session, so a subscriber cannot subscribe on another org’s behalf. You normally omit publisher_org_id; if you do send it, it must match the listing’s real publisher or the request is rejected, so a subscriber can never spoof who the listing belongs to. Cancel a subscription with its ID:

DELETE /v1/marketplace/subscriptions/<subscriptionId>

Public bootstrap endpoints

Before a visitor signs in, your client app still needs to know which product it is, how to brand itself, and which plans to offer. A set of public, unauthenticated, cached endpoints under /v1/marketplace provides exactly that. They are safe to call on every page load and are designed for fast first paint.

EndpointWhat it returns
GET /v1/marketplace/resolve-domainResolves a custom domain to the owning organization and package, so the client knows which product it is serving.
GET /v1/marketplace/app-configThe full application configuration (branding and presentation) for a domain or package, for pre-auth rendering.
GET /v1/marketplace/build-configPlatform-specific build configuration for a domain and platform: the settings a built client reads.
GET /v1/marketplace/plansThe published pricing plans for a package, for the signup plan picker.
GET /v1/marketplace/addonsAdd-ons applicable to a chosen main plan.
GET /v1/marketplace/packagesPublished packages: the general browse list, or the curated signup roll-up.

A typical client boot sequence fans out across several of these on the first page load: resolve the domain, pull the app-config to brand the page, then load plans for the signup picker.

# 1. Which product is this domain?
GET /v1/marketplace/resolve-domain?domain=app.yourproduct.com

# 2. Brand and configure the pre-auth UI
GET /v1/marketplace/app-config?domain=app.yourproduct.com

# 3. Plans to show on signup
GET /v1/marketplace/plans?saas_package_id=<packageId>&visibility=signup&page_size=100

Resolving a domain

Your apps are served from your own custom domains. The resolve endpoint maps a domain to the org and package behind it, so a generic client binary can figure out which product configuration to load. It returns 404 if the domain is not mapped.

GET /v1/marketplace/resolve-domain?domain=app.yourproduct.com
# (legacy alias: GET /v1/marketplace/resolve?domain=...)

App configuration

The app-config endpoint returns the full configuration used to render your product’s shell before login: theme, branding, and presentation. Supply either a domain or a package_id. The public variant is cached and serves the branding an anonymous visitor sees.

GET /v1/marketplace/app-config?domain=app.yourproduct.com
GET /v1/marketplace/app-config?package_id=<packageId>

Two variants are tenant-internal and therefore require an authenticated token whose organization matches the request: passing a subscriber_org_id (the per-tenant configuration) or draft=true (the pre-release configuration of a staged change). The plain public branding view needs neither and stays open.

Build configuration

The build-config endpoint hands a running client its platform-specific settings. Both domain and platform are required; platform is one of ios, android, windows, macos, linux, or web. See App Configurations & Builds for how these settings are produced.

GET /v1/marketplace/build-config?domain=app.yourproduct.com&platform=ios

Plans for signup

The plans endpoint serves the published, read-only pricing tiers a shopper picks from at signup. Pass the saas_package_id (either the package UUID or its package slug) and optionally visibility=signup to get only the curated signup set rather than your full catalog. The response carries the plans plus any promotions and grouping configuration, so the picker can render exactly as you intend.

# All published plans for a package (UUID or slug)
GET /v1/marketplace/plans?saas_package_id=<packageId>

# Curated signup set, full page of results
GET /v1/marketplace/plans?saas_package_id=acme-field-service&visibility=signup&page_size=100

Curation is advertising-only: the signup set narrows what is shown on the public picker, but your full catalog remains available for in-app upgrades. Add-ons (such as extra credit or storage) are picked after a main plan and come from the separate add-ons endpoint, which requires the package UUID.

GET /v1/marketplace/addons?saas_package_id=<packageId>&plan_slug=business-gold

Packages roll-up

To surface multiple of your packages on a single signup page, where a shopper first picks a product and then a plan within it, use the packages endpoint in signup mode with either your org_id or a domain. Without visibility=signup, the same endpoint returns a general published-package browse list with optional search and sort.

# Curated multi-package signup roll-up
GET /v1/marketplace/packages?visibility=signup&org_id=<yourOrgId>

# General published browse
GET /v1/marketplace/packages?search=field&sort=newest

Caching and rate limits

The public discovery and bootstrap endpoints set cache headers so they can be served fast and called on every load. Browse and plan responses carry a short public cache; app-config and build-config are cached longer. When you update your listing, plans, or branding, the cached configuration refreshes for the domains pointing at your package. The public surface is also rate-limited per client IP to keep enumeration and abuse in check; legitimate browsing, which fans out across several of these endpoints per page, sits comfortably inside the limit.

Permissions

Listing writes are permission-gated within your organization: creating, updating, and deleting a listing each require the corresponding marketplace permission, posting a review requires the review permission, and subscribing or cancelling requires the subscribe permission. Every write is scoped to your organization and audit-logged with the acting user. A caller without the right permission receives a 403; an unknown listing or subscription returns a 404; a subscriber that supplies a mismatched publisher is rejected as a client error.

API reference

Public: browse & discovery (no auth)

Method & pathDescription
GET /v1/marketplace/listingsBrowse published listings. Optional search, category, sort (rating, newest, downloads).
GET /v1/marketplace/packagesList published packages. search + sort (newest, name); or visibility=signup with org_id or domain for the signup roll-up.
GET /v1/marketplace/plansPublished pricing plans. saas_package_id (UUID or slug), visibility (all, signup), page, page_size (max 100).
GET /v1/marketplace/addonsAdd-ons for a chosen plan. saas_package_id (required), optional plan_slug, page, page_size.
GET /v1/marketplace/resolve-domainResolve a custom domain to org + package. Legacy alias: GET /v1/marketplace/resolve.
GET /v1/marketplace/app-configApp configuration for a domain or package_id. subscriber_org_id / draft=true variants require a matching auth token.
GET /v1/marketplace/build-configBuild configuration. domain + platform required.
GET /v1/marketplace/build-targetsActive build targets. Optional domain, platform, org_id, environment.

Authenticated: listing management

Method & pathDescription
POST /v1/marketplace/listingsCreate a listing. Body: template_id, title, optional description, category, tags, pricing_type, price_cents, currency, screenshots. Responds 201.
GET /v1/marketplace/listings/manageList your org’s own listings (all statuses by default). Optional mine_only, page, page_size, search, category, status, pricing_type.
GET /v1/marketplace/listings/:idGet one listing. Requires publisher_org_id.
PATCH /v1/marketplace/listings/:idUpdate a listing (any subset of the create fields plus status).
DELETE /v1/marketplace/listings/:idDelete a listing.

Authenticated: reviews & subscriptions

Method & pathDescription
POST /v1/marketplace/reviewsCreate a review. Body: listing_id, publisher_org_id, rating (1–5), optional review_text. Responds 201.
GET /v1/marketplace/reviewsList reviews for your org. Optional listing_id, page, page_size.
POST /v1/marketplace/subscriptionsSubscribe to a published listing. Body: listing_id, optional publisher_org_id (must match if sent), expires_at. Responds 201.
DELETE /v1/marketplace/subscriptions/:idCancel a marketplace subscription.

Related: SaaS Packages (publishing a package), Pricing Plans (the tiers served on the plans endpoint), App Configurations & Builds (what app-config and build-config deliver), and Store & App Distribution (publishing native builds to the app stores). Full request/response schemas are in the API Reference.

Frequently asked questions

How do prospects discover my product?
Through public browse of published listings, with search, category, and sorting by rating, newest, or downloads. Only published listings appear publicly.
Do reviews affect where my product ranks?
Customers can leave a rating and text review, and reviews inform how listings sort in discovery.
Is a marketplace listing the same as my pricing plans?
No. A marketplace listing is discovery-level. The plans customers actually subscribe to and pay for are defined separately. See Pricing Plans.
Does a listing show up before I publish it?
No. A listing moves through draft and review states and appears publicly only once published.