Docs
Operate

Paid Public Flows

Quick Answer

To sell a flow today:

  1. Open the creator workspace billing page and complete seller payout onboarding.
  2. Open the flow's Publish page.
  3. Save the public listing, pricing or price catalog, and optional trial settings.
  4. Publish the current draft as the live buyer version.
  5. Verify buyer checkout from another workspace.

Example:

  • Seller onboarding: /<workspace-id>/billing
  • Flow publishing: /<workspace-id>/flows/<slug>/publish
  • Public app page: https://breyta.ai/apps/<flow-slug>
  • Buyer verification: sign in as a different workspace and open
    /<buyer-workspace-id>/discover

Breyta handles buyer checkout, Stripe webhooks, entitlement state, and payout routing.
The creator does not create Stripe Checkout Sessions, products, or prices manually.
The creator does need a seller account for their workspace so payouts can be routed correctly.

Paid publishing and seller payout setup are currently behind the
BREYTA_FLOW_REUSE_APPROVER_USER_IDS rollout gate. If the Publish page or
seller-payout controls are missing, confirm that the current user id is included
in that allow-list.

What Breyta Handles Vs What The Creator Handles

AreaBreyta handlesCreator handles
Buyer paymentsStripe Checkout Sessions, webhook delivery, checkout completion, entitlement stateNothing directly in Stripe Checkout
Seller payoutsConnected-account routing, payout transfer metadata, Connect account persistence on the workspaceCompleting Stripe onboarding and giving Stripe required payout details
Flow publishingRuntime install/check/run/release machineryAuthoring the flow, setting metadata, releasing the live version

Seller Onboarding (Once Per Workspace)

Breyta uses Stripe Connect seller accounts for creator payouts.
The current integration creates an Express connected account for the creator workspace and routes buyer payments to that account.

Creator onboarding path:

  1. Open /<workspace-id>/billing.
  2. In the seller payouts card, start or resume Stripe onboarding.
  3. Complete the Stripe-hosted onboarding flow.
  4. Return to Breyta. The billing page refreshes seller payout state through
    ?billing_refresh=seller.

The workspace is ready to sell when the Connect state is effectively active.
In sandbox validation, the ready state corresponded to:

  • charges_enabled=true
  • payouts_enabled=true
  • card_payments=active
  • transfers=active

If seller onboarding is incomplete, buyer checkout is blocked with:

  • Creator payouts are not configured for this flow

Operators can still use the admin Stripe Connect endpoints for diagnostics and
sandbox runbooks, but they are no longer the normal creator path.

Publish From The Flow

Use the dedicated Publish page for the flow:

/<workspace-id>/flows/<slug>/publish

The Publish page owns the creator-facing paid-flow controls:

  • public listing visibility for Discover/install surfaces
  • free, one-time, subscription, usage, or subscription usage pricing
  • optional price catalogs for multiple plans
  • subscription interval
  • before-install paid checkout
  • prepaid run-pack quantity for usage pricing
  • included runs for subscription usage pricing
  • optional subscription trial days
  • whether a trial requires a payment method
  • draft-to-live publishing
  • seller payout readiness
  • installs and checkout activity

For a paid flow:

  1. Make sure the flow has a saved draft.
  2. Open the Publish page.
  3. Choose One-time purchase, Subscription, Usage per run, or Subscription usage.
  4. Enter amount and currency.
  5. For subscriptions, choose the billing interval and optional trial settings.
  6. For usage pricing, enter the run-pack quantity. For subscription usage, enter included runs per billing period.
  7. Enable public listing.
  8. Save settings.
  9. Publish changes.

Public paid flows can include manual interfaces, schedules, and webhook
interfaces. End users manage automatic entrypoint enablement per installation.

The checkout path charges one-time purchases, subscriptions, prepaid usage
packs, and subscription-usage plans through Stripe Checkout. Usage packs and
subscription usage then rely on Breyta's run ledger for allowance tracking.
Trial-run packages can bypass Stripe first and start with a Breyta trial
entitlement when the selected pricing shape supports that path.
Advanced source/CLI workflows can still represent paywall.when explicitly.

Breyta's default public-flow platform fee is 5% plus 30 cents USD. One-time
USD checkout applies both components. Subscription checkout applies the
percentage component through Stripe Checkout; fixed subscription fee settlement
is tracked separately.

The publish action creates the live version buyers install. If the draft differs
from the live version, the page shows that the draft needs publishing.

Author Monetization In Source (Advanced)

The Publish page is the normal creator path. Source-first authoring remains
useful for code-reviewed flow definitions, fixtures, and CLI-heavy operations.
The flow file can carry marketplace monetization metadata directly, and
breyta flows push persists it. For new paid apps, author the catalog under
:marketplace {:app {... :monetization {:plans [...]}}}. Legacy flow-level
:marketplace {:monetization ...} is still supported for existing listings,
but new paid apps should use app-owned identity so Discover, checkout, billing,
and install ownership all use the same app id and plan ids.

Pricing Models

Choose the pricing type based on what the buyer is purchasing:

Pricing typeBuyer paysBuyer receivesTypical use caseRequired fields
:freeNothingFree install and run accessOpen tools, lead-gen flows, free templatespricing.type
:one-timeOne upfront paymentPaid access without recurring billingFixed-fee utility, template, or appamount, currency
:subscriptionRecurring monthly or yearly chargeAccess while the subscription stays activeSaaS-style app accessamount, currency, interval
:usageOne-time payment for a prepaid packA fixed number of successful runs with no time expiry"$100 for 500 runs"amount, currency, unit, included-quantity
:subscription-usageRecurring monthly or yearly chargeA fixed number of successful runs every billing period"$49/mo includes 22 runs"amount, currency, interval, unit, included-quantity

Operational rules:

  • :usage is prepaid packaging, not pay-as-you-go metering.
  • :usage packs do not expire by time; they are consumed only by successful completed runs.
  • :subscription-usage resets allowance on subscription renewal.
  • :subscription-usage does not currently bill paid overages. When included runs are exhausted, the buyer is blocked until renewal or a future product change.
  • Failed, cancelled, terminated, and timed-out runs do not consume paid allowance.

Trial Options

Supported trial shapes depend on the pricing type:

Pricing typeSupported trial
:one-timetrial.runs
:subscriptiontrial.days, optional trial.payment-method-required
:usagetrial.runs
:subscription-usagetrial.runs, or pricing.free-quantity as the fallback no-card trial-run allowance when explicit trial.runs is absent

Important trial details:

  • trial.days is the subscription-style time-based trial.
  • trial.runs is the run-counted trial.
  • pricing.free-quantity on :subscription-usage is a PLG-style fallback trial entry point, not a second paid allowance bucket.
  • If both trial.runs and pricing.free-quantity are present on :subscription-usage, explicit trial.runs wins.

Supported values:

  • pricing.type: :free, :one-time, :subscription, :usage, :subscription-usage
  • pricing.amount: positive price in major currency units. Decimals are allowed when the currency supports them, for example "0.99" USD.
  • pricing.currency: lowercase ISO currency code such as "usd"
  • pricing.interval: :month or :year for subscriptions and subscription usage
  • pricing.unit: :run for usage and subscription usage
  • pricing.free-quantity: zero or more free trial runs for :usage, or fallback no-card trial runs for :subscription-usage when trial.runs is not set
  • pricing.included-quantity: positive paid run quantity for :usage, or positive included runs per billing period for :subscription-usage
  • paywall.when: :before-install or :before-run for paid flows
  • trial.days: positive integer, optional
  • trial.payment-method-required: true or false, optional
  • plans: app-owned catalog entries under
    :marketplace {:app {:monetization {:plans [...]}}}. Every plan must
    normalize to a unique stable plan-id, every entry must be valid, and at
    most one plan can be marked default or recommended. If no default is set,
    the first plan is treated as the default.
  • Seat-based pricing is not implemented. Do not describe a plan as "N seats" or
    "N installs" unless the product has added explicit seat entitlements. Use
    run quantities only for usage-priced plans.

New app-owned source example:

{:slug :customer-insights
 :name "Customer Insights"
 :tags ["analytics" "customer-insights"]
 :discover {:public true}
 :marketplace
 {:visible true
  :app
  {:app-id "customer-insights-suite"
   :app-name "Customer Insights"
   :app-primary-flow-slug "customer-insights"
   :app-flow-slugs ["customer-insights"]
   :monetization
   {:plans
    [{:plan-id "starter"
      :name "Starter"
      :default true
      :pricing {:type "subscription"
                :amount 29
                :currency "usd"
                :interval "month"}
      :trial {:days 7
              :payment-method-required false}}
     {:plan-id "pro-pack"
      :name "Pro Pack"
      :pricing {:type "usage"
                :amount 49
                :currency "usd"
                :unit "run"
                :included-quantity 250}}
     {:plan-id "metered"
      :name "Metered"
      :pricing {:type "subscription-usage"
                :amount 99
                :currency "usd"
                :interval "month"
                :unit "run"
                :included-quantity 1000}}]}}}}

Use a single plan in the catalog for a one-price app. Existing legacy
flow-level examples with :marketplace {:monetization {:pricing ...}} remain
valid for preserving old listings.

Multi-Plan Catalogs

Use a plan catalog when a buyer should choose among multiple pricing options
for the same app, for example:

  • monthly vs annual subscription
  • starter vs pro tiers
  • subscription plus prepaid run-pack options
  • a recommended default plan with alternatives

Rules:

  • each plan must normalize to a unique stable plan-id
  • at most one plan can be marked default or recommended
  • existing buyer entitlements store the selected plan-id, so deleting or renaming active plan ids is risky and should be treated like a migration

Example:

{:slug :paid-flow-catalog
 :tags ["catalog"]
 :discover {:public true}
 :marketplace {:visible true
               :app {:app-id "paid-flow-catalog"
                     :app-name "Paid Flow Catalog"
                     :app-primary-flow-slug "paid-flow-catalog"
                     :app-flow-slugs ["paid-flow-catalog"]
                     :monetization
                     {:plans [{:plan-id "starter"
                               :name "Starter"
                               :default true
                               :pricing {:type "subscription"
                                         :amount 29
                                         :currency "usd"
                                         :interval "month"}}
                              {:plan-id "pro-pack"
                               :name "Pro Pack"
                               :pricing {:type "usage"
                                         :amount 100
                                         :currency "usd"
                                         :unit "run"
                                         :included-quantity 500}}
                              {:plan-id "metered"
                               :name "Metered"
                               :pricing {:type "subscription-usage"
                                         :amount 49
                                         :currency "usd"
                                         :interval "month"
                                         :unit "run"
                                         :included-quantity 22
                                         :free-quantity 5}}]}}}
 ...}

If you operate directly against /api/commands, the underlying monetization command is flows.marketplace.monetization.update.
For source-authored paid apps, prefer the app-owned catalog shape above. For
day-to-day creator work, prefer the Publish page so public listing,
monetization, and draft publishing stay in one place.

Publish Checklist

App path:

  1. Confirm seller payouts are ready on /<workspace-id>/billing.
  2. Open /<workspace-id>/flows/<slug>/publish.
  3. Save the public listing and paid-flow settings.
  4. Publish changes so the current draft becomes the live buyer version.
  5. Verify from another workspace.

Source/CLI path:

  1. Author the flow with descriptive metadata tags for the use case, audience,
    integration, and modality. Do not treat end-user as an installability
    requirement; existing legacy flows may still carry it as ordinary metadata.
  2. For a new paid app, add
    :marketplace {:app {... :monetization {:plans [...]}}} for paid behavior.
    Keep :marketplace {:monetization ...} only when preserving an existing
    legacy listing.
  3. Choose one marketplace visibility path:
    • source-first: add :marketplace {:visible true} in the flow file before push
    • explicit after push: run breyta flows marketplace update <slug> --visible=true
  4. Choose one discover visibility path:
    • source-first: add :discover {:public true} in the flow file before push
    • explicit after push: run breyta flows discover update <slug> --public=true
  5. Push the flow:
breyta flows push --file ./tmp/flows/<slug>.clj
  1. Run the explicit visibility commands if you chose the explicit path.
  2. Release a live version:
breyta flows release <slug> --release-note-file ./release-note.md
  1. Verify the buyer surface from another workspace.

Verify The Published Result

From the Publish page, check that:

  • seller payouts are ready for paid flows
  • availability is public
  • pricing and trial settings match the intended buyer offer
  • paid checkout is before install
  • the live version is up to date

From the CLI, use:

breyta flows show <slug> --pretty
breyta flows discover list
breyta flows discover search <query>
breyta flows readiness <slug> --target live --public --marketplace

Check for:

  • tags are descriptive metadata; installability comes from public visibility,
    marketplace visibility, and a released live version, not from an end-user tag.
  • marketplace.visible is true
  • marketplace.app.monetization.plans contains the intended pricing, paywall,
    and optional trial fields for new paid apps. Existing legacy listings may
    still report marketplace.monetization.
  • discover.public is true
  • the flow has an active released version
  • the public app page at https://breyta.ai/apps/<flow-slug> opens the
    intended buyer-facing app surface

Then verify the actual buyer experience from another workspace in the web app:

  • the flow appears in /:workspace-id/discover
  • the CTA matches one-time vs subscription vs trial behavior
  • checkout completes
  • the resulting installation state matches the paywall policy

Current Product State

The current publishing flow is real and creator self-serve.

Today:

  • seller onboarding starts from the workspace billing page
  • paid-flow publishing starts from the flow Publish page
  • the Publish page writes listing, pricing, trial, and live publish state
  • CLI/source metadata still works for scripted or code-reviewed publishing
  • paid publishing is gated by BREYTA_FLOW_REUSE_APPROVER_USER_IDS during rollout

Treat the app path as canonical for normal creator use, and the CLI/source path
as an advanced/operator path.

Related

As of May 21, 2026