The Gemini API key is stored using Devvit's built-in settings system. This is the recommended approach for managing sensitive configuration in Devvit apps.
- Go to https://aistudio.google.com/app/apikey
- Sign in with your Google account
- Click "Create API Key"
- Copy the key (starts with
AIza...)
- Go to https://console.cloud.google.com/
- Create a new project or select existing
- Enable the "Generative Language API"
- Go to Credentials → Create Credentials → API Key
- Copy the key
Pricing:
- Free tier: 15 requests/minute, 1,500 requests/day
- Paid tier: $0.075 per 1M input tokens, $0.30 per 1M output tokens
The easiest way to set the API key is using the Devvit CLI:
# Set the API key for your app
npx devvit settings set apiKey
# You'll be prompted to enter the key securely
# Or provide it directly:
npx devvit settings set apiKey "AIza...your-key-here"Benefits:
- ✅ Secure: Key is encrypted and stored securely by Devvit
- ✅ Simple: No custom endpoints needed
- ✅ Standard: Follows Devvit platform conventions
- ✅ Persistent: Survives deployments and updates
# List all settings (values are hidden for security)
npx devvit settings list
# Output:
# apiKey: ********** (set)# Try analyzing a document
curl -X POST https://your-app.reddit.com/api/analyze \
-H "Content-Type: application/json" \
-d '{
"fileData": "data:image/png;base64,...",
"fileType": "image/png",
"fileName": "test.png"
}'
# If key is not set, you'll get:
{
"error": "Gemini API key not configured. Run: npx devvit settings set apiKey"
}In src/server/ai/gemini.ts:
import { GoogleGenerativeAI } from '@google/generative-ai';
import { settings } from '@devvit/web/server';
export async function analyzeDocument(
fileData: string,
fileType: string
): Promise<{ description: string; summary: string }> {
// Retrieve API key from Devvit settings
const apiKey = await settings.get('apiKey');
if (!apiKey) {
throw new Error('Gemini API key not configured. Run: npx devvit settings set apiKey');
}
// Initialize Gemini client with the key
const genAI = new GoogleGenerativeAI(apiKey as string);
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' });
// Make API call
const result = await model.generateContent([prompt, filePart]);
return parseResponse(result);
}The settings are defined in devvit.json:
{
"settings": [
{
"type": "string",
"name": "apiKey",
"label": "Gemini API Key",
"helpText": "Your Google Gemini API key for document analysis",
"isSecret": true
}
]
}- Encrypted storage: Devvit settings are encrypted and stored securely
- Moderator-only access: Only app developers/moderators can set settings via CLI
- No client exposure: Key never sent to client, only used server-side
- Persistent: Key survives deployments and updates
- Platform standard: Uses Devvit's recommended approach for secrets
- Shared key: All users of the app share the same API key
- Rate limiting: Implement per-user rate limits to prevent abuse
- CLI access required: Must have Devvit CLI access to set/update the key
Problem: The key hasn't been set via Devvit settings yet.
Solution:
- Get a Gemini API key from Google AI Studio
- Run
npx devvit settings set apiKeyin your project directory - Test the analysis endpoint
Problem: The key is set but doesn't work.
Solution:
- Verify the key is correct in Google AI Studio
- Check if the Generative Language API is enabled in your Google Cloud project
- Verify you haven't exceeded rate limits (15 req/min on free tier)
- Try generating a new API key
- Check the server logs for detailed error messages
Setup Flow:
- Get Gemini API key from Google AI Studio
- Add settings configuration to
devvit.json - Run
npx devvit settings set apiKeyto set the key - Deploy the app
- Analysis endpoint automatically uses the key from Devvit settings
Key Storage:
- Stored via Devvit settings system (encrypted)
- Setting name:
apiKey - Accessible only server-side via
settings.get('apiKey') - Persists across deployments
Why This Works:
- Uses Devvit's built-in secrets management
- No custom endpoints needed
- Follows platform best practices
- Secure and simple to manage