-
Notifications
You must be signed in to change notification settings - Fork 2
Configuration file
Pair reads runtime configuration from APPLICATION_PATH/.env through Pair\Core\Env.
This page reflects ~/Sites/pair/.env.example.
# core app
APP_NAME="Pair Application"
APP_URL=
APP_VERSION="1.0"
APP_ENV=production
APP_DEBUG=false
# database
DB_HOST=127.0.0.1
DB_NAME=pair
DB_USER=root
DB_PASS=
DB_UTF8=true
# framework behavior
OAUTH2_TOKEN_LIFETIME=3600
PAIR_SINGLE_SESSION=true
PAIR_AUTH_BY_EMAIL=true
PAIR_AUDIT_ALL=true
PAIR_AUTH_RATE_LIMIT_ENABLED=true
PAIR_AUTH_RATE_LIMIT_MAX_ATTEMPTS=10
PAIR_AUTH_RATE_LIMIT_DECAY_SECONDS=900
PAIR_MOBILE_ACCESS_TOKEN_LIFETIME=900
PAIR_MOBILE_REFRESH_TOKEN_LIFETIME=2592000
PAIR_API_RATE_LIMIT_ENABLED=true
PAIR_API_RATE_LIMIT_MAX_ATTEMPTS=60
PAIR_API_RATE_LIMIT_DECAY_SECONDS=60
PAIR_API_RATE_LIMIT_REDIS_PREFIX="pair:rate_limit:"
PAIR_TRUSTED_PROXIES=
PAIR_SOCIAL_AUTH_PROVIDERS=
PAIR_SOCIAL_AUTH_TIMEOUT=15
PAIR_SOCIAL_AUTH_CONNECT_TIMEOUT=5
PAIR_SOCIAL_GOOGLE_CLIENT_ID=
PAIR_SOCIAL_GOOGLE_CLIENT_SECRET=
PAIR_SOCIAL_APPLE_CLIENT_ID=
PAIR_SOCIAL_APPLE_CLIENT_SECRET=
PAIR_SOCIAL_APPLE_TEAM_ID=
PAIR_SOCIAL_APPLE_KEY_ID=
PAIR_SOCIAL_APPLE_CLIENT_SECRET_TTL=
PAIR_SOCIAL_APPLE_PRIVATE_KEY=
PAIR_SOCIAL_APPLE_PRIVATE_KEY_PATH=
PAIR_SOCIAL_MICROSOFT_CLIENT_ID=
PAIR_SOCIAL_MICROSOFT_CLIENT_SECRET=
PAIR_SOCIAL_WHATSAPP_CLIENT_ID=
PAIR_SOCIAL_WHATSAPP_CLIENT_SECRET=
PAIR_SOCIAL_WHATSAPP_CONFIG_ID=
PAIR_CACHE_DRIVER=file
PAIR_CACHE_PATH=
PAIR_CACHE_PREFIX=pair
PAIR_CACHE_REDIS_PREFIX="pair:cache:"
PAIR_ORIGIN_GZIP=auto
PAIR_OBSERVABILITY_ENABLED=false
PAIR_OBSERVABILITY_DEBUG_HEADERS=true
PAIR_OBSERVABILITY_TRACE_SAMPLE_RATE=1.0
PAIR_OBSERVABILITY_ERROR_SAMPLE_RATE=1.0
PAIR_OBSERVABILITY_MAX_SPANS=100
PAIR_OBSERVABILITY_MAX_EVENTS=50
UTC_DATE=true
# observability exporters (optional)
SENTRY_DSN=
SENTRY_ENVIRONMENT=
SENTRY_RELEASE=
SENTRY_TRACES_SAMPLE_RATE=1.0
SENTRY_ERROR_SAMPLE_RATE=1.0
SENTRY_TIMEOUT=10
SENTRY_CONNECT_TIMEOUT=3
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
OTEL_EXPORTER_OTLP_HEADERS=
OTEL_SERVICE_NAME=
OTEL_SERVICE_VERSION=
OTEL_TIMEOUT=10
OTEL_CONNECT_TIMEOUT=3
# redis (optional, used by API rate limiting and cache when configured)
REDIS_HOST=
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TIMEOUT=1
# crypto
AES_CRYPT_KEY=
OPTIONS_CRYPT_KEY=
# logger and notifications
PAIR_LOGGER_DISABLED=false
PAIR_LOGGER_EMAIL_RECIPIENTS=
PAIR_LOGGER_EMAIL_THRESHOLD=4
PAIR_LOGGER_TELEGRAM_BOT_TOKEN=
PAIR_LOGGER_TELEGRAM_CHAT_IDS=
PAIR_LOGGER_TELEGRAM_THRESHOLD=4
# telegram bot api (optional)
TELEGRAM_BOT_TOKEN=
TELEGRAM_API_BASE_URL="https://api.telegram.org"
TELEGRAM_TIMEOUT=20
TELEGRAM_CONNECT_TIMEOUT=5
TELEGRAM_WEBHOOK_SECRET_TOKEN=
# passkey / webauthn
PASSKEY_RP_ID=
PASSKEY_RP_NAME=
PASSKEY_ALLOWED_ORIGINS=
PASSKEY_REQUIRE_USER_VERIFICATION=true
# google maps
GOOGLE_MAPS_API_KEY=
GOOGLE_MAPS_BROWSER_API_KEY=
GOOGLE_MAPS_TIMEOUT=15
GOOGLE_MAPS_CONNECT_TIMEOUT=5
# whatsapp cloud api
WHATSAPP_CLOUD_ACCESS_TOKEN=
WHATSAPP_CLOUD_PHONE_NUMBER_ID=
WHATSAPP_CLOUD_API_VERSION=v23.0
WHATSAPP_CLOUD_API_BASE_URL="https://graph.facebook.com"
WHATSAPP_CLOUD_TIMEOUT=20
WHATSAPP_CLOUD_CONNECT_TIMEOUT=5
WHATSAPP_CLOUD_WEBHOOK_VERIFY_TOKEN=
WHATSAPP_CLOUD_APP_SECRET=
# stripe (optional)
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_API_VERSION=
# openai (optional)
OPENAI_API_KEY=
OPENAI_API_BASE_URL="https://api.openai.com/v1"
OPENAI_RESPONSES_MODEL=gpt-5.4-mini
OPENAI_EMBEDDINGS_MODEL=text-embedding-3-small
OPENAI_REALTIME_MODEL=gpt-realtime
OPENAI_TIMEOUT=30
OPENAI_CONNECT_TIMEOUT=5
OPENAI_STORE_RESPONSES=false
# gemini (optional)
GEMINI_API_KEY=
GEMINI_API_BASE_URL="https://generativelanguage.googleapis.com/v1beta"
GEMINI_GENERATION_MODEL=gemini-2.5-flash
GEMINI_EMBEDDINGS_MODEL=gemini-embedding-2
GEMINI_TIMEOUT=30
GEMINI_CONNECT_TIMEOUT=5
# claude (optional)
CLAUDE_API_KEY=
CLAUDE_API_BASE_URL="https://api.anthropic.com/v1"
CLAUDE_MESSAGES_MODEL=claude-sonnet-4-5
CLAUDE_API_VERSION=2023-06-01
CLAUDE_MAX_TOKENS=1024
CLAUDE_TIMEOUT=30
CLAUDE_CONNECT_TIMEOUT=5
# resend (optional)
RESEND_API_KEY=
RESEND_API_BASE_URL="https://api.resend.com"
RESEND_FROM_ADDRESS=
RESEND_FROM_NAME=
RESEND_WEBHOOK_SECRET=
RESEND_TIMEOUT=20
RESEND_CONNECT_TIMEOUT=5
# cloudflare turnstile (optional)
CLOUDFLARE_TURNSTILE_SITE_KEY=
CLOUDFLARE_TURNSTILE_SECRET_KEY=
CLOUDFLARE_TURNSTILE_VERIFY_URL="https://challenges.cloudflare.com/turnstile/v0/siteverify"
CLOUDFLARE_TURNSTILE_RESPONSE_FIELD=cf-turnstile-response
CLOUDFLARE_TURNSTILE_TIMEOUT=10
CLOUDFLARE_TURNSTILE_CONNECT_TIMEOUT=3
# meilisearch (optional)
MEILISEARCH_HOST="http://127.0.0.1:7700"
MEILISEARCH_API_KEY=
MEILISEARCH_DEFAULT_INDEX=
MEILISEARCH_TIMEOUT=10
MEILISEARCH_CONNECT_TIMEOUT=3
MEILISEARCH_SEARCH_LIMIT=20
# supabase (optional)
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
SUPABASE_TIMEOUT=20
SUPABASE_CONNECT_TIMEOUT=5
# web push (vapid)
PUSH_VAPID_PUBLIC=
PUSH_VAPID_PRIVATE=
PUSH_VAPID_SUBJECT=APP_NAMEAPP_URLAPP_VERSIONAPP_ENVAPP_DEBUG
APP_URL is optional and must contain an absolute HTTP(S) application URL without credentials, query string, or fragment. When configured, Pair uses it as BASE_HREF in CLI processes, where no HTTP request exists. Web requests continue to derive BASE_HREF from the current request.
DB_HOSTDB_NAMEDB_USERDB_PASSDB_UTF8
OAUTH2_TOKEN_LIFETIMEPAIR_SINGLE_SESSIONPAIR_AUTH_BY_EMAILPAIR_AUDIT_ALLPAIR_AUTH_RATE_LIMIT_ENABLEDPAIR_AUTH_RATE_LIMIT_MAX_ATTEMPTSPAIR_AUTH_RATE_LIMIT_DECAY_SECONDSPAIR_MOBILE_ACCESS_TOKEN_LIFETIMEPAIR_MOBILE_REFRESH_TOKEN_LIFETIMEPAIR_API_RATE_LIMIT_ENABLEDPAIR_API_RATE_LIMIT_MAX_ATTEMPTSPAIR_API_RATE_LIMIT_DECAY_SECONDSPAIR_API_RATE_LIMIT_REDIS_PREFIXPAIR_TRUSTED_PROXIESPAIR_SOCIAL_AUTH_PROVIDERSPAIR_SOCIAL_AUTH_TIMEOUTPAIR_SOCIAL_AUTH_CONNECT_TIMEOUTPAIR_CACHE_DRIVERPAIR_CACHE_PATHPAIR_CACHE_PREFIXPAIR_CACHE_REDIS_PREFIXPAIR_ORIGIN_GZIPPAIR_OBSERVABILITY_ENABLEDPAIR_OBSERVABILITY_DEBUG_HEADERSPAIR_OBSERVABILITY_TRACE_SAMPLE_RATEPAIR_OBSERVABILITY_ERROR_SAMPLE_RATEPAIR_OBSERVABILITY_MAX_SPANSPAIR_OBSERVABILITY_MAX_EVENTSUTC_DATE
PAIR_ORIGIN_GZIP
Notes:
-
PAIR_ORIGIN_GZIP=autoenables origin gzip only when the request accepts gzip and Pair does not detect an edge compression layer such as Cloudflare -
PAIR_ORIGIN_GZIP=onforces Pair to useob_gzhandlerwhen PHP can safely do so -
PAIR_ORIGIN_GZIP=offdisables Pair's origin output compression buffer - Pair never starts
ob_gzhandlerwhen PHPzlib.output_compressionis already enabled
PAIR_SOCIAL_AUTH_PROVIDERSPAIR_SOCIAL_AUTH_TIMEOUTPAIR_SOCIAL_AUTH_CONNECT_TIMEOUTPAIR_SOCIAL_GOOGLE_CLIENT_IDPAIR_SOCIAL_GOOGLE_CLIENT_SECRETPAIR_SOCIAL_APPLE_CLIENT_IDPAIR_SOCIAL_APPLE_CLIENT_SECRETPAIR_SOCIAL_APPLE_TEAM_IDPAIR_SOCIAL_APPLE_KEY_IDPAIR_SOCIAL_APPLE_CLIENT_SECRET_TTLPAIR_SOCIAL_APPLE_PRIVATE_KEYPAIR_SOCIAL_APPLE_PRIVATE_KEY_PATHPAIR_SOCIAL_MICROSOFT_CLIENT_IDPAIR_SOCIAL_MICROSOFT_CLIENT_SECRETPAIR_SOCIAL_WHATSAPP_CLIENT_IDPAIR_SOCIAL_WHATSAPP_CLIENT_SECRETPAIR_SOCIAL_WHATSAPP_CONFIG_ID
Notes:
-
PAIR_SOCIAL_AUTH_PROVIDERSaccepts comma-separated or space-separated provider keys such asgoogle,apple,microsoft,whatsapp -
PAIR_SOCIAL_AUTH_TIMEOUTandPAIR_SOCIAL_AUTH_CONNECT_TIMEOUTcontrol outbound OAuth/OIDC calls made bySocialAuth - built-in provider defaults can be overridden with
PAIR_SOCIAL_<PROVIDER>_LABEL,ICON,AUTHORIZE_URL,TOKEN_URL,PROFILE_URL,SCOPES,PROFILE_QUERY, andAUTHORIZE_PARAMS - Apple can use
PAIR_SOCIAL_APPLE_CLIENT_SECRETdirectly or generate it from team/key/private-key settings;PAIR_SOCIAL_APPLE_CLIENT_SECRET_TTLcaps the generated JWT lifetime -
PAIR_SOCIAL_WHATSAPP_CONFIG_IDis added to WhatsApp authorization parameters when configured
PAIR_CACHE_DRIVERPAIR_CACHE_PATHPAIR_CACHE_PREFIXPAIR_CACHE_REDIS_PREFIXREDIS_HOSTREDIS_PORTREDIS_PASSWORDREDIS_DBREDIS_TIMEOUT
Notes:
-
PAIR_CACHE_DRIVERacceptsfile,apcu, orredis -
fileis the dependency-free default and usesPAIR_CACHE_PATHwhen provided -
apcurequires APCu to be installed and enabled in the current runtime -
redisrequires the Redis PHP extension andREDIS_HOST -
PAIR_CACHE_REDIS_PREFIXnamespaces cache keys independently from rate limiter keys
Example:
PAIR_CACHE_DRIVER=redis
PAIR_CACHE_REDIS_PREFIX="pair:cache:"
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TIMEOUT=1REDIS_HOSTREDIS_PORTREDIS_PASSWORDREDIS_DBREDIS_TIMEOUTPAIR_API_RATE_LIMIT_REDIS_PREFIX
Notes:
- if
REDIS_HOSTis empty, Pair falls back to file-based rate limiting - if Redis is temporarily unavailable, Pair falls back to file-based storage automatically
-
PAIR_TRUSTED_PROXIESshould contain exact IPs and/or CIDR ranges for trusted reverse proxies
Example:
PAIR_API_RATE_LIMIT_ENABLED=true
PAIR_API_RATE_LIMIT_MAX_ATTEMPTS=120
PAIR_API_RATE_LIMIT_DECAY_SECONDS=60
PAIR_API_RATE_LIMIT_REDIS_PREFIX="pair:rate_limit:"
PAIR_TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TIMEOUT=1Password login attempts are rate limited by both normalized identifier and client IP. This protects existing and non-existing identifiers with the same generic login error.
PAIR_AUTH_RATE_LIMIT_ENABLED=true
PAIR_AUTH_RATE_LIMIT_MAX_ATTEMPTS=10
PAIR_AUTH_RATE_LIMIT_DECAY_SECONDS=900See AuthAttemptLimiter for the framework class that applies these settings in web and token login flows.
Pair native mobile auth uses short-lived access tokens and optional rotating refresh tokens stored as hashes in api_tokens.
PAIR_MOBILE_ACCESS_TOKEN_LIFETIME=900
PAIR_MOBILE_REFRESH_TOKEN_LIFETIME=2592000Notes:
-
PAIR_MOBILE_ACCESS_TOKEN_LIFETIMEcontrols the access-token lifetime returned asexpires_in -
PAIR_MOBILE_REFRESH_TOKEN_LIFETIMEcontrols how long a refresh token can rotate the session - invalid or non-positive values fall back to Pair defaults
AES_CRYPT_KEYOPTIONS_CRYPT_KEY
PAIR_OBSERVABILITY_ENABLEDPAIR_OBSERVABILITY_DEBUG_HEADERSPAIR_OBSERVABILITY_TRACE_SAMPLE_RATEPAIR_OBSERVABILITY_ERROR_SAMPLE_RATEPAIR_OBSERVABILITY_MAX_SPANSPAIR_OBSERVABILITY_MAX_EVENTSPAIR_LOGBAR_SLOW_REQUEST_MSPAIR_LOGBAR_SLOW_QUERY_MSPAIR_LOGBAR_QUERY_BUDGETPAIR_LOGBAR_DUPLICATE_QUERY_BUDGETPAIR_LOGBAR_MAX_EVENTSPAIR_LOGBAR_SHOW_SQL_VALUESPAIR_LOGBAR_CSS_PATHPAIR_LOGBAR_JS_PATHPAIR_LOGGER_DISABLEDPAIR_LOGGER_EMAIL_RECIPIENTSPAIR_LOGGER_EMAIL_THRESHOLDPAIR_LOGGER_TELEGRAM_BOT_TOKENPAIR_LOGGER_TELEGRAM_CHAT_IDSPAIR_LOGGER_TELEGRAM_THRESHOLDTELEGRAM_BOT_TOKENTELEGRAM_API_BASE_URLTELEGRAM_TIMEOUTTELEGRAM_CONNECT_TIMEOUTTELEGRAM_WEBHOOK_SECRET_TOKEN
Notes:
-
PAIR_LOGGER_TELEGRAM_CHAT_IDSaccepts standard Telegram numeric chat IDs, including negative IDs for groups and channels -
PAIR_LOGGER_TELEGRAM_BOT_TOKENis the preferred Telegram bot token for Pair logger notifications;TELEGRAM_BOT_TOKENremains a legacy fallback for existing applications -
PAIR_OBSERVABILITY_ENABLED=trueenables Pair runtime spans without requiring a third-party package in the core framework -
PAIR_OBSERVABILITY_DEBUG_HEADERS=trueallows explicit responses to expose correlation and timing headers only whenAPP_DEBUG=true -
PAIR_OBSERVABILITY_TRACE_SAMPLE_RATEandPAIR_OBSERVABILITY_ERROR_SAMPLE_RATEcontrol telemetry volume before provider adapters are called -
PAIR_OBSERVABILITY_MAX_SPANSandPAIR_OBSERVABILITY_MAX_EVENTScap in-process retained telemetry -
PAIR_LOGBAR_SLOW_REQUEST_MS,PAIR_LOGBAR_SLOW_QUERY_MS,PAIR_LOGBAR_QUERY_BUDGET, andPAIR_LOGBAR_DUPLICATE_QUERY_BUDGETtune local LogBar diagnostics -
PAIR_LOGBAR_MAX_EVENTScaps retained LogBar entries for one request -
PAIR_LOGBAR_SHOW_SQL_VALUES=falsekeeps SQL bound values hidden by default; sensitive values are still masked when the flag is enabled -
PAIR_LOGBAR_CSS_PATHandPAIR_LOGBAR_JS_PATHlet applications override copied LogBar asset paths when the public asset layout differs from Pair defaults -
TELEGRAM_API_BASE_URLcan target the official cloud endpoint or a local Bot API server -
TELEGRAM_WEBHOOK_SECRET_TOKENis the shared secret Telegram sends inX-Telegram-Bot-Api-Secret-Token
SENTRY_DSNSENTRY_ENVIRONMENTSENTRY_RELEASESENTRY_TRACES_SAMPLE_RATESENTRY_ERROR_SAMPLE_RATESENTRY_TIMEOUTSENTRY_CONNECT_TIMEOUTOTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTEL_EXPORTER_OTLP_HEADERSOTEL_SERVICE_NAMEOTEL_SERVICE_VERSIONOTEL_TIMEOUTOTEL_CONNECT_TIMEOUT
Notes:
-
SENTRY_DSNis used bySentryObservabilityAdapter -
SENTRY_ENVIRONMENTfalls back toAPP_ENV -
SENTRY_RELEASEfalls back toAPP_VERSION -
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTis used byOpenTelemetryHttpExporter -
OTEL_EXPORTER_OTLP_HEADERSaccepts comma-separatedName=valuepairs -
OTEL_SERVICE_NAMEandOTEL_SERVICE_VERSIONdefault to app metadata when empty
SUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYSUPABASE_TIMEOUTSUPABASE_CONNECT_TIMEOUT
Notes:
-
SUPABASE_URLis the project base URL used bySupabaseClient -
SUPABASE_ANON_KEYis used for user-scoped requests and Realtime URL construction -
SUPABASE_SERVICE_ROLE_KEYis for trusted server-side calls only and must never be exposed to browsers or client apps -
SUPABASE_TIMEOUTandSUPABASE_CONNECT_TIMEOUTcontrol the dependency-free HTTP bridge
PASSKEY_RP_IDPASSKEY_RP_NAMEPASSKEY_ALLOWED_ORIGINSPASSKEY_REQUIRE_USER_VERIFICATION
GOOGLE_MAPS_API_KEYGOOGLE_MAPS_BROWSER_API_KEYGOOGLE_MAPS_TIMEOUTGOOGLE_MAPS_CONNECT_TIMEOUT
WHATSAPP_CLOUD_ACCESS_TOKENWHATSAPP_CLOUD_PHONE_NUMBER_IDWHATSAPP_CLOUD_API_VERSIONWHATSAPP_CLOUD_API_BASE_URLWHATSAPP_CLOUD_TIMEOUTWHATSAPP_CLOUD_CONNECT_TIMEOUTWHATSAPP_CLOUD_WEBHOOK_VERIFY_TOKENWHATSAPP_CLOUD_APP_SECRET
Notes:
-
WHATSAPP_CLOUD_ACCESS_TOKENshould be a long-lived or system user token withwhatsapp_business_messaging -
WHATSAPP_CLOUD_PHONE_NUMBER_IDis the business phone number ID used by the/messagesand/mediaendpoints -
WHATSAPP_CLOUD_WEBHOOK_VERIFY_TOKENis your own shared secret for thehub.*verification challenge -
WHATSAPP_CLOUD_APP_SECRETlets Pair verifyX-Hub-Signature-256on inbound webhooks
STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETSTRIPE_API_VERSION
Notes:
-
STRIPE_SECRET_KEYis required only when using the defaultStripeGatewaySDK client -
STRIPE_WEBHOOK_SECRETis required only for Stripe webhook signature verification -
STRIPE_API_VERSIONis optional; when set, Pair passes it to the Stripe PHP SDK asstripe_version
OPENAI_API_KEYOPENAI_API_BASE_URLOPENAI_RESPONSES_MODELOPENAI_EMBEDDINGS_MODELOPENAI_REALTIME_MODELOPENAI_TIMEOUTOPENAI_CONNECT_TIMEOUTOPENAI_STORE_RESPONSES
Notes:
-
OPENAI_API_KEYis required only when usingOpenAIClientoutbound calls -
OPENAI_STORE_RESPONSES=falsekeeps Responses API calls privacy-first by default -
OPENAI_RESPONSES_MODEL,OPENAI_EMBEDDINGS_MODEL, andOPENAI_REALTIME_MODELcan be changed per application or per request
GEMINI_API_KEYGEMINI_API_BASE_URLGEMINI_GENERATION_MODELGEMINI_EMBEDDINGS_MODELGEMINI_TIMEOUTGEMINI_CONNECT_TIMEOUT
Notes:
-
GEMINI_API_KEYis required only when usingGeminiClientoutbound calls -
GEMINI_GENERATION_MODELandGEMINI_EMBEDDINGS_MODELcan be changed per application or per request
CLAUDE_API_KEYCLAUDE_API_BASE_URLCLAUDE_MESSAGES_MODELCLAUDE_API_VERSIONCLAUDE_MAX_TOKENSCLAUDE_TIMEOUTCLAUDE_CONNECT_TIMEOUT
Notes:
-
CLAUDE_API_KEYis required only when usingClaudeClientoutbound calls -
CLAUDE_API_VERSIONconfigures the required Anthropic API version header -
CLAUDE_MAX_TOKENSis the default output cap when callers omitmax_tokens
RESEND_API_KEYRESEND_API_BASE_URLRESEND_FROM_ADDRESSRESEND_FROM_NAMERESEND_WEBHOOK_SECRETRESEND_TIMEOUTRESEND_CONNECT_TIMEOUT
Notes:
-
RESEND_API_KEYis required only when usingResendMaileroutbound calls -
RESEND_FROM_ADDRESSandRESEND_FROM_NAMEprovide the default sender identity -
RESEND_WEBHOOK_SECRETis required only for signed webhook verification
PAIR_HUMAN_CHALLENGE_PROVIDERCLOUDFLARE_TURNSTILE_SITE_KEYCLOUDFLARE_TURNSTILE_SECRET_KEYCLOUDFLARE_TURNSTILE_VERIFY_URLCLOUDFLARE_TURNSTILE_RESPONSE_FIELDCLOUDFLARE_TURNSTILE_TIMEOUTCLOUDFLARE_TURNSTILE_CONNECT_TIMEOUT
Notes:
-
PAIR_HUMAN_CHALLENGE_PROVIDERcan beauto,turnstile,recaptcha,captcha, ornone -
CLOUDFLARE_TURNSTILE_SITE_KEYis used byCloudflareTurnstileto render browser widgets -
CLOUDFLARE_TURNSTILE_SECRET_KEYis required only for server-side token validation -
CLOUDFLARE_TURNSTILE_RESPONSE_FIELDdefaults to the standard Turnstile field posted by implicit widgets - Turnstile works independently from Cloudflare CDN usage
GOOGLE_RECAPTCHA_SITE_KEYGOOGLE_RECAPTCHA_SECRET_KEYGOOGLE_RECAPTCHA_VERIFY_URLGOOGLE_RECAPTCHA_RESPONSE_FIELDGOOGLE_RECAPTCHA_TIMEOUTGOOGLE_RECAPTCHA_CONNECT_TIMEOUT
Notes:
-
GOOGLE_RECAPTCHA_SITE_KEYis used byHumanChallengeto render CAPTCHA widgets whenPAIR_HUMAN_CHALLENGE_PROVIDER=recaptchaorcaptcha -
GOOGLE_RECAPTCHA_SECRET_KEYis required only for server-side token validation -
GOOGLE_RECAPTCHA_RESPONSE_FIELDdefaults to the standardg-recaptcha-responsefield posted by reCAPTCHA widgets
MEILISEARCH_HOSTMEILISEARCH_API_KEYMEILISEARCH_DEFAULT_INDEXMEILISEARCH_TIMEOUTMEILISEARCH_CONNECT_TIMEOUTMEILISEARCH_SEARCH_LIMIT
Notes:
-
MEILISEARCH_HOSTpointsMeilisearchClientto the Meilisearch instance -
MEILISEARCH_API_KEYis optional only for unsecured local development instances -
MEILISEARCH_DEFAULT_INDEXis used by read-model sync when an index is not passed explicitly -
MEILISEARCH_SEARCH_LIMITapplies only when a search call does not pass explicit pagination
PUSH_VAPID_PUBLICPUSH_VAPID_PRIVATEPUSH_VAPID_SUBJECT
- Keep secrets in
.env, not in Git. - Keep numeric/boolean values unquoted if you want automatic type casting.
- Keep
APP_ENValigned with your deployment target (development/staging/production). - Use environment-specific
.envvalues for local/staging/production. - Keep
GOOGLE_MAPS_API_KEYserver-side only and use a browser-restricted key forGOOGLE_MAPS_BROWSER_API_KEY. - Keep
WHATSAPP_CLOUD_ACCESS_TOKENandWHATSAPP_CLOUD_APP_SECRETserver-side only. - Keep
CLOUDFLARE_TURNSTILE_SECRET_KEYserver-side only and validate tokens before public writes. - Keep
MEILISEARCH_API_KEYserver-side only and index only fields that are safe to expose in search results. - Keep observability exporter credentials server-side only and avoid sending request bodies or secrets in telemetry attributes.
- Tune API limits by traffic class and verify
429handling in clients.
See also: Env, API, RateLimiter, ThrottleMiddleware, Request, SocialAuth, CloudflareTurnstile, MeilisearchClient.