Pricing one product at a single price almost always leaves money on the table. Some customers would happily have paid more for more; others never bought at all, because the only thing on offer was the full package at the full price when a lighter, cheaper version would have won them over. The standard answer is older than software itself: sell the same thing at several levels. Standard, Gold, Platinum. Lite, Pro, Studio. Good, better, best. It works in cars, in coffee, and in plugins.
On a pricing page this is trivial — three columns, three prices, a row of checkmarks. The interesting question is everywhere else: how does one product become three products without becoming three codebases? Ship three separate builds and you have tripled your release, QA and support burden for what is, underneath, the same software. Branch on the price list inside your code and you have wired your engineering to your marketing in a way that bites the first time someone renames a SKU. The clean answer is a small, stable concept that sits between the two — a version, also called an edition. This guide is about what editions buy you commercially, what it means for your licensing system to actually carry them, and the one property that makes the whole thing hold together as your catalog grows.
Good, Better, Best: The Oldest Trick That Still Works
Tiered pricing is not a gimmick; it is how you capture a range of willingness to pay with a single product. A flat price forces every customer through one gate. A tiered line gives you a low entry point that converts the price-sensitive buyer, a flagship tier that lets the high-intent buyer spend what they were always willing to spend, and a middle tier that — by simply existing — makes the flagship look reasonable. The same code, sold three ways, reaches three audiences it could not reach as one.
In audio software this is everyday reality, and it maps cleanly onto the JUCE and plugin world. A synth ships Lite for the hobbyist and Pro for the studio. A channel strip ships Standard with the core modules and Platinum with the full processing chain unlocked. The feature line between the tiers is a marketing decision — which modules, which presets, how many voices, which export formats — and it can move whenever you want it to, because it is a decision about what the same binary turns on, not about which binary you shipped. Editions are simply the mechanism that lets one build serve the entire ladder, so that adding, removing or repositioning a tier is a catalog change rather than a code change.
The Hard Part Isn’t Pricing — It’s Shipping
The reason editions deserve a guide of their own is that the obvious ways to build tiers are all traps.
The first trap is separate builds. You compile a Lite binary and a Pro binary from the same source with different flags, sign them separately, distribute them separately, and now every release is three releases. A bug fix has to be carried across all of them; a customer who upgrades from Lite to Pro has to download and reinstall a different artifact; your support team has to ask which build someone is running before they can answer a question. You have turned a pricing tier into a distribution problem.
The second trap is subtler and more common: branching on the catalog. The build is single, but somewhere in the code there is logic that says if this license is for the “Gold” SKU, unlock the Gold features. It looks harmless and works fine — right up until marketing renames Gold to Professional, or splits it into a regional SKU and a campaign SKU, or retires it and replaces it with something priced differently. Every one of those is a normal commercial move, and every one of them now risks breaking feature gating in binaries that are already on customers’ machines. You cannot patch a shipped build retroactively, so the code’s knowledge of your price list quietly becomes a liability that ages badly. The whole point of an edition is to give you the upside of tiering without either trap: one binary, and a feature switch that does not depend on the catalog at all.
What It Means for the License Manager to Carry the Edition
This is where the licensing layer earns its place. An edition is only useful if the license itself tells the application which feature set to unlock — otherwise you are back to building it by hand. In KEYZY, a version is exactly that: a stable label that travels with the license. It has two parts, a human-readable label like Gold and a short, fixed code like gold, and your application only ever reads the code. Every product starts with a default Full edition (code full) until you define more, so the simple case costs you nothing and the tiered case is there when you need it. The full mechanics live in the Versions (editions) concept page; I’ll keep this to what matters for the argument.
The crucial design choice is where the edition gets attached. It is not baked into the product, and it is not hard-coded into the build. It is decided where the product meets the SKU — when you place a product into a sellable catalog entry, you choose the edition it ships with there. The customer activates one serial, KEYZY resolves SKU → product → version, and the license your application receives already contains the right edition code. On the device, your code reads it and branches once:
std::string version = pValidator->getVersion(); // e.g. "gold"
if (version == "gold") {
// unlock Gold features
}
The same value comes back as version_code on the REST validate response, so online and server-side flows branch on it too. One binary, shipped once, and the license decides what to turn on. The license manager carrying the edition is what turns “good, better, best” from a build-system chore into a catalog setting.
The Edition Code Doesn’t Know Your Catalog
Here is the property that makes all of this hold together, and it is the part worth slowing down for. The edition code is deliberately decoupled from the SKU. Your code commits to gold once and trusts it unconditionally; KEYZY guarantees that whatever SKU a customer bought, the license carries the right code. That decoupling runs in both directions, and both directions matter.
In one direction, a SKU can be renamed, repriced, retired and replaced as often as your marketing wants, and none of it touches your binary. The SKU number and name are catalog data — they are meant to change. Because your application reads the code and never the SKU, a rename is just a rename. There is no shipped build anywhere that cares.
In the other direction — the one that tends to be undersold — one edition can live across many SKUs. The same gold code might back a dozen different SKUs at once: a standard-price SKU, a regional SKU, a bundle SKU, a campaign SKU, a renewal SKU, a dealer SKU. To your code they are all simply gold. This is the part I’d most want you to take away: you provide the version code in the binary, and whoever packages it for sale — you, your marketing team, or a dealer reselling on your behalf — can ship that product through whatever SKUs the business needs, on whatever channels, at whatever prices, without changing a line of code. The alternative, branching on the catalog, would force your application to know every SKU name that counts as “gold” and keep that list in sync forever as SKUs are added, renamed and retired. That is manageable for one SKU and a maintenance nightmare across a growing catalog. An edition collapses the entire list back into a single stable code. The contract is the code; the catalog is free to move around it.
Editions and Bundles
The same independence is what lets editions and bundles compose without any special handling. A bundle in KEYZY is a single SKU that carries several products, and because an edition is attached where a product meets a SKU, each product in a bundle can ship at whatever edition that bundle is meant to represent — the same gold code your code already checks, now arriving via a bundle SKU instead of a single-product one. There is nothing new for your application to learn. The full treatment of how bundles work as a license-layer object lives in its own guide, Bundles That Belong in Your License Layer, Not Your Cart; if you sell tiers and bundles, it’s worth reading alongside this one.
Ship Once, Sell Many Ways
Step back and editions are about keeping two things that move at different speeds from being chained together. Your catalog moves fast: prices change, SKUs are renamed and retired, regions and campaigns and bundles come and go, tiers get repositioned as you learn what sells. Your shipped binaries move slowly and, once they are on a customer’s machine, not at all. The mistake is to let the fast layer reach into the slow one — to make code that you cannot easily change depend on a price list that you change all the time.
An edition is the thin, stable seam between them. Marketing gets to run the full good-better-best playbook — add a tier, rename one, regionalize, bundle, discount, retire — and engineering gets to ship a single binary that reads one fixed code and trusts it forever. This is the model KEYZY is built around: a version code that is yours to commit to once, deliberately ignorant of the catalog churning around it, so that you can sell one product a dozen ways and never once recompile to do it. Ship once; sell many ways. The edition is what makes the second half of that sentence free.