IntelliPlan is configured entirely through environment variables — there is no GUI settings panel and no config file committed to the repository. In local development, copyDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/UAnirudh/IntelliPlan/llms.txt
Use this file to discover all available pages before exploring further.
.env.example to .env (which is gitignored) and fill in real values. On Railway, Render, or any other PaaS, set these as dashboard environment variables rather than committing them. The sections below cover every variable IntelliPlan reads, what happens when one is absent, and where to get the value.
Core
These four variables must be set in every environment. The application will start without them but will be insecure or non-functional.Flask’s cryptographic signing key. Used for session cookies, CSRF tokens, and any other signed value. Set this to a long, random string and never reuse it across deployments. Generate one with:
The canonical origin of the deployment, e.g.
https://intelliplan.tech. Used to construct absolute URLs in emails, OAuth redirect URIs, push notification endpoints, and the IndexNow key file path. Include the scheme; omit the trailing slash.SQLAlchemy connection string. Defaults to
sqlite:///intelliplan.db in the template, which is fine for local development. For production, use a Postgres URL such as postgresql://user:pass@host/dbname.The port Gunicorn binds to. Most PaaS hosts inject this automatically; the value in
.env is only needed for local runs.Admin
Comma-separated list of email addresses that can access the admin panel at the path defined by
ADMIN_PATH. Example: uanirudh0811@gmail.com. Users not on this list are rejected with 403.The URL path for the admin panel. The default is intentionally obscure. Change it to something secret for your deployment and keep it out of public documentation.
AI — Model Keys
API key for Google Gemini, IntelliPlan’s primary AI provider. Get one at aistudio.google.com/apikey. The free tier allows 20 requests per day on
gemini-2.5-flash; once that quota is spent every AI feature stops unless a Groq fallback key is also set. See AI Providers for the full fallback chain.API key for Groq, IntelliPlan’s fallback AI provider. Strongly recommended even though it is technically optional — without it, exhausting the Gemini free-tier quota takes down all AI features. Get a free key at console.groq.com/keys.
API key for Anthropic Claude. Only ever called for accounts on the paid plan — leaving this unset simply drops Claude from the provider chain. If set, paid users receive Claude Sonnet for standard tasks and Claude Haiku for fast tasks.
Comma-separated list of email addresses that receive paid-plan AI access before a formal billing system exists. Useful for beta testers and team members.
A dedicated Groq API key for speech transcription (Whisper). Speech requests run against this key so that a long voice session cannot exhaust the key used for text answers. Falls back to
GROQ_API_KEY when unset.A dedicated Groq API key for image/vision requests. Falls back to
GROQ_API_KEY when unset.API key for Fish Audio, which powers Plani’s read-aloud voice feature. Get a key at fish.audio. Without this key the read-aloud button is hidden.
Server-side
sk_ secret key for Pollinations, used for AI image, video, and 3D generation. Obtain one at enter.pollinations.ai/keys. This must be a secret key — a publishable pk_ key in server code would allow anyone to spend the balance.AI Firewall — Rate Limits
All limits are optional. When unset, the defaults shown below apply. Counters are stored in the database (not in process memory) so they survive deploys and are shared across multiple instances.Rate limits are per account for signed-in users, and per signed device cookie for guests. A guest keeps their identity across IP changes, so a school behind one NAT address is not treated as a single student.
- Guest
- Free
- Paid
| Variable | Default | Description |
|---|---|---|
AI_GUEST_RPH | 4 | Requests per hour |
AI_GUEST_RPD | 8 | Requests per day |
AI_GUEST_TPD | 12000 | Estimated tokens per day |
AI_GUEST_MAX_OUTPUT | 1200 | Maximum output tokens per request |
Set to
1 to disable every AI feature site-wide without a deploy. Useful for cost emergencies or provider outages. Unset or set to 0 to re-enable.Google OAuth + Calendar
OAuth 2.0 Client ID from Google Cloud Console. Used for “Sign in with Google” and Google Calendar sync.
OAuth 2.0 Client Secret matching
GOOGLE_CLIENT_ID.Must be registered in Google Cloud Console and match byte-for-byte. Default:
https://intelliplan.tech/oauth2callback.Notion OAuth
Client ID from a public Notion integration created at app.notion.com/developers/connections. A public connection (not an internal integration) is required for users to authorize IntelliPlan to read their Notion workspace.
Client secret for the Notion integration.
Must be registered in the Notion integration’s OAuth configuration and match byte-for-byte — Notion rejects the token exchange otherwise. Default:
https://intelliplan.tech/oauth/notion/callback. Add a second redirect URI for local development if needed (e.g. http://localhost:5000/oauth/notion/callback).Canvas OAuth
Developer Key ID from Canvas (canvas.instructure.com for the public instance, or a school’s own Canvas host). See
.env.example for step-by-step instructions on registering a Developer Key.Developer Key secret matching
CANVAS_CLIENT_ID.Default:
https://intelliplan.tech/oauth/canvas/callback. Must match the Developer Key registration exactly.Base URL for the public Canvas instance. For schools with a self-hosted Canvas, set per-institution overrides using the pattern
CANVAS_CLIENT_ID_<HOST_UPPERCASE> and CANVAS_CLIENT_SECRET_<HOST_UPPERCASE>, replacing dots and dashes with underscores.Google Classroom
OAuth 2.0 Client ID for Google Classroom. Separate from the Google Calendar credentials — Classroom requires its own OAuth consent screen scope.
Client secret for Google Classroom OAuth.
Blackboard Learn OAuth
Blackboard uses a three-legged (3LO) OAuth flow. Three distinct values are issued by the Anthology developer portal — they are not interchangeable. Runpython scripts/blackboard_doctor.py to validate your configuration without printing any secret values.
The UUID sent as OAuth
client_id. This is not the Application ID — confusing the two causes Blackboard to return {"code":"illegalArgument","message":"invalid client_id"} after the student has already signed in.The secret matching
BLACKBOARD_APP_KEY.The UUID the school’s Blackboard administrator must add under System Admin → Integrations → REST API Integrations with End User Access set to Yes. IntelliPlan shows this value to students whose school has not yet approved the integration so they can hand it to their admin.
OAuth scopes.
offline is required — without it Blackboard issues no refresh token and every connection dies at the first expiry (approximately one hour).Default:
https://intelliplan.tech/api/lms/callback/blackboard. Must match the developer portal registration byte-for-byte.Moodle
Set to
0 to hide the Moodle integration in the Connect screen while an institution is not ready to issue web-service tokens. Does not affect existing connections.Email — Resend (Preferred)
API key from resend.com/api-keys. When set, Resend is used for all outgoing email. See Email Configuration for domain setup.
The
From address for all emails sent via Resend. Must use a domain verified in your Resend account. For the recommended subdomain setup, use IntelliPlan <noreply@send.intelliplan.tech>.Email — SMTP Fallback
Used only whenRESEND_API_KEY is not set.
Hostname of the SMTP server (e.g.
smtp.gmail.com).SMTP port. 587 (STARTTLS) is the standard for most providers.
SMTP username, usually the sending email address.
SMTP password. For Gmail, create an App Password at myaccount.google.com/apppasswords — spaces are stripped automatically.
The
From address when using SMTP. Defaults to SMTP_USER when unset.Lifecycle Email — Reply Routing
Physical postal address printed in the footer of every marketing email (newsletter, feedback request). Required by CAN-SPAM §7704(a)(5). With this unset, newsletter and feedback sends refuse to run and log loudly. A PO box or registered agent’s address is acceptable. See Email Configuration for details.
Where student replies to lifecycle emails actually land. Must be a mailbox that receives email — a send-only domain silently bounces every reply. Use a Gmail address or any working inbox until the sending domain has MX records.
Support contact address printed in email bodies as a
mailto: link. Falls back to MARKETING_REPLY_TO when unset.Push Notifications (VAPID)
Base64url-encoded uncompressed ECDH public key. Generate once with
python vapid.py. See Push Notifications for full setup instructions.Base64url-encoded raw 32-byte ECDH private key. Treat like a password — rotating it invalidates every existing browser subscription.
An email address a push service can reach you at. Sent as the
sub claim in the VAPID JWT; some services (notably FCM) reject pushes that lack it.Cron
Shared secret that authorizes calls to all cron endpoints (
/cron/notifications, /cron/send-reminders, /cron/lifecycle-emails, /cron/weekly-newsletter). Pass as the X-Cron-Token or X-Cron-Secret header, or as a ?secret= query parameter. Without this set, every cron endpoint returns 503 and nothing is ever delivered.Sentry
Data Source Name from your Sentry project. When set, unhandled exceptions and errors are reported to Sentry. Leaving this unset disables error reporting entirely — the application functions normally without it.
Encryption at Rest
Fernet key used to encrypt all third-party OAuth tokens stored in the database (Canvas, Google, Notion, Blackboard, Moodle). Without it those tokens are stored in plaintext. Generate a key with:To rotate: put the new key first, comma-separated (
new,old). Values are decrypted with any listed key and always written with the first. Then run scripts/encrypt_existing_tokens.py. Losing this key is not recoverable — affected students must reconnect their accounts.reCAPTCHA
Public site key from google.com/recaptcha/admin. Both
RECAPTCHA_SITE_KEY and RECAPTCHA_SECRET_KEY must be set or the check remains off entirely.Secret key for server-side verification. Never expose this in client-side code.
Which reCAPTCHA widget to render.
v2 draws a checkbox; v3 is invisible and score-based. This must match the type of key you registered — a mismatch causes the widget to not appear at all.v3 only. Google’s default is 0.5. Setting this too high causes real students on shared or VPN’d connections to be refused. Verification fails open if Google is unreachable — a Google outage will not cause an IntelliPlan outage.
Analytics
IntelliPlan loads no third-party analytics script in the browser. Product usage is measured server-side via PostHog, which sets no browser cookie. Microsoft Clarity was removed to honour the privacy promise made to schools. Any analytics added in future must be declared in
cookie_policy.py and gated on consent.IndexNow
IndexNow key served at
/<key>.txt. Used to notify participating search engines (Bing, Yandex) when public URLs change. The default value in .env.example is the live production key.Full URL to the key file, e.g.
https://intelliplan.tech/15d38c49db0d48efa4ec2ad2635b43c9.txt.IndexNow submission endpoint.