Plans
The Plans view is where operators define the subscription tiers Lumio offers — their pricing, the numeric limits they impose, and the feature grid that maps plan tier to feature availability. Every account is tied to exactly one plan; the plan's defaults cascade through the system unless an account has an override (see Accounts).
Where to find it
Admin sidebar → Plans (/plans). Detail pages live at /plans/\{id\}.
Quick start
- Open Admin → Plans to see the list.
- Click a plan (e.g.
pro) to open its detail page. - Review pricing, numeric limits, and the Feature Grid at the bottom.
- Toggle individual features ON/OFF for this plan via the This Plan ON/OFF column.
- Save — the change propagates to every account on the plan that does not have a per-account override.
Detailed walkthrough
Plans list (/plans)
Columns:
- Name — display name (e.g. "Pro").
- Slug — machine identifier (
free,pro,enterprise). - Monthly / Yearly — Stripe price display.
- Overlays — max overlays allowed.
- Integrations — max integrations allowed.
- Visibility — Public or Hidden.
- Order — sort position in public pricing pages.
Plan detail (/plans/[id])
Multiple sections:
- Slug / Description — plan identity.
- Price (Monthly) / Price (Yearly) — Stripe-linked prices.
- Plan Limits — numeric fields: Max Overlays, Max Storage, Max Upload Size, Max Integrations, Chat Retention (days).
- Feature Grid — "Manage global feature flags and plan-specific feature assignments." Rows for every feature flag with four columns:
- Feature — name.
- Global ON/OFF — the global kill-switch state (from Feature Flags).
- Default for Accounts — the global default-on flag for new accounts.
- This Plan ON/OFF — the plan-level opt-in for this specific plan.
Changes in This Plan ON/OFF write via PUT /api/plans/\{id\}/features. Changes in Global ON/OFF / Default for Accounts write via PUT /api/feature-flags/\{flagId\}/detail and also affect every other plan.
Visibility
Plans with visibility = hidden are not shown on the public pricing page but can still be assigned via the admin Accounts view. Typical uses: grandfathered legacy plans, enterprise-only tiers negotiated per-customer.
Common scenarios
- Raise the upload limit for Pro — open
pro, changemax_upload_size_bytes, save. Every Pro account without a per-account override picks up the new cap. - Ship a new beta feature to Enterprise only — set the feature to
ONon the Enterprise plan's This Plan ON/OFF column, leave itOFFfor Free and Pro, and ensure the Global ON/OFF is enabled. - Sunset a plan — set visibility to Hidden; existing accounts stay, pricing page no longer offers it.
- Apply a global kill-switch — toggle Global ON/OFF for a feature; every plan is overridden to off regardless of per-plan settings.
Permissions
| Action | Permission |
|---|---|
| View plan list / detail | plans:read |
| Create a plan | plans:create |
| Edit plan fields / feature assignments | plans:edit |
| Delete a plan | plans:delete |
| Edit feature-flag detail rows | feature-flags:edit |
Dashboard entry requires admin:access. System admins implicitly hold all of the above.
API
| UI action | GraphQL | REST |
|---|---|---|
| List plans | adminPlans / public plans query | GET /v1/plans and GET /v1/admin/plans |
| Create plan | adminCreatePlan | POST /v1/admin/plans |
| Update plan | adminUpdatePlan | PATCH /v1/admin/plans/\{id\} |
| Delete plan | adminDeletePlan | DELETE /v1/admin/plans/\{id\} |
| Update plan features | adminSetPlanFeature | PUT /v1/admin/plans/\{id\}/features |
| Feature-flag detail list | adminFeatureFlagsDetail | GET /v1/admin/feature-flags/detail |
| Feature-flag detail update | adminUpdateFeatureFlagDetail | PUT /v1/admin/feature-flags/\{id\}/detail |
Plan CRUD
The admin UI supports the full create / edit / delete lifecycle for plans, in addition to editing the seeded tiers. Every operation is exposed via both GraphQL and REST; see GraphQL and REST for full schemas.
Permissions
| Action | Permission |
|---|---|
| List / view plans | plans:read |
| Create a plan | plans:create |
| Edit a plan | plans:edit |
| Delete a plan | plans:delete |
System admins implicitly hold all four. The admin UI hides every action whose permission the caller does not hold.
Create flow
Use Plans → New Plan to open the create dialog.
- Slug is required and immutable. It must match the regex
^[a-z0-9]+(?:-[a-z0-9]+)*$(lowercase letters, digits, single dashes between segments) and be 2 to 40 characters long. Examples:free,pro,enterprise-legacy. Slugs must be globally unique — duplicates return409 Conflict(REST) or a"Plan slug already in use"GraphQL error. - Name, prices, numeric limits, visibility, and sort order all mirror the editable fields on the detail page.
- Stripe IDs (
stripe_product_id,stripe_monthly_price_id,stripe_yearly_price_id) are optional. Lumio does not auto-create Stripe products. Create the Stripe product and prices manually in your Stripe dashboard, then paste the IDs into these fields so that billing flows can reference them. - On success, the new plan is created with an empty feature assignment set. Use the Feature Grid on the detail page to enable features for the new plan.
Edit flow
Open the plan detail page at /plans/\{id\} and edit any field except the slug.
- The slug is immutable after creation. If you need a different slug, create a new plan and migrate accounts to it, then delete the old one.
- Saving the form calls
adminUpdatePlan/PATCH /v1/admin/plans/\{id\}, which rewrites all editable fields and then invalidates the feature cache for every account currently on the plan. The new limits and prices take effect on the next request from those accounts — no restart required. - Changes to Stripe IDs here only update the reference in Lumio. Price changes in Lumio do NOT update Stripe. If you change a price, update the Stripe product/price in your Stripe dashboard and paste the new price ID into the corresponding field.
Delete flow
From the plan detail page (or the list row), use Delete Plan.
- Deleting a plan is blocked when any accounts still reference it. The API returns
409 Conflictwith the message"Cannot delete plan: N account(s) still reference it. Migrate them to a different plan first."Move those accounts to another plan (see Accounts) and retry. - When the plan has no accounts attached, deletion cascades through the
plan_featuresforeign key and removes every per-plan feature assignment automatically. No other data is affected. - Deletion is permanent. Slugs of deleted plans can be reused by new plans.
Stripe integration
Lumio treats Stripe IDs as manually managed references. The admin UI does not call the Stripe API to create or mutate products or prices.
- Create products and prices in your Stripe dashboard first.
- Paste the Stripe
productID intostripe_product_idand thepriceIDs (monthly + yearly) into the matching fields on the plan. - Price changes in Lumio (
price_monthly,price_yearly) only update the display price shown on marketing pages. They do not reprice any Stripe subscription. To change what subscribers pay, update the price in Stripe, create a new Stripe price if needed, and paste the new price ID into the plan. - Removing a Stripe ID from a plan (setting it to empty) disables checkout flows that depend on it until a new ID is pasted back.
Tips & gotchas
- Effective feature state for an account is the AND of: Global ON × Plan ON × not-explicit-account-override-off. If any of those are off, the feature is off for the account.
- Stripe prices are maintained in Stripe; this page only references them. Creating a brand-new plan tier requires an accompanying Stripe product + price.
- Chat Retention is in days.
0means "keep forever" — confirm with the data-retention policy before setting that. - Hidden plans still appear in Subscriptions and Accounts.
Related
- Feature Flags — global kill-switches
- Accounts — per-account plan and limit overrides
- Subscriptions — which accounts are on which plan
- Coupons — discounts against these plans