Subscriptions
Softly uses RevenueCat for subscription management across iOS and Android. The backend syncs subscription state from RevenueCat via webhooks and on-demand sync.
Pricing
| Plan | Price |
|---|---|
| Free | $0 forever |
| Pro Monthly | $4.99/month |
| Pro Annual | $39.99/year (save 33%) |
| Lifetime | $79.99 one-time |
| Family | $7.99/month |
Tiers
| Feature | Free | Pro | Family |
|---|---|---|---|
| Tasks | 5 max | Unlimited | Unlimited |
| Recurring tasks | No | Yes | Yes |
| AI parses/month | 5 | 200 | 200 (shared pool) |
| Voice input | Native only | Deepgram + native | Deepgram + native |
| NL editing (QuickEditBar) | No | Yes | Yes |
| AI suggestions | Starter (hardcoded) | AI-powered (Haiku) | AI-powered (Haiku) |
| Streak freeze | No | Yes (1/week) | Yes (1/week) |
| Celebrations (confetti) | No | Yes | Yes |
| Life admin score | No | Yes | Yes |
| Document vault | No | Yes | Yes |
| Life templates | No | Yes | Yes |
| Smart rescheduling | No | Yes | Yes |
| Household sharing | No | No | Yes |
| Family activity feed | No | No | Yes |
RevenueCat Integration
RevenueCat handles all App Store and Play Store interactions. The mobile app uses the RevenueCat SDK (services/revenuecat.ts) to:
- Present the custom paywall
- Process purchases
- Restore previous purchases
After a successful purchase, the app calls POST /api/v1/subscriptions/sync to trigger a backend sync. The backend queues a SyncSubscriptionJob that calls the RevenueCat API to verify and update the user's tier.
Webhook Sync
RevenueCat sends webhook events for subscription changes (renewals, cancellations, billing issues). The backend receives these at:
POST /api/v1/webhooks/revenuecatThe webhook is verified using the REVENUECAT_WEBHOOK_SECRET environment variable. On receipt, it queues the same SyncSubscriptionJob for async processing.
Custom Paywall
The paywall screen (subscription/index.tsx) is a custom-built UI using Purchases.getOfferings() and Purchases.purchasePackage() directly — no RevenueCatUI templates needed. It shows:
- Billing period toggle (Monthly / Annual / Lifetime)
- Pro feature list with pricing
- Free tier comparison
- Restore purchases button
- Apple legal text
Lifetime vs Recurring
Lifetime users have subscription_tier: "pro" with subscription_expires_at: null. The mobile app distinguishes them with a gold crown badge (vs sage for recurring Pro). Sustainability math: a lifetime purchase at $79.99 covers ~80 years of AI costs at Haiku pricing.
Tier Limits
Limits are enforced on the backend. When a free user hits a limit, the API returns a 403 with a message prompting upgrade:
- Task limit: Free users cannot create more than 5 tasks
- Recurring tasks: Free users cannot create recurring tasks
- AI limit: Free users get 5 AI parses per month
- Voice: Deepgram transcription tokens are only issued to Pro/Family users
- AI suggestions: Free users see hardcoded starter suggestions only (no AI call)
Grandfathered Users
Users who signed up during beta are flagged with grandfathered_at and receive unlimited AI access and all Pro features regardless of their subscription tier.
AI Cost Per User
| Tier | AI Cost/Month | Revenue/Month | Margin |
|---|---|---|---|
| Free | $0.003 | $0 | -$0.003 |
| Pro | $0.02 | $4.99 | 99.6% |
| Family | $0.04 | $7.99 | 99.5% |
AI costs are negligible thanks to Claude Haiku (~10x cheaper than Sonnet). See Cost Analysis for full breakdown.