Plans & pricing
The four plans, exact limits, feature rows, and page copy — all from `priv/repo/seeds/plans.exs`, `lib/chatbotgen/features.ex`, and `App/Billing/Plan/Index.jsx`.
The billing page at /app/billing lists every plan, a comparison table, and a short FAQ. This doc reflects what's literally in the three source files that power it.
Page header
- Eyebrow: BILLING
-
: Choose a plan that scales with you - Subtitle: "Every paid plan starts with a 7-day free trial. Cancel anytime, no questions asked."
Top-right buttons:
-
See my usage (ghost) →
/app/usage -
Manage subscription (outline) — rendered only if
subscriptionis present. Clicking firesrouter.post("/app/billing/portal").
Current-plan strip
Below the header. Two variants:
Without a subscription (verbatim):
You're on Free. Upgrade anytime for more chatbots, messages, and AI tools.
With a subscription:
Current plan: {currentPlanName}
Additionally:
-
If
subscription.status === "trialing", a small amber Free trial pill is shown -
If
subscription.current_period_endis present, "Renews {Mon D, YYYY}" is appended
The four plans (verified from priv/repo/seeds/plans.exs)
| Plan | sort_order | Price (cents) | Interval | Chatbots | Documents | URLs | Messages/mo | Chars trained |
|---|---|---|---|---|---|---|---|---|
| Free | 0 | 0 | month | 1 | 3 | 5 | 50 | 400,000 |
| Starter | 1 | 2,900 | month | 3 | 20 | 50 | 2,000 | 2,000,000 |
| Growth | 2 | 7,900 | month | 10 | 100 | 200 | 10,000 | 11,000,000 |
| Business | 3 | 19,900 | month | 50 | 200 | 500 | 30,000 | 40,000,000 |
All four are interval "month". No yearly plans exist in the seed.
The seed comment captures the training-limits philosophy (verbatim):
max_chars_trainedis the PRIMARY / binding constraint (enforced before ingest)max_trained_documents/max_trained_urlsare loose OPERATIONAL caps only (they protect the Oban queue, PDF/DOCX parser, crawl throughput). The UI de-emphasises these counters in favour of the chars bar.
Plan card copy
Each card shows a one-line pitch (verbatim from PLAN_COPY in Plan/Index.jsx):
- Free — "For kicking the tires. Not for production."
- Starter — "For solo founders adding a chatbot to one site."
- Growth — "For businesses closing leads on autopilot." + Most popular badge
- Business — "For teams with multiple bots and serious volume."
Only Growth has a badge. The card body shows:
-
{plan.name} - Pitch
- Price: "$NN / month" for paid plans, Free for Free
-
Bullet list:
{max_chatbots} chatbot(s),{max_messages} messages/mo,{max_chars_trained} training chars(formatted with K / M suffixes) - Plus one bullet per feature enabled on this plan (see below)
Action button on each card
Verified from PlanCard:
- If it's the current plan: a disabled-looking Current plan pill (no action)
-
Otherwise a Button whose label depends on state:
- With an existing subscription, clicking Free: Downgrade
- With an existing subscription, any other plan: Switch to {plan.name}
-
Without a subscription, and
plan.trial_period_days > 0: Start {N}-day trial - Without a subscription, Free: Stay on Free
- Without a subscription, any other paid plan: Start free trial
All buttons fire router.post("/app/billing/checkout", { price_id: plan.stripe_price_id }).
Feature gates (verified from lib/chatbotgen/features.ex)
The @min_sort_order map:
| Feature key | Min sort_order | First plan that has it |
|---|---|---|
whatsapp |
0 | Free |
telegram |
0 | Free |
custom_branding |
1 | Starter |
tools |
2 | Growth |
handoff |
3 | Business |
priority_support |
3 | Business |
Each plan's features map is generated by Features.features_for_plan/1 at seed time and re-derived by the JSON serializers at runtime.
Display labels (verbatim from FEATURE_LABELS in Plan/Index.jsx)
-
whatsapp→ WhatsApp integration -
telegram→ Telegram integration -
tools→ AI Tools (lead capture, booking, email, webhooks) -
handoff→ Human handoff -
custom_branding→ Remove ChatbotGen branding -
priority_support→ Priority support (24h SLA)
Trust row (3 cards)
Verbatim:
- 7-day free trial — "Every paid plan includes a full week of access — no charge until day 8."
- Cancel anytime — "One click in the customer portal. Keep access through the end of the billing period."
- Upgrade or downgrade — "Change plans mid-cycle with prorated credits. We'll never lock you in."
Comparison table
Heading: Compare every feature. Subtitle: "The honest breakdown. No asterisks."
Rows (in this order):
- Chatbots
- Messages / month
- Training content
- Documents / bot
- URLs / bot
- WhatsApp integration
- Telegram integration
- AI Tools (lead capture, booking, email, webhooks)
- Human handoff
- Remove ChatbotGen branding
- Priority support (24h SLA)
Feature cells render ✓ when the plan has the feature, — when it doesn't.
Common questions (FAQ — verbatim)
- What happens if I hit my message limit? — "Your chatbot keeps running but will reply with a friendly 'please try later' message to new visitors until the next billing period — or until you upgrade."
- What counts as a 'training character'? — "Every character of the content you feed your chatbot — URLs crawled, files uploaded, Q&As, and text sources. We measure the raw text, not images or HTML."
- Can I switch plans later? — "Yes. Upgrade instantly (prorated) or downgrade at the end of the cycle. No hidden fees, no contracts."
- Do you offer a free tier? — "Yes — Free forever, 1 chatbot, 50 messages/month, 400K training chars. Great for testing. Production customers typically start on Starter."