Quota & Paywall
By default, free users get a limited number of AI messages a month and Pro users don’t.
| Free | Pro | |
|---|---|---|
| Chat messages and scans | freeMessagesPerMonth a month (10 by default) | Unlimited |
| Image generation | Not available | Available |
The limit resets on the first of the month. Nothing carries over.

Changing the limit
Change freeMessagesPerMonth in supabase/functions/_utils/ai.config.json, then
redeploy. The app reads the same file for the plan card, so the two stay in sync.
supabase functions deploy chat identifyWhen someone hits the limit
The app calls presentPaywall('quota_exceeded'), which shows an upgrade sheet, or your
Superwall paywall if you’ve set one up under that same placement
name. Edit the sheet’s copy in src/i18n/en.json, under paywall.*:
"paywall": {
"quota_title": "You're out of free messages",
"quota_body": "Upgrade to Pro for unlimited messages, image generation, and every model.",
"quota_upgrade_cta": "Upgrade to Pro"
}Checking Pro status
Pro means an active RevenueCat entitlement, checked in both the app and the server:
- The app gates its UI on
config.js→purchases.proEntitlementId. - The server checks the RevenueCat API for the entitlement named by
PRO_ENTITLEMENT_ID.
Both default to pro. If your RevenueCat entitlement is also named pro, there’s nothing to configure.
If the two names don’t match, a paying user sees Pro features in the app but gets turned away by the server. Keep them the same, or leave both at the default. See Edge Functions → Secrets.
No REVENUECAT_SECRET_KEY means every user is treated as not-Pro, including people
who already paid. Image generation and image-output models go dark for everyone.
Removing the limit
Raise it far enough not to matter
supabase secrets set AI_FREE_MESSAGES="999999"
supabase functions deploy chat identifyUpdate freeMessagesPerMonth in ai.config.json too, or the plan card will still
show the old number.
Or delete the check entirely
Remove the quotaGuard calls from supabase/functions/chat/index.ts and
supabase/functions/identify/index.ts, then redeploy.
With nothing in place, an anonymous sign-up can spend your OpenRouter credit without limit. Keep some ceiling before you ship.
Verify
A free account can send more messages than the old limit without seeing the upgrade sheet.