How to Build a Claude-Powered News Digest App
A Claude-powered news digest app pulls content from RSS feeds, APIs, or scrapers, then uses Claude to summarize, rank, and group that content into a short, readable digest — delivered by email, Slack, or a web page on a schedule. The core loop is: fetch → summarize → structure → deliver, repeated daily or hourly.
This guide walks through each piece of that loop with working code, so you can go from "a pile of articles" to a digest a user actually wants to read, without building a custom NLP pipeline from scratch.
What a Claude-powered news digest app actually does
Most teams overcomplicate this. You don't need a custom summarization model or a vector database to launch a useful digest product. You need four things:
- A source list — RSS feeds, a news API, or scraped pages
- A deduplication/filter step — so the same story from five outlets doesn't appear five times
- A summarization step — Claude reads the raw content and produces a clean, consistent summary
- A delivery mechanism — email, Slack webhook, static page, or in-app feed
Claude is the piece that turns "20,000 words of scraped articles" into "6 bullet points a human will actually read." Everything else is plumbing.
Step 1: Collect source content
Start simple. RSS is still the most reliable way to get structured article data without scraping headaches. For each source, pull the latest items, strip HTML, and truncate to a reasonable length (2,000–4,000 characters per article is usually enough for a good summary).
import Parser from "rss-parser";
const parser = new Parser();
async function fetchArticles(feedUrls) {
const articles = [];
for (const url of feedUrls) {
const feed = await parser.parseURL(url);
for (const item of feed.items.slice(0, 10)) {
articles.push({
title: item.title,
link: item.link,
published: item.pubDate,
content: (item.contentSnippet || item.content || "").slice(0, 3000),
});
}
}
return articles;
}
Run deduplication before summarization — a cheap string-similarity check on titles (or even a simple Jaccard similarity on normalized words) removes most duplicate coverage of the same story.
Step 2: Summarize and rank with Claude
This is where the digest gets its value. Instead of calling Claude once per article (slow, expensive, and inconsistent formatting), batch a group of articles into a single prompt and ask for a structured summary with ranking.
const prompt = `You are generating a daily news digest. Below are ${articles.length} articles.
For each one, write a 1-2 sentence summary. Then pick the top 5 stories by importance
and explain why in one line. Return JSON only, no commentary.
Articles:
${articles.map((a, i) => `[${i}] ${a.title}\n${a.content}`).join("\n\n")}
`;
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4",
max_tokens: 1500,
messages: [{ role: "user", content: prompt }],
}),
});
const data = await response.json();
A few things that matter here:
- Ask for JSON explicitly and validate it before storing — Claude is reliable at this but you still want a parser that fails loudly instead of shipping garbled output
- Cap the batch size — if you're feeding 50+ articles, split into two calls rather than one huge prompt; it keeps summaries consistent in tone and length
- Include publication date and source name in the prompt so Claude can flag stale or duplicate coverage
If your digest covers multiple topics (tech, finance, local news), run a separate summarization pass per topic. It's easier to tune prompt instructions per category than to ask one prompt to handle everything well.
Step 3: Structure the digest output
Once you have Claude's JSON response, map it into your digest schema. A minimal schema that works for email and web rendering:
{
"date": "2024-05-14",
"topics": [
{
"name": "Technology",
"top_story": "...",
"items": [
{ "title": "...", "summary": "...", "link": "..." }
]
}
]
}
Keep the schema stable even if your prompt changes — your email template or front-end shouldn't need to know about Claude's internals.
Step 4: Schedule and deliver
A cron job (or a scheduled serverless function) triggers the fetch → summarize → deliver pipeline once or twice a day. For email delivery, render the structured digest into an HTML template and send via your mail provider. For Slack, post a formatted message using blocks. For a web app, just store the JSON and render it client-side.
// pseudocode for the daily job
const articles = await fetchArticles(FEED_URLS);
const deduped = dedupe(articles);
const digest = await summarizeWithClaude(deduped);
await sendDigestEmail(subscribers, digest);
Handling API access and scaling
Once you move past a prototype, two things start to matter: reliable streaming for longer digests and clean usage visibility per customer if you're running this as a multi-tenant product.
SubToAPI turns your existing Claude access into an HTTPS API with application keys (sub_live_...), so each environment or customer can have its own key instead of sharing one credential across your whole backend. That's useful for a digest app with multiple tenants — you can track usage per key and know exactly which customer's digest generation is consuming tokens.
For digests with many topics, streaming the response (see /docs/streaming) lets you start rendering the first topic while Claude is still generating the rest, which matters if you're building a live preview in your admin dashboard. The /docs/messages reference covers the request shape used above, and /docs/quickstart walks through getting a key and making your first call. If you later want the digest generator to call out to a search or fetch tool directly instead of pre-fetching articles yourself, /docs/tools covers tool use.
Pricing is straightforward if you're shipping this as a product: Solo at €9 for a single project, Team at €19/seat once collaborators need their own keys, and Scale at €49/seat for larger usage and teams. Check /pricing for the current breakdown, or start with a free trial at /signup.
Cost and rate limit considerations
Summarizing 50 articles a day across multiple topics adds up in tokens fast. A few practical levers:
- Truncate article bodies before sending them to Claude — you rarely need the full text for a good summary
- Cache summaries for articles that haven't changed since the last run
- Batch articles into fewer, larger prompts rather than many small ones — this reduces per-request overhead
- Run cheaper models for first-pass filtering (e.g., deciding which articles are worth a full summary) and reserve the stronger model for final digest writing
questions
Do I need a vector database to build a Claude-powered news digest app? No. For most digest products, RSS feeds plus a deduplication step and a well-structured prompt are enough. Vector search becomes useful later if you add semantic search across historical digests, but it's not required to ship.
How often should the digest regenerate? Daily is standard for most news digests, but breaking-news or finance-focused products often run hourly. Match the cadence to how time-sensitive your content category is, and cache aggressively between runs to control costs.
Can I let users customize their digest topics? Yes — store a per-user topic/source list, filter articles against it before the summarization step, and run one Claude call per unique topic combination rather than per user to avoid duplicate work.