API Keys
Richfolio uses up to 5 external services, all with generous free tiers. Only Resend and a recipient email are required — everything else is optional.
Add each key as a repository Secret: Settings → Secrets and variables → Actions → Secrets tab. Add RECIPIENT_EMAIL as a Variable instead (easier to view/edit).

Resend (Email) — Required
Resend delivers the HTML email reports.
- Go to resend.com and sign up
- Navigate to API Keys in the dashboard
- Click Create API Key, give it a name, and copy the key
- Add as a GitHub Secret — name:
RESEND_API_KEY, value: the key you just copied
Free tier: 3,000 emails/month. Sends from onboarding@resend.dev by default. Can only send to your account owner email unless you verify a custom domain (Dashboard → Domains → Add Domain → add DNS records).
Recipient Email — Required
Add as a GitHub Variable (not Secret): name: RECIPIENT_EMAIL, value: your email address.
Must match your Resend account email unless you’ve verified a custom domain.
NewsAPI (Headlines) — Optional
Provides top headlines per ticker for the daily brief.
- Go to newsapi.org and sign up
- Your API key is shown on the dashboard immediately
- Add as a GitHub Secret — name:
NEWS_API_KEY, value: the key from the dashboard
Free tier: 100 requests/day. Richfolio uses ~4 requests per run via batching. Headlines from the last 24 hours only. If not set, the brief runs without news.
Google Gemini (AI Analysis) — Optional
Powers the AI buy recommendations with Gemini 2.5 Flash.
- Go to aistudio.google.com/apikey
- Click Create API Key, select a Google Cloud project (or create one)
- Copy the key and add as a GitHub Secret — name:
GEMINI_API_KEY, value: the key you just copied
Free tier: 250 requests/day, 10 requests/minute. Richfolio uses 1 request per run (plus 1 per STRONG BUY ticker for detailed analysis). New keys may take a few minutes for quota to activate (you might see 429 errors initially). If not set or quota exhausted, falls back to gap-based recommendations.
A note on Gemini model tiers
Google’s pricing page states that Gemini 2.5 Pro is “Free of charge” for both input and output tokens. In practice, however, free-tier Pro requests frequently hit 429 RESOURCE_EXHAUSTED errors — even with minimal usage. Google does not publish the actual RPD (requests per day) limits for the free tier; third-party sources suggest Pro may be capped at ~100 RPD, but the real number appears to vary by account and is not guaranteed.
Richfolio uses Gemini 2.5 Flash for all AI calls (both main analysis and detailed STRONG BUY analysis) because Flash has a more generous and reliable free-tier quota. The quality difference for financial analysis text is negligible.
Using a different AI model
If you have a paid Gemini plan or want to use a different provider entirely, the model is easy to swap. The AI calls live in two files:
src/aiAnalysis.ts— main buy recommendations (line ~225)src/detailedAnalysis.ts— detailed STRONG BUY analysis (line ~119)
To switch to Gemini Pro (if you have paid quota):
// In both files, change:
model: "gemini-2.5-flash",
// To:
model: "gemini-2.5-pro",
To switch to Claude or another provider, you would replace the @google/genai calls with your provider’s SDK. For example, with the Anthropic SDK:
// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // uses ANTHROPIC_API_KEY env var
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
});
The prompt and JSON parsing logic stay the same — only the API call changes. Add your provider’s API key as a GitHub Secret.
Telegram Bot — Optional
Delivers condensed summaries to your Telegram account.
Create the bot
- Open Telegram and search for @BotFather
- Send
/newbot - Choose a name (e.g., “Richfolio Brief”) and username (must end in
bot, e.g.,richfolio_brief_bot) - BotFather replies with your bot token — copy it
Get your chat ID
- Search for @userinfobot on Telegram and start it
- It replies with your numeric user ID — this is your chat ID
Important: Send any message to your new bot (e.g., “hi”) before running Richfolio — this is required before the bot can message you.
Add both as GitHub Secrets:
- Name:
TELEGRAM_BOT_TOKEN, value: the token from BotFather - Name:
TELEGRAM_CHAT_ID, value: your numeric user ID
Notes: If not set, the brief skips Telegram. Messages are condensed summaries (not full HTML). 4,096 character limit per message — news is truncated if needed.
Summary
| Key | Required | Service |
|---|---|---|
RESEND_API_KEY | Yes | Email delivery |
RECIPIENT_EMAIL | Yes | Your email address |
NEWS_API_KEY | No | News headlines |
GEMINI_API_KEY | No | AI buy recommendations |
TELEGRAM_BOT_TOKEN | No | Telegram delivery |
TELEGRAM_CHAT_ID | No | Telegram delivery |