Skip to Content

Secrets

The AI edge functions read their configuration from Supabase function secrets. These are server-side only: they are never bundled into your app, and must never be given an EXPO_PUBLIC_ prefix.

What you need

SecretRequiredWhat it is
OPENROUTER_API_KEYYes, for AIYour OpenRouter  API key, used by chat, generate and identify. If it is missing, provider setup returns provider_not_configured.
AI_FREE_MESSAGESNoOverrides freeMessagesPerMonth from supabase/functions/_utils/ai.config.json on the server. Keep it at the same value as the app’s allowance. The supplied default is 10.
REVENUECAT_SECRET_KEYYes, for Pro featuresYour RevenueCat secret API key for API v1. The server uses it to check Pro entitlements. If it is unset, image generation and image-output chat models are refused for every user.
PRO_ENTITLEMENT_IDNoThe RevenueCat entitlement that grants Pro. Defaults to pro. Must match config.js → purchases.proEntitlementId.

Supabase supplies SUPABASE_URL, SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY to the functions. Do not add them as custom project secrets. The service-role key bypasses row-level security and must never be included in your app. See Supabase’s default secrets .

supabase/functions/.env.example documents all of them.

For local development, keep custom secrets in supabase/functions/.env. Chat messages and scans share the monthly allowance; image generations are excluded. See quota for how usage is counted.

The two entitlement settings must match

Two places name the RevenueCat entitlement that unlocks Pro. The app gates its UI on one; the server enforces the other.

WhereSettingDefault
Appconfig.js → purchases.proEntitlementId'pro'
ServerPRO_ENTITLEMENT_ID secretpro

If they disagree, a paying user may see Pro features in the app while the server refuses image generation or applies the free allowance.

Both default to pro, so if you name your RevenueCat entitlement pro there is nothing to do. If yours is named something else, such as premium or pro_monthly, set both to that value:

config.js
purchases: { proEntitlementId: 'premium', },
supabase secrets set PRO_ENTITLEMENT_ID="premium"

Set them

Get an OpenRouter key

Create a key from the OpenRouter dashboard  and add credit to use paid models.

Get your RevenueCat secret key

Copy a secret API key for API v1 from your RevenueCat project. It starts with sk_. Keep it separate from the public SDK keys in .env.local. See RevenueCat authentication .

Push the secrets to your Supabase project

From your project root:

supabase secrets set OPENROUTER_API_KEY="sk-or-v1-..." supabase secrets set REVENUECAT_SECRET_KEY="sk_..." supabase secrets set AI_FREE_MESSAGES="10"

Verify

supabase secrets list

Confirm that the secret names are listed. This verifies that the values were saved, not that the credentials work. After deploying the functions, send a chat message and test image generation with a Pro account.

Hosted secret changes are available without redeploying. Changes to code or ai.config.json still require a deploy. See Supabase’s production secrets .

Error codes

The function response body carries a code. These are the ones caused by configuration:

CodeHTTPMeaning
provider_not_configured500OPENROUTER_API_KEY is not set.
pro_required403A Pro-only feature was requested without a verified entitlement. Check REVENUECAT_SECRET_KEY and the entitlement name.
quota_exceeded402The user used up AI_FREE_MESSAGES this month and is not Pro.
invalid_model400The requested model slug is not in the deployed registry. Add it to ai.config.json and redeploy chat.
Last updated on