createMembershipPlan
Launch a new membership tier by creating a subscription plan. Set pricing, visibility, and billing for paid, free, or claim profiles.
Instructions
Create a membership plan - Create a new membershipplan record. Writes live data.
Use when: launching a new plan tier. Rare - usually configured in BD admin UI. Check profile_type carefully: paid, free, or claim - changing later affects billing and visibility.
Required: subscription_name, profile_type.
Pre-check before create: BD does NOT enforce uniqueness on subscription_name. Duplicate plan names confuse admins at signup-form configuration, billing reports, and member migration. Do a server-side filter-find: listMembershipPlans property=subscription_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateMembershipPlan, OR ask the user, OR pick an alternate subscription_name and re-check. Never silently create a duplicate.
Enums: payment_default: yearly, monthly.
Parameter interactions:
subscription_type- typicallymemberfor standard member plansprofile_type:paid,free, orclaim- controls how profile visibility and billing workmonthly_amount/yearly_amount- price in the site's currencysub_active=1makes the plan available for new signups;sub_active=0grandfathers existing members onlysearchable=1makes members on this plan findable in public search
See also: updateMembershipPlan (modify existing).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| subscription_name | Yes | ||
| subscription_type | No | Internal role identifier - distinct from `profile_type`. Default `"member"` (applied when omitted). Valid values NOT publicly documented by BD. **Omit on create** unless BD staff or admin UI gave you an authoritative value. For plan monetization model (paid/free/claim-listing) use `profile_type`, NOT this field. | member |
| profile_type | Yes | Plan monetization model. Documented values: `paid`, `free`, `claim`. **BD does NOT validate server-side** — values outside this set are stored verbatim with undefined render behavior (live observed: `"individual"` accepted on prior writes). Stick to documented values. | |
| monthly_amount | No | ||
| yearly_amount | No | ||
| sub_active | No | Plan availability for NEW signups: - `1` = active (plan appears on public signup pages; new members can join) - `0` = inactive (plan hidden from new-signup flows; existing members on this plan keep it — grandfather behavior) Use this to retire a plan cleanly. Do NOT hack the signup widget markup to hide a plan. | |
| searchable | No | Whether members on this plan appear in public member search results. `1`=visible in search, `0`=hidden. Use this to hide a membership tier from public listings without deactivating billing. | |
| search_priority | No | Search-result display priority (integer). **Lower number = higher in results.** NOT a 0/1 boolean - numeric value determines ordering. - `0` = highest priority (top of public search results) - `1`, `2`, `3`, ... = progressively lower Use `0` for featured/premium tiers that must appear first. Higher numbers for standard/budget tiers. No upper bound. | |
| payment_default | No | ||
| subscription_filename | No | Optional URL slug for this plan's public page. Must be site-wide unique — duplicates cause URL routing conflicts. Pre-check with 5 filtered `list*` calls (each `property_value=<proposed>&property_operator==`): `listMembershipPlans`+`subscription_filename`, `listTopCategories`+`filename`, `listSubCategories`+`filename`, `listWebPages`+`filename`, `listUsers`+`filename`. Any hit = taken. Safe to leave blank. | |
| custom_checkout_url | No | Optional custom checkout URL for this plan. Stored in `users_meta` (`database=subscription_types`, `key=custom_checkout_url`); BD auto-routes extra non-direct-column fields to users_meta on create. Must be unique across plans. Pre-check: `listUserMeta(database="subscription_types", key="custom_checkout_url")` then client-filter for any row whose `value` matches yours. Any hit = taken. Safe to leave blank. |