Paywalls & experiments
Configure which products your paywall shows from the dashboard (no app release) and A/B test two layouts to see which converts. Your app asks for the current offering at runtime; EntitleHub decides what to return.
Offerings & packages
- Offering: a named lineup you show on a paywall (e.g.
default,black_friday). One is current. - Package: one purchasable option in an offering (e.g.
monthly,annual,lifetime), pointing at a store product.
Create them in Dashboard → Paywalls. Because the app fetches the lineup at runtime, you can swap products, reorder, or launch a promo offering without shipping an update. The durable entitlement mapping still lives in the engine, a package just references a product by id.
Fetch the current offering
GET /v1/offerings/current?app_user_id=USER_ID
Authorization: Bearer pk_live_…
200 OK
{
"identifier": "default",
"display_name": "Default",
"is_current": true,
"packages": [
{ "identifier": "annual", "store": "app_store", "store_product_id": "pro_annual",
"product": { "display_name": "Pro (Annual)", "type": "subscription",
"price_micros": 49990000, "currency": "USD", "entitlements": ["pro"] } }
]
}Render a button per package (price/title come from the resolved product), then pass its store_product_id to your SDK's purchase(). GET /v1/offerings/all returns every offering. Returns 404 when no offering is configured.
Include app_user_id so experiments can assign a variant (below). Without it you always get the plain current offering. The mobile SDKs pass it for you when you configure an app user.
A/B experiments
Start an experiment in Dashboard → Paywalls → Experiments: pick a control offering, a treatment offering, and the % of users routed to treatment. From then on, GET /v1/offerings/current?app_user_id=… returns the variant that user is assigned to, tagged so you can log exposure:
{
"identifier": "black_friday",
"packages": [ /* … */ ],
"experiment": { "identifier": "price_test_q3", "variant": "treatment" }
}- Deterministic: a given
app_user_idalways lands in the same variant, across sessions and devices. - Conversion: measured per variant (share of exposed users who become entitled) on the experiment card.
- One experiment runs per app at a time; stopping it keeps the results.
Experiments work through the same /v1/offerings/current call, if your app already fetches the current offering with an app_user_id, it's already experiment-ready.
