Case study · Side project
A content pipeline I built for @productbykel. It turns the day’s AI news into Instagram reels and carousels, learns from how each post performs, and publishes nothing until I approve it.
The problem
Posting AI news by hand doesn’t scale
I wanted @productbykel to cover AI news on a steady cadence for PMs and builders. Doing it by hand meant reading feeds, picking stories, writing copy, designing slides, recording voiceover and cutting video for every single post. The cadence fell apart whenever my day job got busy.
Full automation wasn’t the answer either. An account that posts a wrong fact about a model launch loses trust fast. I wanted the machine to do the legwork and keep me as the editor.
How it’s built
AI News Engine: from headline to published post
Claude does the research and drafting. Two human checkpoints decide what ships, and post performance feeds the next run.
- AI step
- Human checkpoint
- Code
- Service
- IngestCode
Every other morning a cron job pulls AI news and ranks stories by source coverage, PM relevance and freshness.
- Vercel cron
- NewsAPI
- TLDR AI
- Pick the storiesAI step
A Claude agent reads the full articles, picks a lead story, suggests carousel stories and recommends a format.
- Claude Sonnet 4.6
- Performance signals
- Editor's cutHuman checkpoint
I choose the final three carousel stories. Claude pre-selects them and I can override any pick.
- Dashboard
- Write the copyAI step
Slide copy, the reel script and image prompts come back as structured JSON through forced tool calls.
- Claude Sonnet 4.6
- Forced tool use
- Humanizer rules
- Produce the mediaService
Images, voiceover and video are generated, then rendered as a vertical reel and five square slides.
- Flux 1.1 Pro
- ElevenLabs
- Remotion Lambda
- ReviewHuman checkpoint
I preview the voiceover, reel and slides. Nothing publishes without my approval.
- Dashboard
- Publish and learnCode
Approved posts go out on a schedule. A daily job pulls views and likes back so the next run knows what lands.
- YouTube
- App
- Next.js on Vercel, password-gated
- Data
- Supabase Postgres and Storage
- AI
- Claude Sonnet 4.6 with forced tool use
- Media
- fal.ai Flux 1.1 Pro, ElevenLabs, Remotion Lambda on AWS
- Channels
- Instagram Graph API, YouTube Data API, LinkedIn API
Version two
Closing the loop
The first version made content. The second one learns from it. A daily job pulls views, likes and comments from Instagram and YouTube and matches each post back to the episode that produced it. From there the engine works out which formats and topics land, and passes those findings to Claude as performance signals the next time it picks stories. When the sample is too small to trust, it stays quiet instead of guessing.
I also added a news hub. It ranks stories by how many sources are covering them, how relevant they are to PMs and how fresh they are, and it merges near-duplicate headlines. Every story offers three paths: an automated carousel, an automated reel, or a filming brief with a hook, talking points and a call to action so I can shoot the reel myself.
Product decisions
The calls I made and why
Approval before publish
Claude drafts, I decide. Two gates keep a wrong story or a bad render off my accounts.
Remotion over a video API
I picked Remotion over Creatomate to own the templates and the render pipeline instead of renting them.
Swappable image model
All image generation lives in one route, so trying a new model is a one-file change.
One source of truth for voice
A shared set of humanizer rules goes into every prompt so captions sound like me, not like a model.
What broke
Running it in production
Timeouts
Long Claude calls hit Vercel’s function limits. I raised the limits on the heavy routes and collapsed a multi-step agent loop into a single pass.
A token that expired quietly
Instagram tokens last 60 days, and the sync failed silently for weeks once mine ran out. The engine now refreshes its own token every week.
Disappearing thumbnails
Instagram image links are signed and expire within days. Thumbnails now get copied to Supabase Storage once and served from there.
Open endpoints
The production URL sat outside Vercel’s protection, so anyone could have triggered a render or a post. Every page and API route now requires a login, and the cron jobs use their own secret.
Stack
- Next.js
- Vercel cron
- Supabase
- Claude Sonnet
- Forced tool use
- Flux 1.1 Pro
- ElevenLabs
- Remotion Lambda
- Instagram Graph API
- YouTube Data API
- LinkedIn API
The dashboard itself is private because it can publish to my accounts.
