AI Module
LaunchKit Pro is an AI-ready full-stack SaaS starter kit with mock mode and provider-ready OpenAI/Gemini adapters. It includes prompt templates, text generation, usage tracking, history, and demo/test account guardrails — not a finished hosted AI SaaS business with bundled provider credits.
Default install uses AI_PROVIDER=MOCK — no external API keys required. Buyers can run the app immediately, then enable OpenAI or Gemini by adding their own provider key in server environment variables.
AI module overview
The AI module provides:
| Capability | Description |
|---|---|
| Mock AI provider | Deterministic sample outputs for local dev and demos |
| OpenAI adapter | Chat Completions when AI_PROVIDER=OPENAI |
| Gemini adapter | Google Generative Language API when AI_PROVIDER=GEMINI |
| Provider switch | Single active provider selected via AI_PROVIDER env |
| Provider status | GET /ai/provider-status — configured provider, model, demo flags |
| Generation | POST /ai/generate — workspace-scoped text generation |
| History | GET /ai/history — paginated generations with sample badges |
| Usage | GET /ai/usage — workspace usage summary |
| Templates | GET /ai/templates and GET /ai/templates/:templateId |
| Usage limits | Plan limits + system ceiling + test-user caps |
| Demo restrictions | Public demo can view UI and sample history; generation blocked |
| Admin reporting | GET /admin/ai-usage — platform aggregates |
Provider implementation lives in the backend under src/modules/ai/providers/. API keys are never returned in API responses, logs, or audit metadata.
Provider modes
| Mode | Env | API key required | Notes |
|---|---|---|---|
| MOCK | AI_PROVIDER=MOCK (default) | None | Works out of the box; no external calls |
| OPENAI | AI_PROVIDER=OPENAI | OPENAI_API_KEY only | Inactive Gemini key can stay empty |
| GEMINI | AI_PROVIDER=GEMINI | GEMINI_API_KEY only | Inactive OpenAI key can stay empty |
Rules:
- The app does not require both OpenAI and Gemini keys together — only the active provider needs a key.
- Inactive provider keys can remain empty in
.env. - Real AI usage requires buyer-owned provider keys and may incur costs from OpenAI or Google.
Environment variables
Copy from backend .env.example. All AI vars are optional for mock install except defaults already set.
| Variable | Default | Description |
|---|---|---|
AI_PROVIDER | MOCK | Active provider: MOCK, OPENAI, or GEMINI |
AI_DEFAULT_MODEL | (empty) | Optional model override for any provider |
AI_OPENAI_MODEL | gpt-4.1-mini | Default OpenAI model |
AI_GEMINI_MODEL | gemini-2.5-flash | Default Gemini model |
OPENAI_API_KEY | (empty) | Required when AI_PROVIDER=OPENAI |
GEMINI_API_KEY | (empty) | Required when AI_PROVIDER=GEMINI |
AI_MONTHLY_GENERATION_LIMIT | 100 | System ceiling combined with plan limits |
AI_TEST_USER_MONTHLY_LIMIT | 5 | Monthly cap for test accounts |
AI_TEST_USER_EMAILS | testuser@launchkitlabs.com,test@launchkitlabs.com | Comma-separated test account emails |
AI_DEMO_RESTRICTED_EMAILS | demo@launchkitlabs.com | Demo accounts blocked from generation |
AI_DEMO_BLOCK_REAL_GENERATION | true | Block AI generate for demo emails |
AI_DEMO_SHOW_SAMPLE_HISTORY | true | Seed/show sample history for demo accounts |
See Environment Variables for the full backend reference.
Setup examples
Mock (default — no API key)
AI_PROVIDER=MOCKMock mode is active. No external AI key is required.
OpenAI
AI_PROVIDER=OPENAI
OPENAI_API_KEY=your_openai_key
AI_OPENAI_MODEL=gpt-4.1-miniOnly OPENAI_API_KEY is required. Leave GEMINI_API_KEY empty.
Gemini
AI_PROVIDER=GEMINI
GEMINI_API_KEY=your_gemini_key
AI_GEMINI_MODEL=gemini-2.5-flashOnly GEMINI_API_KEY is required. Leave OPENAI_API_KEY empty.
Restart the API after changing provider env vars.
API endpoints
All routes require JWT auth (Authorization: Bearer <accessToken>) unless noted.
Flat routes (dashboard frontend)
| Method | Path | Purpose |
|---|---|---|
GET | /ai/provider-status | Active provider, model, configured flag, demo restriction |
POST | /ai/generate | Generate text for current workspace (optional workspaceId in body/query) |
GET | /ai/history | Paginated generation history |
GET | /ai/usage | Workspace usage summary |
GET | /ai/templates | List active prompt templates |
GET | /ai/templates/:templateId | Single template detail |
Workspace routes (RBAC)
| Method | Path | Permission | Purpose |
|---|---|---|---|
POST | /workspaces/:workspaceId/ai/generate | ai.generate | Generate text |
GET | /workspaces/:workspaceId/ai/generations | ai.view | Paginated history |
GET | /workspaces/:workspaceId/ai/usage | ai.view_usage | Usage summary |
Admin
| Method | Path | Permission | Purpose |
|---|---|---|---|
GET | /admin/ai-usage | admin.ai_usage.view | Platform aggregates + recent records |
NestJS route ordering
Static routes such as /ai/provider-status and /ai/templates must be declared before dynamic :param routes (e.g. /ai/templates/:templateId) in NestJS controllers.
Example requests
# Provider status
curl -s http://localhost:4000/ai/provider-status \
-H "Authorization: Bearer <accessToken>" | jq
# Generate (uses AI_PROVIDER from env)
curl -s -X POST http://localhost:4000/ai/generate \
-H "Authorization: Bearer <accessToken>" \
-H "Content-Type: application/json" \
-d '{"prompt":"Write a welcome email for new SaaS users."}' | jq
# History
curl -s "http://localhost:4000/ai/history?page=1&limit=20" \
-H "Authorization: Bearer <accessToken>" | jq
# Usage
curl -s http://localhost:4000/ai/usage \
-H "Authorization: Bearer <accessToken>" | jq
# Templates
curl -s http://localhost:4000/ai/templates \
-H "Authorization: Bearer <accessToken>" | jqOptional generate fields: templateId, systemPrompt, model, temperature, workspaceId.
Demo account behavior
When AI_DEMO_BLOCK_REAL_GENERATION=true and the user email is in AI_DEMO_RESTRICTED_EMAILS (default includes demo@launchkitlabs.com):
- The AI UI remains visible — Playground, History, Usage, and Templates are not hidden.
- Generation is blocked with HTTP 403 to protect provider credits.
- The frontend shows a warning toast with the backend message.
- Sample AI history is available when
AI_DEMO_SHOW_SAMPLE_HISTORY=true(default).
Typical block message:
Demo account restriction: real AI generation is disabled in the public demo. Sample AI results are available in history.
Test user limits
Test accounts listed in AI_TEST_USER_EMAILS receive a tighter monthly cap via AI_TEST_USER_MONTHLY_LIMIT (default 5).
When the limit is reached, generation returns a readable error such as:
Test account AI limit reached. Please use an admin or normal account for more generations.
Admin and normal users generate according to workspace plan limits and AI_MONTHLY_GENERATION_LIMIT.
Frontend pages
| Path | Purpose |
|---|---|
/dashboard/ai | AI Studio overview |
/dashboard/ai/playground | Run generations |
/dashboard/ai/templates | Browse templates |
/dashboard/ai/history | Past generations (includes Demo Sample badges) |
/dashboard/ai/usage | Usage summary |
The frontend reads provider status from GET /ai/provider-status and shows friendly configuration messages — never API keys.
Buyer notes
- LaunchKit Pro ships AI-ready infrastructure, not preconfigured production AI with free credits.
- Mock mode is the intentional default so buyers can install without vendor accounts.
- Enabling OpenAI or Gemini requires your own API keys and acceptance of provider pricing.
- Monitor usage via
/dashboard/ai/usageand/admin/ai-usage. - Never commit provider keys to git — store them in server env or a secrets manager only.
WARNING
Never commit AI API keys. Rotate keys immediately if exposed.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| Provider selected but API key missing | AI_PROVIDER=OPENAI or GEMINI without key | Add the matching key or switch to AI_PROVIDER=MOCK |
| Mock works but real provider fails | Invalid key, model name, or network | Verify key in provider dashboard; check model env; read backend logs |
| Demo account generation blocked | Expected demo protection | Use a non-demo account to test real generation; view sample history on History page |
| Test account limit reached | AI_TEST_USER_MONTHLY_LIMIT exceeded | Use admin/normal account or raise limit in server env |
| 401 Unauthorized | Missing or expired JWT | Log in again; send Authorization: Bearer header |
| 404 Not Found | Route not deployed or module not registered | Confirm API version, migrations applied, and AI module loaded |
| Template route 404 | Dynamic route registered before static | Ensure static /ai/templates routes precede :templateId in controller |
See also Troubleshooting and Demo Mode.