Pricing & Plans¶
CTFHive's plans are defined in a single source of truth: CTF_Saas_CTRL_Pane/ctrlapp/pricing.py. The marketing templates, the checkout endpoint, and the webhook handler all import from that module directly — there is no separate CMS or spreadsheet to keep in sync.
Plan overview¶
| Slug | Name | Price/mo | CTA | Stripe env var |
|---|---|---|---|---|
solo |
Solo | $25 | Checkout | STRIPE_PRICE_SOLO |
standard |
Standard | $65 | Checkout | STRIPE_PRICE_STANDARD |
pro |
Pro | $125 | Checkout | STRIPE_PRICE_PRO |
enterprise |
Enterprise | Contact us | Contact page | (none) |
The +$5 invariant¶
Every paid tier is priced at the equivalent CTFd-hosted tier plus $5/month. The $5 represents per-team kernel-level isolation and ephemeral labs that CTFd Hosted does not offer.
| CTFHive tier | CTFd equivalent | CTFd price | CTFHive price |
|---|---|---|---|
| Solo | (no equivalent — HTB-style individual training) | — | $25 |
| Standard | CTFd Hosted Basic | $60/mo | $65/mo |
| Pro | CTFd Hosted Plus | $120/mo | $125/mo |
| Enterprise | (custom) | — | Contact |
If you change a price in pricing.py, update the adjacent comment that names the CTFd reference price so the invariant stays auditable in code review.
Plan details¶
Solo — $25/month¶
Individual training and single-organizer events with per-user labs.
- One organizer / individual learner
- Per-user ephemeral lab isolation
- Spawn-on-demand challenges
- WireGuard player access
Call to action: "Start Solo" (Stripe checkout via STRIPE_PRICE_SOLO)
Standard — $65/month¶
Club and workshop CTFs with real per-team isolation.
- ~5 container servers
- Per-team kernel-level isolation
- Layered anti-cheat
- Custom domain + theme
Call to action: "Choose Standard" (Stripe checkout via STRIPE_PRICE_STANDARD)
Pro — $125/month¶
Larger events that need more concurrent challenge capacity.
- Two-node deployment
- ~60 concurrent containers
- Priority provisioning
- Cross-tenant anti-cheat correlation
Call to action: "Choose Pro" (Stripe checkout via STRIPE_PRICE_PRO)
Enterprise — contact us¶
Company-wide and multi-event training with SSO and custom labs.
- Company-wide + multi-event training
- SSO / SAML
- Custom labs and challenge authoring
- Dedicated support and SLAs
Call to action: "Contact us" — routes to the /contact page. The enterprise plan has cta_kind="contact" and no stripe_price_env. Sending plan=enterprise to POST /billing/checkout returns a 400 error; it is not a valid checkout target.
Helpers¶
pricing.py exports two utility functions used by the checkout and webhook routes:
from ctrlapp.pricing import get_plan, monthly_price
plan = get_plan("standard") # Returns Plan dataclass or None
price = monthly_price("pro") # Returns int (dollars) or None
get_plan returns None for unknown slugs. monthly_price returns 0 for enterprise (the price is a sentinel meaning "contact us", not free).