Skip to main content
Pricing plans define the subscription tiers available to customers. Navigate to Admin → Pricing (/admin/pricing) to manage plans, features, and FAQs.

Plan list

The pricing page shows all plans ordered by sort_order, with stats for total plans, active plans, total features, and total FAQs. Each plan card displays its name, monthly and yearly price, subscriber count, and active/inactive status.

Creating a plan

1

Click Add plan

Opens the plan creation form.
2

Fill in core details

FieldRequiredNotes
NameYesDisplayed to customers. Supports multiple locales (stored as JSON).
SlugYesURL-safe identifier, must be unique. Auto-generated from name if left blank.
DescriptionYesShort description shown on the pricing page.
Monthly priceYesIn dollars (e.g. 29). Stored internally in cents. Enter 0 for free plans.
Yearly priceNoIn dollars. Stored internally in cents. Leave blank if no annual billing.
SeatsNoMaximum number of seats for the plan.
Sort orderYesDetermines display order. Lower = earlier.
ActiveToggle to make the plan visible and available to subscribe.
PopularHighlights the plan with a “Popular” badge on the pricing page.
EnterpriseMarks the plan as an enterprise tier.
Discount textNoShort label shown near the price (e.g. “Save 20%”).
3

Set feature values

Every feature defined in the system must have a value for this plan. See Feature quotas below.
4

Save

The plan is created and, if Stripe credentials are configured, a Stripe product and prices are created automatically. A warning is shown if the Stripe sync fails — the plan is still saved locally.

Feature quotas

Features are defined in the features table and linked to plans via the plan_feature_values pivot table. Each feature has a slug that the application uses to enforce quota limits at runtime.

Quota fields on a plan

When creating or editing a plan, the following quota fields are available directly:
FieldFeature slugDescription
Agents quotaagentsMaximum number of AI agents the customer can create
Knowledge base quotaknowledge_basesMaximum knowledge bases
Phone numbers quotaphone_numbersMaximum phone numbers that can be imported
Batch calls quotabatch_callsMaximum concurrent or total batch calling jobs
Voice design quotavoice_designElevenLabs voice design credits
Instant voice clone quotainstant_voice_cloneInstant voice clone slots
Conversational AI minutesconversational_ai_minutesElevenLabs Conversational AI minutes per billing period
In addition to these direct quota fields, you must provide a value for every Feature record in the database via the feature_values array. Set the value to 0 to deny access to a feature, or a positive integer to allow that many units.

Free plans

A plan is considered free when its monthly price (price field in cents) is 0. Free plans:
  • Do not require Stripe product/price IDs.
  • Are excluded from gateway sync operations.
  • Still enforce feature quotas.

Editing a plan

Click the edit icon on a plan card. The form is identical to the creation form. If the monthly or yearly price is changed, the corresponding Stripe prices are updated automatically. Feature values are replaced in full on save — all existing PlanFeatureValue records for the plan are deleted and recreated from the submitted form data.

Enabling and disabling plans

Toggle the Active switch on the plan form, or use the quick-toggle action on the plan card. Inactive plans are hidden from the public pricing page and cannot be subscribed to. Existing subscriptions on an inactive plan are not affected.

Deleting a plan

Deleting a plan removes it from the database and archives the associated Stripe product. Existing subscriptions referencing the plan will lose their pricingPlan relationship.
Click Delete on the plan card. If the plan has a stripe_product_id, the Stripe product is archived first.

Gateway sync

Sync pushes plan pricing to all active payment gateways (Stripe, Razorpay, Paystack). Free plans (price 0) are skipped automatically.

Sync a single plan

Click Sync to gateways on a plan card. The system iterates over all active PaymentProvider records and calls the appropriate gateway SDK:
Creates or updates a Stripe Product with the plan name and description. Creates monthly and yearly Price objects if the respective prices are > 0. Stores the resulting IDs in stripe_product_id, stripe_monthly_price_id, and stripe_yearly_price_id.
Creates Razorpay Plans for monthly and yearly billing cycles. Razorpay credentials are validated before syncing — if the account is not activated or KYC is incomplete, the sync will fail with a descriptive error.
Creates Paystack plans for monthly and yearly billing cycles. Stores plan codes in paystack_monthly_plan_code and paystack_yearly_plan_code.

Sync all plans

Click Sync all plans on the pricing index page to sync every active paid plan across all active payment providers in one operation.

Check sync status

Use Check sync status to see which plans are missing gateway IDs and need to be synced.

Payment provider IDs stored per plan

ProviderFields on pricing_plans table
Stripestripe_product_id, stripe_monthly_price_id, stripe_yearly_price_id
Razorpayrazorpay_monthly_plan_id, razorpay_yearly_plan_id
Paystackpaystack_monthly_plan_code, paystack_yearly_plan_code

FAQ management

The pricing page also manages FAQs displayed on the public pricing page.
1

Add a FAQ

Click Add FAQ. Fill in Question, Answer, Locale (e.g. en), Sort order, and Active.
2

Reorder FAQs

Drag and drop FAQ rows or use the reorder endpoint to submit a new sort_order for each FAQ.
3

Edit or delete

Click the edit or delete icon on any FAQ row.

Import and export

Use the Export plans and Export FAQs buttons to download JSON exports. Use Import plans and Import FAQs to bulk-upload from a JSON file.

Build docs developers (and LLMs) love