Why Buckets?
Without buckets, every paywall would need to independently track product IDs for every platform. Buckets solve this by creating a single abstraction:- One bucket = one logical product across all platforms.
- Change a product ID in the bucket, and every paywall using it updates automatically.
- Paywalls reference buckets, not raw product IDs — keeping paywall configuration clean and portable.
Anatomy of a Product Bucket
The Product Map
The product map is the core of a bucket. It holds one product reference per platform:
A bucket doesn’t need all three platforms populated — a bucket with only an iOS product is perfectly valid. You add platform support as you expand.
Platform Isolation Rule
Stripe products and app store products (iOS/Android) cannot coexist in the same bucket. This is a hard constraint. Stripe paywalls serve a fundamentally different audience (web, Apple Pay) than native app store paywalls, so mixing them in one bucket would create ambiguity at resolution time. If you need both, create separate buckets:- Annual Premium — iOS + Android products
- Annual Premium (Stripe) — Stripe product
Lifecycle of a Product Bucket
1
Create
When you create a bucket, you provide:
- A name (must be unique per organization)
- At least one product on any platform
- An optional description
2
Assign to Paywalls
Paywalls reference buckets through a product_bucket_ids array. A single paywall can use multiple buckets — for example, a paywall offering both an annual and monthly plan would reference two buckets.Bucket assignment happens during:
- Paywall creation — Select buckets in the product selection step.
- Paywall editing — Add, remove, or reorder buckets on an existing paywall.
3
Add or Change Products
You can add, remove, or change individual platform products within a bucket at any time:
- Add a product — Attach a new platform’s product (e.g., adding Android support to an iOS-only bucket).
- Remove a product — Detach a platform’s product from the bucket.
- Move a product — Transfer a product from one bucket to another.
4
View Usage
From the bucket details view, you can see which paywalls currently reference a given bucket. This is useful before making changes — you can understand the blast radius.
5
Delete
Buckets can be deleted individually or in batch. Deleting a bucket removes it from any paywall’s bucket list. If a paywall relied solely on that bucket, it will have no products until you reassign.
Products and Pricing
Each platform product within a bucket carries its own pricing and offer information, pulled from the respective store:iOS (App Store Connect)
- Base price and territory-specific pricing
- Introductory offers: free trial, pay-as-you-go, pay-up-front
- Promotional offers and offer codes
- Offer eligibility is simulated per-territory in the paywall editor
Android (Google Play)
- Base plan pricing with regional configurations
- Per-base-plan offers: free trials, percentage discounts, fixed-amount discounts
- basePlanId is required for subscriptions (in-app purchases use a sentinel value)
Stripe
-
Price points tied to a specific
price_id -
Free trials via
trial_period_dayson the price -
Stripe products require a
price_id— the product UUID alone isn’t enough
How Buckets Work in the Paywall Editor
When editing a paywall, the bucket system drives the product preview:- The editor loads the paywall’s assigned buckets.
- Based on the selected territory and platform in the preview, Helium resolves the right product from each bucket.
-
A
products.tsxfile is generated with localized prices, offer details, and product metadata. - The live preview renders with real pricing data for the selected territory.
Duplicate Detection
Helium prevents the same product from appearing in multiple buckets on a paywall. Before publishing, a duplicate check runs across all buckets assigned to the paywall:- Same iOS product UUID in two buckets — blocked.
- Same Android product UUID + base plan in two buckets — blocked.
- Same Stripe product UUID + price ID in two buckets — blocked.
Key Rules
- Bucket names are unique per organization.
- Every bucket must have at least one product on any platform.
- Stripe and iOS/Android products cannot share a bucket (platform isolation).
- A paywall can reference multiple buckets (one per logical product offering).
- Changes to a bucket propagate to all paywalls using it.
- Duplicate products across buckets on the same paywall are blocked at publish time.
-
Android subscriptions require a
basePlanId; Stripe products require aprice_id.