# Free tier enforcement (Descrybe v2) How the forever-Free plan is packaged and gated versus paid plans. ## Packaging (EnsureDefaultPlans / ProvisionFreePlan) | Plan | Price | Max products | Monthly AI credits | Notes | |------|-------|-------------:|-------------------:|-------| | **Free** | $0 | 50 | **0** | New signups via `ProvisionFreePlan` | | Starter | $49/mo | 1,000 | 1,000 | ~50% cover; entry “lower fish” | | Plus | $199/mo | 5,000 | 5,000 | ~50% cover; Woo+Shopify | | Growth | $299/mo | 25,000 | 25,000 | Hero; near A1 absolute $; full stores + BYOK | | Business | $499/mo | 50,000 | 50,000 | Plytix-class SKUs; ~50% cover | | Scale | $999/mo | 150,000 | 120,000 | ~40% cover | | Enterprise | Custom | Unlimited (`null`) | 1,000,000 | `is_custom`; large managed grant + BYOK | **A1 legacy** stays dump-faithful (PAYG, ~100 products in practice, Stores/AI integrations off) — not overwritten by `EnsureDefaultPlans`. Public plans are intentionally richer so A1’s deal is not “better” than what new customers get. Extra AI beyond the monthly grant: buyable one-time **credit packs** (`GET /api/billing/credit-packs`, Checkout `{ "pack": "…" }`). See [stripe-setup.md](stripe-setup.md). `EnsureDefaultPlans` upserts public plans by name (idempotent). Free intentionally grants **no** AI credits so signup never burns LLM cost. SKU/feed packaging follows the public ladder (50 SKUs on Free, etc.). Existing Free wallets are not wiped on plan sync; only the `plans.monthly_credits` row is corrected. New cycles / `AssignPlan` allocate from the plan row. ## Entitlements Exposed on `/api/auth/me` → `credits` and `/api/billing/credits`: | Field | Meaning | |-------|---------| | `can_use_ai` | `remaining_credits > 0` **OR** paid plan (not Free) | | `can_use_eprel` | **Always true** — EU EPREL is public free data on every plan (no credits). Platform may still disable the enricher via `eprel.enabled`. | | `is_free_plan` / `is_paid_plan` | Derived from active plan name | `billing.AIBrandApplyAllowed` already blocks brand-kit injection into AI prompts on Free. ## Free vs paid matrix | Capability | Free | Paid (Starter+) | |------------|------|-----------------| | Signup / map feed / view products | Yes | Yes | | Normalize / parse_specs / fill_fields | Yes (no credit debit) | Yes | | `ai_enhance` (titles / descriptions / SEO copy) | **Skipped** (`can_use_ai=false`) | Yes (credits) | | EPREL enrichment | **Yes (all plans)** | Yes | | AI-only job (`title`, `description`, `enhance_*`) | **402** `ai_requires_upgrade` | Credits gate | | EPREL-only job | **Yes** (no upgrade) | Yes | | Email campaign AI generate | **402** via `can_use_ai` / `ErrAIRequiresUpgrade` | Credits / paid | | SEO formula editors (config) | Editable | Editable | | SEO AI apply (`/api/seo/apply`) | **402** via `can_use_ai` | Credits / paid | | Email campaign AI generate | **402** on Free (`/api/campaigns/:id/generate` AI mode) | Credits / paid | | Product SKU cap | 100 | Per plan | | Upgrade banners | Dashboard + Products | Low-credit / limit banners | ## Processing behavior 1. **Start job** — `AssertCanStartProcessing` always checks SKU cap. Credit wallet is checked only when `RequiresAI` / `RequiresEPREL` (AI-only or EPREL-only types). 2. **Full / attributes jobs on Free** — allowed; pipeline `StepPolicy` sets `AllowAI=false`, `AllowEPREL=false` and appends clear notes (`ai_enhance: skipped (Free plan…)`, `eprel: skipped (paid plan…)`). 3. **ConsumeCredits** — no debit when `!CanUseAI && tokenCount==0` (free normalize path). ## Demo user `cmd/seed-demo` ensures a standalone **Platform Demo** company (never renames A1), upserts `demo@descrybe.test` + `demo@descrybe.local`, binds them **only** to Platform Demo, and assigns the custom **Platform Demo** plan (~1,000,000 monthly AI credits, unlimited SKUs, all feature gates ON). Free plan definition for new signups remains `monthly_credits=0`. See [demo-user.md](demo-user.md) and [safe-test-fixtures.md](safe-test-fixtures.md). ## UI - Products: Free info banner; AI options disabled with upgrade hint; process toast notes AI skip. - Dashboard: Free-specific banner (not “out of credits”). - Marketing pricing: Free lists 0 AI credits; EPREL included on all plans. ## Related - [free-tier-verify.md](free-tier-verify.md) — live smoke while demo is Enterprise - [eprel.md](eprel.md) — EPREL step details - [demo-user.md](demo-user.md) — Enterprise credits for demo - Repo sibling `PRICING-AND-USER-GROWTH.md` (v1 docs) — commercial ladder; Free AI pack in that doc is overridden here to **0** for cost control - SEO apply: `apps/api/internal/seo` (`can_use_ai`) - Campaign AI: `apps/api/internal/campaigns` (`ErrAIRequiresUpgrade` on AI generate)