Content
Ship a daily AI news digest your team actually reads
Get a sourced roundup, add what practitioners are posting on X, pull one video transcript, then compose the issue in Markdown and archive it in a LiveDoc.
Copy the prompt
Replace the bracketed fields, then paste it into Claude Code, Codex, or any AI with terminal access. It installs the Felo skill, asks before spending credits, and runs the workflow.
Build a daily industry brief for [industry or topic]. Time window: last 24 hours, timezone [timezone]. Audience: [readers]. Watchlist (optional): X [accounts or topics], YouTube [channels], Reddit [communities]. Pick the 5-8 items that matter. For each: what happened, why it matters, the source link, and whether it is an announcement, a result, or an opinion. Sections: 1. Top story. 2. 5-8 items with a source link each. 3. What people are saying on X, with handles and dates. 4. One video quote with a timestamp. 5. What to watch next. Rules: - Link every item. Group duplicate coverage and keep the best source. - Separate announcements from independent results; label vendor claims. - Report only metrics the source returns. Missing data is "Not available", never zero. - If nothing significant happened, say so instead of padding the issue. - Before spending credits, show the API calls you plan to make and wait for my approval. - Do not schedule, publish, or send anything. - Write the result to ./daily-brief.md and summarize it in chat.
The copy also includes the install steps and safety rules.
What you get
Example output from a run. Not a live generation.
AI industry brief — 2026-10-30
Top story
A major lab published a smaller model with tool use at the same benchmark score as its flagship. Vendor claim; independent results are still pending.
Items
- Small model, same benchmark — vendor benchmark, not yet replicated. [source]
- Agent framework release — new tracing and retry controls. [source]
What people are saying
@example_dev: "The win is latency, not the score." — 2026-10-30 08:12 JST
One video quote
"We stopped measuring tokens and started measuring resolved tickets." — [12:40]
What to watch next
Independent evals for tool use, and whether the price holds after launch week.
The exact calls
For developers: the same workflow as copy-paste code, in the order it runs.
Show the exact API calls
Get the sourced roundup
Chat searches the web, ranks the results, writes the answer, and returns the resources it used. Ask for a narrow window so the digest is about the last day, not the last year, and keep the top resources for citations. The helper below sends the key once and throws on a non-2xx response.
digest.ts const BASE = "https://openapi.felo.ai"; const headers = { Authorization: `Bearer ${process.env.FELO_API_KEY}`, "Content-Type": "application/json", }; async function felo<T>(path: string, body?: unknown): Promise<T> { const res = await fetch(`${BASE}${path}`, { method: body ? "POST" : "GET", headers, body: body ? JSON.stringify(body) : undefined, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); return res.json() as Promise<T>; } type ChatData = { data: { answer: string; resources: { link: string; title: string; snippet: string }[]; }; }; const roundup = await felo<ChatData>("/v2/chat", { query: "Biggest AI news stories in the last 24 hours", }); const sources = roundup.data.resources.slice(0, 5);Example output
{ "answer": "The main stories today are …", "sources": [ { "link": "https://example.com/story", "title": "…", "snippet": "…" } ] }Add what practitioners are posting
Press coverage repeats the announcement; X shows whether anyone can get it to work. Search the same 24-hour window, then filter on engagement so three useful posts survive instead of twenty replies. Keep the handle and timestamp — they are part of the citation.
digest.ts type XData = { data: { tweets: { content: string; author: { username: string }; created_at: string; metrics: { retweet_count: number; favorite_count: number }; }[]; next_cursor: string | null; has_next: boolean; }; }; const since = Math.floor((Date.now() - 24 * 60 * 60 * 1000) / 1000); const social = await felo<XData>("/v2/x/tweet/search", { query: "AI agents", limit: 20, since_time: since, }); const posts = social.data.tweets .filter((tweet) => tweet.metrics.favorite_count >= 50) .slice(0, 3);Example output
{ "data": { "tweets": [ { "content": "…", "author": { "username": "…" }, "created_at": "2026-10-29T02:14:00Z", "metrics": { "retweet_count": 12, "favorite_count": 180 } } ] } }Pull one video transcript
A single talk or demo is often the most substantive item of the day. Fetch its subtitles with timestamps, then flatten them into one paragraph — the digest only needs a short excerpt, and
with_time=truegives you timestamps to jump back to.digest.ts type SubtitleData = { data: { title: string; contents: { text: string; start: number; duration: number }[]; }; }; const videoCode = "dQw4w9WgXcQ"; // replace with today's video id const video = await felo<SubtitleData>( `/v2/youtube/subtitling?video_code=${videoCode}&language=en&with_time=true`, ); const transcript = video.data.contents.map((line) => line.text).join(" ");Example output
{ "title": "Example Video Title", "contents": [ { "text": "Subtitle text", "start": 0.32, "duration": 14.26 } ] }Compose the issue in Markdown
This step is plain code, not an API call: assemble the roundup, the X posts, the transcript excerpt, and the source list into one Markdown string. Keep the sources at the bottom and a link beside every claim — a digest without citations is just another summary.
digest.ts const date = new Date().toISOString().slice(0, 10); const issue = [ `# AI digest — ${date}`, "", "## The roundup", roundup.data.answer, "", "## What practitioners are posting", ...posts.map((post) => `- @${post.author.username}: ${post.content}`), "", "## From the video", transcript.slice(0, 1200), "", "## Sources", ...sources.map((source) => `- [${source.title}](${source.link})`), ].join("\n"); console.log(issue);Archive the issue in a LiveDoc
Create one archive LiveDoc and add each issue as a document resource, so the file stays in your repo while the searchable copy lives in the platform. Later questions — "when did we last cover this?" — run semantic retrieval over every issue instead of opening dated files.
digest.ts type LiveDocData = { data: { short_id: string } }; const archive = await felo<LiveDocData>("/v2/livedocs", { name: "AI digest archive", description: "One document resource per daily issue", }); await felo(`/v2/livedocs/${archive.data.short_id}/resources/doc`, { title: `AI digest — ${date}`, content: issue, }); type Retrieved = { data: { title: string; content: string; score: number }[] }; const past = await felo<Retrieved>( `/v2/livedocs/${archive.data.short_id}/resources/retrieve`, { query: "what did we say about agent frameworks last month" }, ).then((res) => res.data.filter((hit) => hit.score >= 0.7));Example output
[ { "title": "AI digest — 2026-10-01", "content": "…", "score": 0.88 } ]
What's included
- A sourced roundup with dated links
- Practitioner posts from X with handles
- One YouTube transcript excerpt with a timestamp
- The issue archived in a LiveDoc so past issues are searchable
What it doesn't do
- No paywalled news or private Slack/Discord sources
- X coverage is incomplete; it is a signal, not a survey
- One video per issue, and only when subtitles are available
- It does not schedule or publish the issue; that is your agent's job
- No invented engagement numbers or quotes
Questions
Can I use it for an industry other than AI?
Yes. Replace the industry, timezone, watchlist, and audience placeholders. The same prompt works for any beat with public coverage.
Can it run every day?
The prompt runs once. To publish daily, set the schedule in an agent or cron job that executes the same workflow and archives each issue.
Does it read every video on my watchlist?
No. It picks one video and uses its transcript when subtitles exist. A title or description is never treated as proof of the content.
How much does an issue cost?
Each search, extraction, and transcript spends usage-based credits; current rates are on the pricing page. The prompt asks for approval before spending.
Will it miss stories?
Possibly. Coverage depends on what the sources return, and the issue states its gaps instead of pretending to be complete.
How do I avoid repeating yesterday's news?
Run it against the same LiveDoc archive and ask it to compare the previous issue before selecting today's items.
Related workflows
Turn one question into a sourced research brief
Ask the web, pull the pages behind the answer as Markdown, add what X is saying, then keep the evidence in a LiveDoc you can query again later.
Open workflowContentTurn a YouTube video into a publishable article
Pull the timestamped transcript, shape it into readable blocks, outline and draft with a model you control, then leave the result in a LiveDoc for review.
Open workflowOfficeTurn a research page into a slide deck
Extract the page, file it as LiveDoc context, then let the PPT Task API build the deck while you poll for the finished link.
Open workflowMake it yours
The same recipe, adapted to the way you actually ship.
Run it before the team wakes up
Wrap the steps in a function and call it from cron once a day. Write each issue to a dated file in your repo, but create the archive LiveDoc only once and reuse its `short_id` — otherwise every run starts a new, empty archive.
Change the beat
The same five steps work for any niche: swap the Chat query and the X query for your vertical, and keep the transcript only when the day's video is actually on topic. A narrow beat is what makes a digest worth subscribing to.
Publish where the team already reads
Send `issue` to Slack, email, or your CMS and treat the LiveDoc as the source of truth. The composed Markdown is plain text, so every destination takes it without conversion.
Keep going
The reference pages behind this recipe, and where to go next.