@model PricingViewModel @using Microsoft.AspNetCore.Html @{ ViewData["Title"] = "Pricing"; ViewData["ShellClass"] = "marketing-shell"; var paidPlans = Model.Plans.Where(x => x.RequiresStripeSubscription).ToList(); var suggestedPlanId = paidPlans.Count >= 2 ? paidPlans[paidPlans.Count / 2].SubscriptionLevelID : (int?)null; }

Pricing

Simple pricing for stories of every size.

Start with a 30-day free trial. No payment details are required until you choose a paid plan.

@if (TempData["PricingMessage"] is string pricingMessage) {
@pricingMessage
}

Plans

Choose the space your story needs.

@if (!Model.Plans.Any()) {

Plans are being prepared.

Active subscription levels are not available yet. Please check back soon.

} else {
@foreach (var plan in Model.Plans) { var isCurrent = Model.CurrentSubscriptionLevelID == plan.SubscriptionLevelID; var isSuggested = suggestedPlanId == plan.SubscriptionLevelID; var isTrialPlan = !plan.RequiresStripeSubscription;
@if (isTrialPlan) {

30-day free trial

} @if (isSuggested) {

Most Popular

}

@plan.DisplayName

@PlanTagline(plan)

@if (plan.RequiresStripeSubscription) { @PriceMarkup(plan.MonthlyPricePence, plan.CurrencyCode) per month @if (plan.AnnualPricePence.HasValue) { @FormatAnnualPrice(plan.AnnualPricePence, plan.CurrencyCode) billed annually } } else { Free 30-day trial workspace No payment details required. Starts immediately after registration. }
    @if (!plan.RequiresStripeSubscription) {
  • 30 days of free access
  • No credit card required
  • }
  • @FormatLimit(plan.MaxBooks) books
  • @FormatLimit(plan.MaxCharactersPerProject) characters per project
  • @FormatLimit(plan.MaxScenesPerBook) scenes per book
  • @FormatStorageAllowance(plan.MaxStorageMB) storage
  • @FormatLimit(plan.MaxCollaborators) collaborators
@if (!plan.RequiresStripeSubscription) { Start Free Trial } else { @(isCurrent ? "Current Plan" : "Subscribe Now") @if (plan.AnnualPricePence.HasValue) { Choose annual billing } }
}
}

What is included

Everything you need to keep a complex novel coherent.

Planning capacity

Database-backed limits for books, chapters, scenes, characters, storage, and collaborators scale with the plan you choose.

Story organisation

Characters, plot threads, story assets, locations, and the story bible help keep the moving pieces of your manuscript in one place.

Structure and flow

Timeline, scene metrics, story health, and analytics views help you understand pacing, pressure, and revision priorities.

Continuity confidence

Relationship mapping, continuity warnings, import, export, backups, and restore points support serious drafting and revision work.

Questions

Pricing FAQ

Can I start with a free trial?

Yes. Creating an account starts a 30-day Draft Desk trial immediately, so you can try the workspace before choosing a paid subscription.

Can I subscribe without using the trial?

Yes. Choose a paid plan from this page. If you are not signed in, PlotDirector will ask you to log in before continuing to checkout.

Can I change plan later?

Yes. Signed-in users can manage subscription changes from the account subscription area.

What happens to my work if I cancel?

Your existing story data remains in PlotDirector. Your account may return to the application-managed Draft Desk level after the paid subscription ends.

Is PlotDirector suitable for a series?

Yes. The higher plan limits are designed for authors managing multiple books, long arcs, and larger casts.

Do I need a credit card for the trial?

No. Payment details are not required for the free trial. Stripe Checkout is only used when you choose a paid subscription.

What happens when the trial expires?

Your trial status will show in your dashboard and subscription pages. When the 30 days are over, choose a paid plan to continue with higher paid-plan access.

Begin with clarity

Ready to take control of your story?

Try PlotDirector free for 30 days with no payment details, or choose the paid plan that fits the novel you are building.

@functions { private const int PracticalUnlimited = 999999; private static string FormatLimit(int value) => value >= PracticalUnlimited ? "Unlimited" : value.ToString("N0"); private static string FormatStorageAllowance(int megabytes) => megabytes >= PracticalUnlimited ? "Unlimited" : StorageUsage.FormatBytes(megabytes * 1024L * 1024L); private static IHtmlContent PriceMarkup(int? pence, string? currencyCode) { if (!pence.HasValue) { return new HtmlString("Contact us"); } var code = string.IsNullOrWhiteSpace(currencyCode) ? "GBP" : currencyCode.ToUpperInvariant(); var symbol = string.Equals(code, "GBP", StringComparison.OrdinalIgnoreCase) ? "£" : string.Empty; return new HtmlString($"{symbol}{pence.Value / 100m:0.00} {code}"); } private static string FormatAnnualPrice(int? pence, string? currencyCode) { if (!pence.HasValue) { return "Contact us"; } var code = string.IsNullOrWhiteSpace(currencyCode) ? "GBP" : currencyCode.ToUpperInvariant(); var symbol = string.Equals(code, "GBP", StringComparison.OrdinalIgnoreCase) ? "£" : string.Empty; return $"{symbol}{pence.Value / 100m:0.00}"; } private static string PlanTagline(SubscriptionLevel plan) => string.IsNullOrWhiteSpace(plan.Description) ? plan.RequiresStripeSubscription ? "For authors ready to build with confidence." : "A calm place to begin." : plan.Description; }