This guide covers obtaining, configuring, and securing the API keys required for Primr.
| Credential | Purpose | Console |
|---|---|---|
GEMINI_API_KEY |
Google AI for research & analysis | Google AI Studio |
That's it! Primr uses DuckDuckGo for web search by default — no search API key needed.
| Credential | Purpose | Console |
|---|---|---|
SEARCH_API_KEY |
Google Custom Search API (only if SEARCH_PROVIDER=google) |
Google Cloud Console |
SEARCH_ENGINE_ID |
Custom Search Engine config (only if SEARCH_PROVIDER=google) |
Programmable Search Engine |
Primr defaults to DuckDuckGo for web search, which requires no API keys. If you have a grandfathered Google Custom Search Engine with whole-web search, you can use it instead:
# In your .env file:
SEARCH_PROVIDER=google # Use Google Custom Search
SEARCH_API_KEY=your_key_here
SEARCH_ENGINE_ID=your_id_hereNote: Google deprecated "Search the entire web" for new Programmable Search Engines in January 2026. New CSEs are limited to 50 domains, making them unsuitable for Primr's use case. Only use
SEARCH_PROVIDER=googleif you have an existing whole-web CSE.
- Go to Google AI Studio
- Sign in with your Google account
- Click "Create API Key"
- Immediately copy the key - you won't see it again
- Store securely (see Secure Storage below)
Pricing: Free tier includes 60 requests/minute. See pricing.
- Go to Google Cloud Console
- Create a new project (recommended: separate project for Primr)
- Enable the Custom Search API:
- APIs & Services → Library → Search "Custom Search API" → Enable
- Create credentials:
- APIs & Services → Credentials → Create Credentials → API Key
- Restrict the key immediately (see Key Restrictions)
Pricing: 100 free queries/day, then $5/1000 queries.
- Go to Programmable Search Engine
- Click "Add" to create a new search engine
- Select "Search the entire web"
- Name it (e.g., "Primr Research")
- Copy the Search Engine ID from Control Panel
This is a configuration ID, not a secret - but still don't share publicly.
cp .env.example .env
chmod 600 .env # Restrict file permissions (Linux/macOS)Edit .env with your keys. The file is gitignored by default.
Never use environment variables directly in shell - they persist in shell history:
# BAD - logged in shell history
export GEMINI_API_KEY="your-key"
# GOOD - use .env file or prompt
read -s GEMINI_API_KEY # Prompts without echoFor production deployments, use a secrets manager instead of .env files:
| Platform | Service | Documentation |
|---|---|---|
| AWS | Secrets Manager | docs |
| GCP | Secret Manager | docs |
| Azure | Key Vault | docs |
| Self-hosted | HashiCorp Vault | docs |
See CLOUD_DEPLOYMENT.md for integration examples.
Always restrict API keys - an unrestricted key is a liability.
- Go to APIs & Services → Credentials
- Click on your API key
- Under "API restrictions": Select "Restrict key" → Custom Search API only
- Under "Application restrictions":
- Servers: Restrict by IP address
- Web apps: Restrict by HTTP referrer
- Local dev: Can leave unrestricted, but use a separate dev key
Currently limited options, but:
- Use separate keys for dev/staging/prod
- Monitor usage in AI Studio dashboard
- Set up billing alerts
primr doctorHealthy output shows all checks passing. If keys are invalid or expired, doctor will identify which one.
| Error | Cause | Fix |
|---|---|---|
| "API key expired" | Key revoked or project deleted | Create new key in Cloud Console |
| "Quota exceeded" | Hit rate/daily limit | Wait for reset, or use --mode deep (uses Gemini search) |
| "Invalid API key" | Typo, extra whitespace, or wrong key | Re-copy from console, check for spaces |
| "API not enabled" | Custom Search API not enabled | Enable in Cloud Console → APIs & Services |
| "Forbidden" | Key restrictions blocking request | Check IP/referrer restrictions |
Google API keys don't expire automatically, but rotate them:
- Every 90 days for production
- Immediately if potentially exposed
- When team members leave
Rotation process:
- Create new key in Cloud Console
- Update
.envor secrets manager - Verify with
primr doctor - Delete old key in Cloud Console
For the MCP server's own authentication (separate from Google keys):
from primr.api.auth import create_api_key, rotate_api_key
# Create key with expiration
key = create_api_key("client-name", expires_in_days=90)
# Rotate with grace period
new_key = rotate_api_key(old_key, grace_hours=24)Act immediately:
- Revoke the key in Google Cloud Console (don't just rotate)
- Check usage logs for unauthorized activity:
- Cloud Console → APIs & Services → Metrics
- Create new key with restrictions
- Audit access - who had the key, how was it exposed?
- Review billing for unexpected charges
If you see unauthorized usage, contact Google Cloud support.
primr --dry-run "Company Name" https://company.com| Mode | Tokens | Deep Research | Search | Total |
|---|---|---|---|---|
| scrape | ~$0.05 | -- | ~$0.04 | ~$0.10 |
| deep | -- | ~$2.50 | -- | ~$2.50 |
| full | ~$0.60 | ~$2.50 | ~$0.35 | ~$3.50 |
Deep Research is a flat per-task fee from Google (not token-based). Search costs $0.035/query. Use primr --dry-run for estimates based on your actual usage history.
In Google Cloud Console:
- Billing → Budgets & alerts
- Create budget with email alerts at 50%, 90%, 100%
- Keys stored in
.envfile (not shell history) -
.envhas restricted permissions (chmod 600) -
.envis in.gitignore - API keys restricted to Custom Search API only
- Separate keys for dev/staging/prod
- Billing alerts configured
- Key rotation scheduled (90 days)
- Team knows incident response process
- CONFIG.md - Full configuration reference
- SECURITY_OPS.md - Security operations guide
- CLOUD_DEPLOYMENT.md - Production deployment with secrets management