Skip to main content
A product bucket is a cross-platform container that groups equivalent products from different stores into a single, reusable unit. Instead of managing separate iOS, Android, and Stripe product IDs across every paywall, you define a bucket once — “Annual Premium,” for example — and assign it platform-specific products. Paywalls then reference buckets, and Helium resolves the right product for each user’s platform at runtime.

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
The API validates that you’ve provided at least one product and that you’re not mixing Stripe with iOS/Android.
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.
When a paywall is published, the bucket references are snapshotted onto the paywall version.
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.
Changes propagate to all paywalls using that bucket.
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_days on 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:
  1. The editor loads the paywall’s assigned buckets.
  2. Based on the selected territory and platform in the preview, Helium resolves the right product from each bucket.
  3. A products.tsx file is generated with localized prices, offer details, and product metadata.
  4. The live preview renders with real pricing data for the selected territory.
This means you can preview exactly what a user in Japan on iOS would see, versus a user in Germany on Android — all driven by the same bucket configuration.

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.
If duplicates are detected, you’ll be prompted to resolve the conflict before publishing.

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 a price_id.

Common Patterns