API Key Management Feature
Added user-specific API key management to the chat application, allowing multiple users to use their own API keys instead of relying on a single .env file.
1. State Management (frontend/app/state.js)
2. Storage (frontend/app/storage.js)
Added separate localStorage key chatapp-api-keys for API key storage
Implemented API key management methods:
loadApiKeys() - Load API keys from localStorage on init
saveApiKeys() - Persist API keys to localStorage
updateApiKey(provider, key) - Update specific provider's API key
getApiKey(provider) - Retrieve API key for a provider
clearApiKeys() - Clear all API keys
3. UI (frontend/index.html)
Added "API Keys" section in the right sidebar settings panel
Groq API Key input field with:
Password-type input for security
Toggle visibility button (eye icon)
Monospace font for better readability
Link to Groq console for obtaining API keys
Placeholder for OpenAI API key (coming soon)
4. Messaging (frontend/app/messaging.js)
Updated sendChatRequest() to:
Extract provider from model ID (e.g., groq/compound → groq)
Retrieve user's API key for that provider
Pass API key in job creation request
5. Chat Settings (frontend/app/chatSettings.js)
Updated getChatParameters() to include systemPrompt in returned parameters
1. Type Definitions (backend/providers/types.ts)
Added apiKey?: string to ChatCompletionOptions interface
Added systemPrompt?: string to ChatCompletionOptions interface
2. Groq Provider (backend/providers/groq.ts)
Updated complete() and stream() methods to:
Accept API key from options.apiKey if provided
Fall back to environment variable if no API key in options
Prepend system prompt to messages if provided
Include imageDetail in request body
Return better error messages when API key is missing
3. Chat Routes (backend/routes/chat.ts)
Updated /api/chat endpoint to:
Accept apiKey parameter from request body
Accept all Groq-specific parameters
Skip isConfigured() check if API key is provided in request
Pass API key through to provider in options
4. Jobs Routes (backend/routes/jobs.ts)
Updated ChatJobInput interface to include apiKey and systemPrompt
Updated runChatJob() function to:
Extract API key from job input
Skip isConfigured() check if API key is provided
Pass API key through to provider in options
Provide helpful error message when API key is missing
Local Storage : API keys are stored in browser's localStorage
Keys never leave the user's browser except when making API calls
Each user maintains their own keys
Keys are stored separately from chat data
Password Input : API key input uses type="password" by default
Users can toggle visibility with eye icon
Prevents shoulder surfing
No Server-Side Storage : Backend never stores user-provided API keys
Keys are only passed through for API calls
Falls back to .env for backward compatibility
Click the settings (cog) icon in the chat header
Scroll to "API Keys" section
Enter your Groq API key (get one from https://console.groq.com/keys )
The key is automatically saved to your browser
Start chatting - your personal API key will be used
Environment variable still works: set GROQ_API_KEY in .env
Users without API keys will fall back to env variable
To require user API keys: remove GROQ_API_KEY from .env
Additional Providers
OpenAI API key support
Anthropic API key support
Custom provider configuration
Key Validation
Test API key button
Show connection status indicator
Validate key format before saving
Enhanced Security
Optional key encryption in localStorage
Session-only keys (not persisted)
Key expiration reminders
Multi-User Features
Profile management
Multiple key sets per user
Usage tracking per API key
To test the feature:
Remove GROQ_API_KEY from your .env file
Open the chat app
Try to send a message - should get error about missing API key
Add your API key in settings
Send message again - should work with your key
Refresh page - API key should persist
Toggle password visibility - should mask/unmask key
Existing .env configuration still works
Users can continue using shared API keys
Gradual migration to user-specific keys
No breaking changes to existing functionality