# TASK 10 — Monetization: watermark-only one-time license + Polar billing > Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here. **Goal:** a **one-time perpetual license** via Polar.sh that removes the branding watermark. All features are free — the only difference between free and paid is the watermark. (Model changed 2026-09-21 from annual subscription to one-time "own it": $29 founder / $49 list lifetime. See `MONETIZATION.md` → Pricing for the reasoning.) **Related work — monetization awareness (2026-09-01, ungated, free):** this task's billing is the *payer* side; the *product* also carries built-in, ungated monetization awareness for every creator — reward-event capture (all 7 `liveChatMessage` reward event types → canonical `RewardEvent` → SQLite persistence), per-session/broadcast reports (members, Super Chat $, stickers, gifts, milestones — the in-app replacement for the emailed "stream activity report"), and a journey tracker (position % + ETA vs. versioned, date-aware YPP thresholds; the Tier-2 bar doubles for new applicants 2027-02-01). Details and design notes: `ai.md` → Monetization. This is tracked as related work under this task's narrative, not a separate task number — it ships in its own code slices with one integration test each. **Scope: v1** (2026-09-01 complete-v1 ruling — there is no v1.x): slice order = reward-event capture → session report → journey tracker → Alerts (TASK 3 item 20). **Business details (pricing, Polar product/checkout/discounts) in `MONETIZATION.md` (gitignored).** **Polar product:** `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` (LlamaCasty, ⚠️ currently configured as $99/yr **subscription** — must be re-created as a **one-time** product: $29 founder / $49 list lifetime) **Checkout:** `llamacasty.com` → Polar hosted page (~80% configured) **Discounts:** `LLAMAFOUNDER` (100% off, 50 uses, `once`), `LLAMA50` (50% off, `once`) **Org ID:** `c05fb364-b967-4f6c-adf2-8a144e46d085` (org-scoped OAT — `organization_id` can be omitted from API calls) **Key prefix:** `LCYT-` **Validate endpoint:** `POST https://api.polar.sh/v1/customer-portal/license-keys/validate` (no auth required for client-side validation) ### Status: 🔶 In progress — steps 1–7 shipped, Velopack update URL pending 1. ✅ **Billing provider** — Polar (polar.sh) chosen and configured. Product, price, license key benefit, discounts, checkout link all created. 2. ✅ **License key entry + verification UI** — About overlay swap panel (same pattern as Licenses panel). Text input + "Activate" button + status message. "Enter License Key" button in the hub. 3. ✅ **Offline entitlement** — `LayoutStore` Settings table: `LicenseKey`, `LicenseValidatedAt`, `IsPremium`. 14-day offline grace period. Startup re-validates online, falls back to cache. 4. ✅ **BrandFlash → watermark toggle** — `IsPremium` property setter flips `BrandFlashEnabled = !value`. Flash stops immediately on premium activation. Flash asset VideoFrame rendering deferred to TASK 4 compositor. 5. ✅ **Remove social slot locks** — all 6 social bar slots open to everyone (no `IsPremium` gating on slots 3-6) — shipped as TASK 10c 6. ✅ **"Unlock Premium" button** — `PremiumUrl` set to Polar checkout; `IsPremiumAvailable` is true; button lights up in the About hub. 7. ✅ **Licensing model** — startup re-validates against Polar API. **Perpetual key (2026-09-21): the license never expires, `IsPremium` never lapses, and the flash does not return.** The former renewal/lapse path is dead. Offline grace period (14 days) still applies to the validation call only. 8. 🔶 **Velopack auto-updates** — NuGet packages + bootstrap in `App.xaml.cs`. Update URL self-hosted on DO droplet (pending configuration).