Skip to content

Environment variables

All environment variables required to run Classmoji

NameRequiredDefaultDescription
DATABASE_URLYesPostgreSQL connection string for the Classmoji database.
BETTER_AUTH_SECRETYesSecret used to sign auth sessions and tokens. Generate with openssl rand -base64 32.
WEBAPP_URLYesPublic base URL of the main web app (e.g. http://localhost:3000).
SLIDES_URLYesPublic base URL of the slides service.
PAGES_URLYesPublic base URL of the pages service.
NameRequiredDefaultDescription
GITHUB_APP_NAMENoSlug of your Github App, used to build install and authorization links.
GITHUB_APP_IDNoNumeric ID of your Github App.
GITHUB_CLIENT_IDNoOAuth client ID for Github sign-in.
GITHUB_CLIENT_SECRETNoOAuth client secret for Github sign-in.
GITHUB_WEBHOOK_SECRETNoSecret used to verify incoming Github webhook signatures. Generate with openssl rand -base64 32.
GITHUB_PRIVATE_KEY_BASE64NoBase64-encoded private key for your Github App, used to authenticate API requests.

AI features (quizzes, Ask Moji, prompt assistant) run on Anthropic Claude. They are optional: when AI_AGENT_URL and AI_AGENT_SHARED_SECRET are unset, AI features are hidden and the related API routes return 503.

NameRequiredDefaultDescription
AI_AGENT_URLNoURL of the AI agent service. Enables AI features when set with the shared secret.
AI_AGENT_SHARED_SECRETNoShared secret used to authenticate the webapp to the AI agent.
ANTHROPIC_API_KEYNoAnthropic API key the AI agent uses to call Claude.
LLM_MODELNoclaude-sonnet-5-5Claude model used for quizzes and the quiz prompt assistant. These accept only the models listed in packages/utils/src/aiModels.ts; any other value runs the default. Set the same value in all three places that read it: the AI agent and the background jobs, which run quizzes, and the web app, which shows it as the default on AI settings.
EXPLORATION_MODELNoclaude-sonnet-5-5Claude model used for code-aware quiz repository exploration. Same list and default as LLM_MODEL, read by the same three: the AI agent, the background jobs and the web app.
EXPLORATION_MODENoControls the code-aware exploration behavior for quizzes.
QUIZ_QUESTION_EFFORTNomediumReasoning effort (low, medium, high, xhigh, max) for quiz question and conversation turns. A classroom with its own API key can override it.
QUIZ_GRADING_EFFORTNohighReasoning effort for final quiz grading. A classroom with its own API key can override it.
EXPLORATION_EFFORTNolowReasoning effort for the code-aware quiz’s excerpt selection (xhigh and max run as high). A classroom with its own API key can override it.
SYLLABUS_BOT_MODELNoLLM_MODEL, then claude-sonnet-5-5Claude model used for Ask Moji. Any Claude model id works here; the quiz list does not apply. Read by the AI agent, and by the web app to show the default. A classroom with its own API key can override it.
SYLLABUS_BOT_EFFORTNolowReasoning effort for Ask Moji. A classroom with its own API key can override it.
AI_MAX_BUDGET_USDNo1.00Per-call cost ceiling in USD for quiz and Ask Moji agent calls on the platform ANTHROPIC_API_KEY. A runaway guard, not a spend limit.
OPENAI_API_KEYNoReserved. Not used by any current feature.
LLM_PROVIDERNoReserved. Only Anthropic/Claude is wired today.
NameRequiredDefaultDescription
STRIPE_SECRET_KEYNoStripe secret API key for subscription checkout and billing.
STRIPE_WEBHOOK_SECRETNoSecret used to verify incoming Stripe webhook signatures.
NameRequiredDefaultDescription
EMAILNoAddress used as the sender for outgoing email.
EMAIL_PASSWORDNoPassword (or app password) for the sending email account.
NameRequiredDefaultDescription
TRIGGER_API_URLNoBase URL of the Trigger.dev API. Leave unset to use Trigger.dev cloud.
TRIGGER_PUBLIC_API_URLNoPublic Trigger.dev API address that GitHub Actions can reach; the generated autograding workflow reports results to it. Leave unset for Trigger.dev cloud. Not the worker-internal TRIGGER_API_URL.
TRIGGER_SECRET_KEYNoTrigger.dev secret key used to authenticate background job runs.

Large files (video, audio, big PDFs) go to a Cloudflare R2 bucket rather than into a classroom’s content repo. The four MEDIA_R2_* variables are optional and all-or-nothing: with any of them unset, media upload is hidden in the UI and the media API routes return 503.

NameRequiredDefaultDescription
MEDIA_R2_ACCOUNT_IDNoCloudflare account the media bucket lives in. Used to build the R2 S3 endpoint.
MEDIA_R2_ACCESS_KEY_IDNoAccess key of an R2 API token scoped to the media bucket (object read/write).
MEDIA_R2_SECRET_ACCESS_KEYNoSecret of that R2 API token. It never leaves the server: uploads are presigned and the browser writes straight to R2.
MEDIA_R2_BUCKETNoName of the R2 bucket media objects are written to.
CLOUDINARY_CLOUD_NAMENoCloudinary cloud name for image and media uploads.
CLOUDINARY_API_KEYNoCloudinary API key for signed uploads.
CLOUDINARY_API_SECRETNoCloudinary API secret for signed uploads.
NameRequiredDefaultDescription
CALENDAR_SECRETNoSecret used to sign calendar feed (iCal) URLs. Generate with openssl rand -base64 32.