<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jayanth</title>
    <description>The latest articles on DEV Community by Jayanth (@grewup).</description>
    <link>https://dev.to/grewup</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3861039%2Fed96fe23-36a0-4d4e-a489-d65e99f6470f.jpeg</url>
      <title>DEV Community: Jayanth</title>
      <link>https://dev.to/grewup</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grewup"/>
    <language>en</language>
    <item>
      <title>I Gave Mistral Remote Agents a Real Coding Task, Closed My Laptop, and Came Back to a Finished App</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Fri, 08 May 2026 11:30:24 +0000</pubDate>
      <link>https://dev.to/grewup/i-gave-mistral-remote-agents-a-real-coding-task-closed-my-laptop-and-came-back-to-a-finished-app-1fg</link>
      <guid>https://dev.to/grewup/i-gave-mistral-remote-agents-a-real-coding-task-closed-my-laptop-and-came-back-to-a-finished-app-1fg</guid>
      <description>&lt;p&gt;&lt;strong&gt;The task I used to test this&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I did not want to test something new. &lt;br&gt;
No hello-world prompt.&lt;br&gt;
No "generate a function" demo.&lt;br&gt;
I gave it a task I would normally spend 30–45 minutes on myself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"Build a complete sales dashboard application and prepare it for deployment."`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a task that typically requires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Prompt → Review output → Fix errors → Re-prompt → Adjust → Fix again → Finalise`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You stay in the loop the entire time. That is the normal pattern with Claude, GPT or any standard AI coding assistant. The model responds step-by-step. You guide every step.&lt;br&gt;
I hit enter.&lt;br&gt;
Watched it start. &lt;br&gt;
Then I closed my laptop and did not check back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I expected vs what I found&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I came back, I expected one of three outcomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;
&lt;span class="sb"&gt;``
&amp;gt; 1. Half-finished output with obvious gaps
&amp;gt; 2. Broken code requiring significant fixes
&amp;gt; 3. A "draft" response asking clarifying questions`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;What I found instead:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;plaintext&lt;br&gt;
&lt;/code&gt;✓ Application structure fully built&lt;br&gt;
✓ UI components organised and functional&lt;br&gt;
✓ Core logic implemented&lt;br&gt;
✓ Deployment-ready configuration included&lt;code&gt;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I had not guided it through a single step. I had not fixed anything midway. I had not even stayed in the session.&lt;br&gt;
That is the distinction that matters. Not better output — different category of behaviour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Mistral Remote Agents actually does (architecture breakdown)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remote execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standard AI coding assistants are tied to your active session. When you close the tab, execution stops. The model waits for your next message.&lt;br&gt;
Mistral Remote Agents changes this model:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standard assistant:
You (active) → Prompt → Model responds → You review → Re-prompt → Repeat

Remote agent:
You define task → Agent executes in cloud → You return to results`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The task moves to cloud execution. It continues independently. Your presence is not required for execution to complete.&lt;/p&gt;

&lt;p&gt;Work mode — tasks not responses&lt;/p&gt;

&lt;p&gt;Inside Mistral's interface, Work Mode treats your input as a workflow objective rather than a prompt requiring a single response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Traditional model:       "Here is your answer"
Work mode:               "Here is the completed outcome"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model plans internal steps, executes them in sequence, and delivers a finished state rather than a sequence of responses you have to assemble.&lt;br&gt;
Tool integration&lt;/p&gt;

&lt;p&gt;The system connects to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`GitHub        — code repository management
Project tools — task and workflow tracking
Internal APIs — custom integrations`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the agent is not just generating text that looks like code. It can structure files, prepare deployment configurations, and organise output for real-world use rather than copy-paste from a chat window.&lt;/p&gt;

&lt;p&gt;Single model for reasoning + coding + execution planning&lt;br&gt;
There is no switching between tools or models for different parts of the task. Reasoning, code generation, and execution planning happen in one flow. No fragmentation, no context loss between tool handoffs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow model shift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the part most coverage gets wrong by treating it as a feature comparison.&lt;br&gt;
Before — how we currently use AI for coding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# The standard loop
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;task_not_complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What to do next?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fix_errors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decide_next_step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user is the execution layer. The model is the generation layer. You manage every transition.&lt;br&gt;
After — what agent-based execution enables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# The agent model
&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;define_objective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Build sales dashboard, deploy-ready&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# ... you do other work ...
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;adjust_if_needed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent manages the transitions. You define the start and review the end. Everything in between is the agent's responsibility.&lt;/p&gt;

&lt;p&gt;This is not a performance improvement. It is a workflow architecture change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I changed after the first test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the initial result, I ran more tasks and noticed what determines output quality.&lt;/p&gt;

&lt;p&gt;Task definition clarity matters more than task complexity&lt;br&gt;
Vague objectives produce vague results regardless of model capability. The agent cannot fill gaps in your intent the way you can through iterative prompting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Weak:   "Build something useful for tracking sales"

Strong: "Build a sales dashboard with:
         - Monthly revenue chart (bar chart)
         - Top 5 products by volume (table)
         - Conversion rate by source (pie chart)
         - CSV export button
         - Deployment configuration for Vercel"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second input removes ambiguity the agent would otherwise resolve with assumptions.&lt;br&gt;
Structured inputs replace iterative correction&lt;br&gt;
In the standard model, vague prompts are cheap because you correct through follow-up messages. In the agent model, vague prompts cost you more because the agent completes a full execution cycle before you can course-correct.&lt;/p&gt;

&lt;p&gt;Front-load the specificity. The investment in a detailed task definition pays back in output that needs minimal revision.&lt;br&gt;
Reviewing replaces prompting&lt;br&gt;
The interaction pattern changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Standard AI:    Prompt → Review → Prompt → Review → Prompt
Remote agent:   Define → [agent executes] → Review → Adjust → Finalise`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill set that produces good results shifts from "prompt engineering" to "task specification" and "output evaluation."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest limitations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not a replacement for every coding workflow.&lt;br&gt;
Tasks that require ongoing creative decision-making — where the direction changes based on intermediate results — still benefit from the interactive model. The agent cannot detect that you have changed your mind mid-execution.&lt;/p&gt;

&lt;p&gt;Output quality on complex tasks is high as a starting point, not necessarily as a final product. Some outputs need tweaking. The meaningful difference is where you start: from zero versus from 80% complete.&lt;/p&gt;

&lt;p&gt;Integration setup with GitHub and project tools requires configuration time upfront. The first session involves more overhead than a standard AI chat. The payoff is subsequent sessions where the context and tooling are already in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The practical implication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The distinction between "AI assistant" and "AI agent" is not semantic. It maps to a real difference in how your time is allocated:&lt;/p&gt;

&lt;p&gt;Assistant model:  your time → mostly spent in the prompt-fix loop&lt;br&gt;
Agent model:      your time → task definition + final review&lt;/p&gt;

&lt;p&gt;For developers and builders running multiple projects simultaneously, the compounding effect is significant. Tasks that required active attention can run in the background. Your focus time goes to the parts that genuinely require it.&lt;/p&gt;

&lt;p&gt;This is early. The integrations are not seamless and task failures do happen. But the architecture is categorically different from what most developers are using daily, and the gap between the two models is going to widen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full breakdown in the original &lt;a href="https://medium.com/ai-in-plain-english/i-tried-mistral-remote-agents-on-a-real-coding-task-it-finished-everything-without-me-this-is-bb73ee09c380" rel="noopener noreferrer"&gt;Medium article.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you tested agent-based coding tools on real production tasks? Drop what held up and what broke in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>agents</category>
    </item>
    <item>
      <title>Claude + Canva Integration — I Built an Instagram Carousel in 5 Minutes (Full Workflow)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Thu, 07 May 2026 15:41:42 +0000</pubDate>
      <link>https://dev.to/grewup/claude-canva-integration-i-built-an-instagram-carousel-in-5-minutes-full-workflow-4g2j</link>
      <guid>https://dev.to/grewup/claude-canva-integration-i-built-an-instagram-carousel-in-5-minutes-full-workflow-4g2j</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this actually is (and what people get wrong)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most people see "Claude Canva integration" and assume it is AI generating images or suggesting layouts. That is not what it does.&lt;br&gt;
What it does: Claude structures an entire design — slide layouts, content, hierarchy — and exports it directly into Canva as a fully editable project. You do not receive a static image. You receive a Canva file you can open and modify exactly like any template you would start from scratch.&lt;/p&gt;

&lt;p&gt;The practical difference: instead of opening Canva, choosing a template, adjusting the layout, and writing the content — you describe what you want, Claude builds the 80% version, and you spend your time on the 20% that requires your specific branding and voice.&lt;br&gt;
Here is the exact workflow that replaced my manual design process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Claude account (any paid plan)
Canva account (free tier works)
The Canva connector enabled inside Claude`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Enable the Canva connector&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This step is non-negotiable. Without it, Claude cannot export anything into Canva.&lt;br&gt;
Inside Claude:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Dashboard → Customize → Skills → Connectors → Find Canva → Connect account`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OAuth flow — takes about 60 seconds. Once connected, the connector persists across sessions. You only do this once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Access Claude Design mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After connecting Canva, return to your Claude dashboard. You will see a new option: Claude Design.&lt;br&gt;
This is separate from the standard chat interface. You are not prompting for text. You are prompting for a designed output. The distinction matters for how you write your prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Create a new design project and set your type&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside Claude Design, create a new project. Define the design type clearly.&lt;br&gt;
Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Instagram Carousel
LinkedIn Post
Presentation Deck
Email Header
Story Slide`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Claude the dimensions, layout constraints, and output format before anything is generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Select High Fidelity mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two options are available: Low Fidelity and High Fidelity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Low Fidelity  = rough structural draft, loose layout
High Fidelity = clean usable design, structured output`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always use High Fidelity for anything that will be exported. Low Fidelity is useful for quickly checking whether a concept layout works before committing to a full generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Upload visual references (optional but high-impact)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude accepts uploaded screenshots, mood boards, or existing designs as visual references. This is where most people underestimate the system.&lt;br&gt;
Instead of describing your desired style in text — which is inherently imprecise — show it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Upload 2–3 carousel examples whose style matches your target
Claude reads the visual patterns: spacing, typography weight, color approach
Output accuracy improves significantly compared to text-only prompts
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have a brand style guide or competitor carousel that represents the aesthetic you want, upload it here. The generated output will reflect those visual patterns rather than Claude's defaults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 — Write a specific prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The quality of the generated design scales directly with the specificity of the prompt. This is where most people leave performance on the table.&lt;br&gt;
Weak prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;"Create a carousel about AI tools"&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Strong prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;"Create a 5-slide Instagram carousel with:
- Bold headline on each slide (max 6 words)
- Supporting text under each headline (max 20 words)
- Minimal white background design
- Topic: 5 AI tools that save 10 hours per week
- Slide 1: Hook/problem statement
- Slides 2–5: One tool per slide with one key benefit
- Final slide: CTA to follow for more"&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second prompt tells Claude the slide count, content structure, visual style, topic, and the purpose of each slide. Claude does not need to make assumptions when the brief is this specific. Fewer assumptions mean fewer iterations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7 — Let Claude ask clarifying questions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After submitting your prompt, Claude does not immediately generate. It asks questions to resolve remaining ambiguity: content depth per slide, colour preferences, font style direction, any specific wording you want preserved.&lt;br&gt;
Most people find this step slightly frustrating and try to skip past it. This is a mistake. The questions surface assumptions that would otherwise produce a design you need to revise significantly. Answering them thoroughly gets you closer to a first draft that requires minimal editing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8 — Review the generated output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generation typically takes 2–4 minutes depending on slide count and complexity.&lt;br&gt;
The output preview shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Layout structure per slide
Content placement and hierarchy
Typography choices
Spacing and visual balance`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, you are not looking for perfection. You are evaluating whether the structure is correct and whether the content is in the right places. Colour, fonts, and exact wording are all editable in Canva — do not try to perfect those through additional Claude prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9 — Export to Canva&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you are satisfied with the structure, click Export to Canva.&lt;br&gt;
The design transfers to your Canva account and opens as a new project. Every element — text boxes, layout blocks, colour fills — is independently editable. This is not a flattened image. It is a layered Canva file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10 — Finalise in Canva&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standard Canva workflow from here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Replace placeholder fonts with your brand fonts
Apply your brand colour palette
Replace any generic text with your specific copy
Add your logo or profile photo where relevant
Adjust any spacing that looks off on mobile preview
Download or publish directly`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total time from prompt to export for a 5-slide carousel: approximately 8–12 minutes including the clarifying questions. Total Canva editing time for brand alignment: approximately 5–10 minutes depending on how many brand elements you are adding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the workflow shift actually means&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The old process for a carousel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Idea → Open Canva → Choose template → Not quite right → Choose another → 
Adjust layout → Write content → Realise layout doesn't fit content → 
Adjust again → Add branding → Publish`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Idea → Describe it → Claude generates structure → Export → Add branding → Publish`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The removal of the "starting from scratch" step is the meaningful change. Not because Claude's output is perfect, but because an 80% starting point with correct structure eliminates the most time-consuming part of the process — the blank canvas decision loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations worth knowing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude's colour defaults are generic. Always plan to replace the colour palette in Canva with your brand colours — do not try to specify exact hex values in the prompt, the results are inconsistent.&lt;br&gt;
Font selection is limited to what Claude defaults to. Canva's font library covers the final step.&lt;/p&gt;

&lt;p&gt;For highly complex layouts — asymmetric grids, layered image compositions — the output sometimes needs significant restructuring. Claude handles standard grid-based carousel layouts well. Experimental layouts less so.&lt;br&gt;
For standard content formats (carousels, listicle slides, educational posts), the workflow saves meaningful time. For highly custom branded content that diverges significantly from standard layouts, expect to spend more time in Canva editing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full workflow breakdown with screenshots in the original &lt;a href="https://medium.com/@jayanth01/claude-canva-integration-i-built-a-full-instagram-carousel-in-5-minutes-step-by-step-guide-ce0153572da9" rel="noopener noreferrer"&gt;medium&lt;/a&gt; post.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using this for a niche where carousels perform differently to average? Drop your use case in the comments — interested in how the workflow holds up across different content types.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>productivity</category>
      <category>socialmedia</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Kept Hitting Claude Token Limits Until I Tracked What Was Actually Burning Them</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Wed, 06 May 2026 13:55:06 +0000</pubDate>
      <link>https://dev.to/grewup/i-kept-hitting-claude-token-limits-until-i-tracked-what-was-actually-burning-them-mg1</link>
      <guid>https://dev.to/grewup/i-kept-hitting-claude-token-limits-until-i-tracked-what-was-actually-burning-them-mg1</guid>
      <description>&lt;p&gt;&lt;strong&gt;The pattern that made no sense&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some days I barely used Claude and hit the limit early. Other days I pushed it hard and lasted much longer.&lt;br&gt;
If the platform was the problem, the behaviour should be consistent. It was not — which meant the variable was me, not the system.&lt;br&gt;
I started tracking everything: how I was prompting, how long my sessions ran, what types of tasks I was running, what differed between good days and bad days. The pattern that emerged was clear once I could see it.&lt;br&gt;
I was not running out of messages. I was burning tokens — silently, in ways that felt completely normal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why token limits feel invisible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most developers think of API cost in terms of individual requests. The problem with Claude (and any context-window model) is that cost is not per-request in any intuitive sense. It is per-token-processed, and that includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Every message you send now
+
Your entire conversation history
+
Any files currently in context
+
Any active tools or integrations
+
All previous responses in the thread`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So every single message you send causes Claude to reprocess the entire accumulated weight of the conversation. A short chat is cheap. A long chat becomes exponentially expensive — not linearly.&lt;br&gt;
This is why the limit can feel random. It is not random at all. It is the silent compounding of context weight across every turn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 10 changes that fixed it&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edit the original prompt instead of stacking follow-ups&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This was the highest-impact change I made.&lt;br&gt;
What I was doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Message 1: "Write me an intro for this post"
Message 2: "Make it shorter"
Message 3: "Add more energy to the opening line"
Message 4: "Actually, change the angle entirely"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of those follow-ups looks like a small correction. What it actually is: a full context reload multiplied four times.&lt;br&gt;
What I changed to:&lt;br&gt;
Edit the original prompt directly instead of appending corrections. Claude processes one refined version with one context load instead of four cumulative loads.&lt;br&gt;
Immediate result: sharper outputs, fewer iterations, lower token burn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Reset sessions before context gets heavy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At message 5, Claude might process a few hundred tokens of history. At message 25, it could be processing tens of thousands — for every single new message, including simple questions.&lt;br&gt;
The pattern I use now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`After every 15–20 messages:
1. Ask Claude: "Summarise everything we have covered so far in this session."
2. Copy the summary.
3. Open a new chat.
4. Paste the summary as the opening context.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You keep continuity. You eliminate history weight. Same outcome at a fraction of the token cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Combine multi-step tasks into single execution prompts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Prompt 1: "Summarise this document"
Prompt 2: "Now extract the key points"
Prompt 3: "Rewrite the intro in under 100 words"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three context loads. Three rounds of history reprocessing.&lt;br&gt;
After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"Summarise this document, extract the key points as bullets, 
and rewrite the intro in under 100 words. Return all three 
in separate labelled sections."`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One context load. One processing cycle. Better output because Claude sees the full scope of what you need before it starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Stop re-uploading the same files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every time you upload a file, Claude reprocesses it from scratch — even if it is identical to one you uploaded two messages ago. This is a hidden cost that does not feel like a cost because the UX treats uploads casually.&lt;br&gt;
Fix: Use Projects to store reference files once. Files in a Project are cached in context rather than reprocessed per upload. For workflows that reference the same documentation, codebase, or data repeatedly, this alone produces significant savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Store persistent instructions once&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you start every session with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"I am a developer building automation workflows. 
Write in a concise technical tone. 
Use code blocks for all examples. 
Avoid unnecessary explanation."`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are burning those tokens every single session. Stored in a Project's system instructions or a reusable prompt template, they load once — and you stop paying for them repeatedly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Disable tools you are not actively using&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Active tools — web search, integrations, connected services — add processing overhead even when they are not being called in a given turn. The model still has to account for their presence in every response.&lt;br&gt;
Default posture: everything off. Enable specific tools only for sessions where they are required. Disable them when done. The per-turn cost reduction is small but it compounds across long sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Match model to task complexity&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task type&lt;/th&gt;
&lt;th&gt;Model tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple Q&amp;amp;A, lookup&lt;/td&gt;
&lt;td&gt;Lightest available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Writing, summarisation&lt;/td&gt;
&lt;td&gt;Mid-tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex reasoning&lt;/td&gt;
&lt;td&gt;Heavy model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code generation&lt;/td&gt;
&lt;td&gt;Depends on complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Using Claude's most powerful model for every task is the equivalent of running a GPU render for a text file. The lighter models handle most everyday tasks at lower token cost per output token. Reserve heavy models for tasks that genuinely need them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Write specific, scoped prompts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vague prompts produce long outputs. Long outputs consume output tokens. Output tokens cost more per unit than input tokens.&lt;br&gt;
Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"What do you think about this approach?"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"List the 3 main risks with this approach. 
Each risk in one sentence. No intro or conclusion."`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second prompt produces a shorter, more useful response — and costs less to generate. Specificity is free. Vagueness is expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Timing matters more than expected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Heavy usage periods produce tighter limits and slower responses regardless of your plan tier. If you are running intensive sessions — large context windows, complex reasoning tasks, multi-file workflows — scheduling them outside peak hours produces longer effective sessions and more consistent availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Track what you are actually burning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;None of these changes matter without visibility. Start logging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# Minimal usage tracking
&lt;/span&gt;&lt;span class="n"&gt;session_start_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_token_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initial_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;after_message_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_token_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;after_message_tokens&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;session_start_tokens&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This message cost: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Session total: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;after_message_tokens&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you can see the delta on each turn, the expensive patterns become obvious within a few sessions. The invisible becomes trackable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The four patterns that account for most waste&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After implementing all of the above, four root causes produce the majority of unnecessary token consumption:&lt;br&gt;
Long unmanaged conversations — context weight compounds exponentially. Reset and summarise before turn 20.&lt;br&gt;
Repeated file uploads — every upload is a full reprocess. Use Projects for persistent files.&lt;/p&gt;

&lt;p&gt;Active unused tools — overhead exists whether you call them or not. Disable by default.&lt;br&gt;
Heavy models on simple tasks — every output token from the heaviest model costs more than the same token from a lighter one. Match the tool to the job.&lt;br&gt;
Fix these four and the limit stops feeling like a restriction. It starts feeling like something you can comfortably stay inside with normal usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mental model that actually changes behaviour&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used to frame it as: Claude is limiting me.&lt;br&gt;
The accurate frame is: my workflow was consuming more than it needed to.&lt;br&gt;
Token limits are signals, not ceilings. They show you exactly how efficiently you are using the system. When you design prompts the way you would design efficient queries — send only what is needed, scope the output, reset before state compounds — the limit stops being a problem you bump into and starts being something you never think about.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full breakdown of these patterns with usage examples in the original &lt;a href="https://medium.com/@jayanth01/i-kept-hitting-claude-ai-token-limits-until-i-fixed-it-10-deep-strategies-that-actually-work-6a40c28bc17d" rel="noopener noreferrer"&gt;Medium article.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is the pattern that hits you hardest? Long sessions, re-uploads, or something else entirely — drop it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Claude API Bill Jumped 47% and I Didn't Change a Single Prompt — Here's Why</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Mon, 04 May 2026 06:09:32 +0000</pubDate>
      <link>https://dev.to/grewup/my-claude-api-bill-jumped-47-and-i-didnt-change-a-single-prompt-heres-why-56gm</link>
      <guid>https://dev.to/grewup/my-claude-api-bill-jumped-47-and-i-didnt-change-a-single-prompt-heres-why-56gm</guid>
      <description>&lt;p&gt;&lt;strong&gt;The problem nobody warned me about&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same prompts. Same workflows. Same model. Higher bill — every single week.&lt;br&gt;
I checked my logs expecting to find a spike in usage. Instead I found something stranger: the same prompt returning different token counts on different runs. Some runs were 30–47% higher than identical runs a few weeks earlier.&lt;/p&gt;

&lt;p&gt;No input change. No structural change. Just more tokens — and a cost bill I could not explain.&lt;br&gt;
After going through Reddit threads, developer forums, and an OpenRouter analysis of over 1M+ real API requests, here is what is actually happening and the six changes that brought my token usage back under control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What changed under the hood&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three things shifted simultaneously, and most cost-increase explanations only mention one of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The tokenizer itself changed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude's tokenizer now splits text differently. Same input produces more token segments. The expected increase from this alone is roughly 1.0x–1.35x. But real-world data from high-volume API users shows 1.4x–1.47x increases — and sometimes higher on specific content types.&lt;br&gt;
Code blocks, markdown formatting, and JSON structures are hit disproportionately hard because of how subword tokenisation handles special characters and whitespace patterns in technical content. If you are building coding assistants, agent workflows, or automation pipelines, your content type is in the high-impact zone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Newer model versions reason deeper by default&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More recent Claude versions spend more internal token budget on reasoning before generating output. This is the "thinking more" behaviour — better response quality, more tokens burned per request. If you upgraded model versions without adjusting your prompting approach, you absorbed a reasoning cost increase on top of the tokenizer change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Conversations compound exponentially&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every message in a multi-turn conversation appends to the context window. With each individual message now slightly larger than before (due to tokenizer changes), long sessions accumulate token weight faster than the same sessions would have previously. A ten-turn conversation that used to cost X tokens now costs 1.4X or more — and that multiplier applies to every turn, not just the last one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real-world impact on different use cases&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use case                  | Token impact | Why
--------------------------|--------------|------------------------------------
Coding assistant          | Very high    | Code blocks + formatting = heavy tokenisation
Long agent workflows      | Very high    | Multi-turn accumulation compounds
Single short prompts      | Low          | Minimal compounding, tokenizer delta only
Automation with full logs | Very high    | Raw log data is extremely token-inefficient
Repeat identical prompts  | Medium-low   | Caching mitigates tokenizer delta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your workflow sends full files, complete conversation histories, or raw log output to the API — you are in the highest impact category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The six changes that actually reduced my costs&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Stop sending unnecessary context&lt;/strong&gt;&lt;br&gt;
Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# Sending everything
&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_file_contents&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;full_history&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_question&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# Send only what the model needs for this specific task
&lt;/span&gt;&lt;span class="n"&gt;relevant_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_relevant_section&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_contents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;relevant_context&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_question&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result for my workflow: 40% token reduction on input alone. The model does not need your entire codebase to answer a question about one function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Break large prompts into focused smaller ones&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`One prompt that asks: analyse this code, suggest improvements, 
rewrite the function, add error handling, and write unit tests.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Prompt 1: Analyse this function for issues (code only, no file context)
Prompt 2: Rewrite with suggested fixes applied (function only)
Prompt 3: Add error handling to this specific function
Prompt 4: Write unit tests for this function signature`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each smaller prompt is cheaper than one large prompt, and the outputs are easier to validate and iterate on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Match reasoning effort to task complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude's newer versions apply heavier reasoning by default. For tasks that do not require deep reasoning — format conversion, simple extraction, classification — you can explicitly instruct the model to keep responses concise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Answer directly and concisely. 
Do not show your reasoning unless asked.
Do not pad the response with caveats or summaries.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saved approximately 15–20% on output tokens for my classification tasks where verbose responses were not needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Reset sessions instead of accumulating context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before: One long continuous session per agent workflow.&lt;br&gt;
After: Fresh session when the conversation exceeds a threshold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;MAX_CONTEXT_TURNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conversation_history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MAX_CONTEXT_TURNS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Summarise previous turns into a single context block
&lt;/span&gt;    &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;summarise_history&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conversation_history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conversation_history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Context: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the exponential compounding problem. Each accumulated turn is now slightly heavier — capping accumulation and replacing with a summary keeps costs predictable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Clean and compress inputs before sending&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before: Raw log output, unformatted JSON, full HTML responses pasted directly.&lt;br&gt;
After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compress_for_api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Remove blank lines
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="c1"&gt;# Remove HTML if only text is needed
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;[^&amp;gt;]+&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Truncate repeated whitespace
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; +&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaning inputs before sending reduced my token count by 20–30% on workflows that process scraped web content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Optimise stable prompts for prompt caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude's prompt caching charges a lower rate for repeated identical prompt prefixes. Structure your system prompts so the stable portion comes first and the dynamic content comes at the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="c1"&gt;# Structure that caches well:
&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;[Your long, stable system prompt here — this gets cached]&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Context for this specific request: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dynamic_context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Task: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;specific_task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caching only applies to the prefix that stays identical between calls. If your system prompt varies per request, caching does not help — standardise it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mental model shift that matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem is not that Claude got worse or more expensive for no reason. The tokenizer change reflects better text processing. The deeper reasoning produces better outputs.&lt;/p&gt;

&lt;p&gt;What changed is the default efficiency assumption. Prompts and workflows designed for the old tokenizer behaviour were implicitly relying on cheaper processing. That assumption no longer holds.&lt;/p&gt;

&lt;p&gt;The fix is not "use less AI." The fix is designing your prompts the way you would design efficient database queries — send only what is needed, structure it cleanly, cache what repeats, and reset state before it compounds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full breakdown with context on the OpenRouter analysis at my&lt;a href="https://medium.com/@jayanth01/i-didnt-change-anything-but-my-claude-api-cost-jumped-47-anthropic-s-tokenizer-explained-0429c817de33" rel="noopener noreferrer"&gt; Medium article.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you hit this in your own workflows? Drop your use case and the token multiplier you observed in the comments — trying to build a picture of which workflows are hit hardest.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I Built an n8n Workflow That Generates “Top 10” Videos Automatically (System Design + Lessons)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Wed, 29 Apr 2026 13:45:23 +0000</pubDate>
      <link>https://dev.to/grewup/i-built-an-n8n-workflow-that-generates-top-10-videos-automatically-system-design-lessons-2jic</link>
      <guid>https://dev.to/grewup/i-built-an-n8n-workflow-that-generates-top-10-videos-automatically-system-design-lessons-2jic</guid>
      <description>&lt;p&gt;&lt;strong&gt;Why I built this&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating content manually doesn’t scale.&lt;/p&gt;

&lt;p&gt;Even a simple “Top 10” video takes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;research&lt;/li&gt;
&lt;li&gt;scripting&lt;/li&gt;
&lt;li&gt;editing&lt;/li&gt;
&lt;li&gt;uploading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repeat that daily → it becomes a bottleneck.&lt;/p&gt;

&lt;p&gt;So instead of optimizing the process…&lt;/p&gt;

&lt;p&gt;I removed myself from it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this system does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This workflow automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generates topics&lt;/li&gt;
&lt;li&gt;writes structured scripts&lt;/li&gt;
&lt;li&gt;creates voiceovers&lt;/li&gt;
&lt;li&gt;generates visuals&lt;/li&gt;
&lt;li&gt;assembles final videos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Runs on a schedule.&lt;/p&gt;

&lt;p&gt;No manual input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Scheduler (cron)
↓
Topic Generator (AI)
↓
Script Generator (Top 10 format)
↓
Voice Generation (TTS)
↓
Visual Generation
↓
Video Assembly
↓
Upload / Storage`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type of pipeline is possible because :contentReference[oaicite:0]{index=0} connects APIs and services into deterministic workflows that execute predefined steps reliably. :contentReference[oaicite:1]{index=1}  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Trigger (Scheduler)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cron node runs daily&lt;/li&gt;
&lt;li&gt;Starts entire pipeline automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Topic Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI generates topics like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Top 10 AI tools”&lt;/li&gt;
&lt;li&gt;“Top 10 productivity apps”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Insight:
&lt;/h3&gt;

&lt;p&gt;Topic quality = performance&lt;/p&gt;

&lt;p&gt;Bad topic → system still runs → bad output at scale&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Script Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Strict structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook&lt;/li&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;Ranked list (#10 → #1)&lt;/li&gt;
&lt;li&gt;Outro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
txt
Top 10 AI tools you need in 2026

#10 ...
#9 ...
...
Why this matters

Structured formats are predictable → perfect for automation


**Step 4 — Voice Generation**
Text → speech (TTS / cloned voice)
Short sentences only
Common mistake

Long paragraphs → unnatural audio → low retention


**Step 5 — Visual Generation**

For each list item:

generate image / clip
map to script section


**Step 6 — Video Assembly**

Combine:

audio
visuals
timing

Output = ready-to-publish video


**Step 7 — Upload / Storage**
YouTube / Drive / S3
store metadata (URL, topic, status)
What actually breaks (real issues)

**1. Garbage input → garbage output**

Automation scales mistakes.

If topics are weak:
→ system produces low-performing videos faster

**2. Generic AI scripts**

Without constraints:
→ repetitive + boring content

Fix:

enforce structure
control output length

**3. Timing + pacing issues**
long segments kill engagement
uneven pacing breaks flow

**4. System maintenance**

n8n workflows are powerful but require setup and maintenance as integrations evolve.


**Key insight**

This is NOT a video generation system.

It’s a content pipeline.

And the difference is:

Manual:
idea → create → edit → publish

System:
data → process → output → repeat


**Why this works**

“Top 10” content has:

fixed structure
repeatable format
predictable output

Which makes it ideal for automation.


**Final workflow (simplified)**
Idea
 → Generate script
 → Generate voice
 → Generate visuals
 → Assemble video
 → Publish


**Final thought**

Most people try to:

edit faster
script better
produce more

But the real leverage is:

Designing systems that produce content without you


**Question for devs**

Anyone here building automated content pipelines?

Curious about:

scaling workflows
handling quality control
avoiding repetitive outputs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automate UGC Ad Videos with AI (Full Workflow + System Design)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Tue, 28 Apr 2026 16:54:45 +0000</pubDate>
      <link>https://dev.to/grewup/automate-ugc-ad-videos-with-ai-full-workflow-system-design-4ilm</link>
      <guid>https://dev.to/grewup/automate-ugc-ad-videos-with-ai-full-workflow-system-design-4ilm</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this builds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An automated pipeline that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generates ad scripts&lt;/li&gt;
&lt;li&gt;creates voice + video&lt;/li&gt;
&lt;li&gt;outputs ready-to-use UGC ads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Input Idea
↓
AI Script Generator
↓
Voice Generation
↓
Video Generation
↓
Editing Layer
↓
Final Output`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Script Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use LLM (Gemini / GPT)&lt;/p&gt;

&lt;p&gt;Structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook&lt;/li&gt;
&lt;li&gt;Problem&lt;/li&gt;
&lt;li&gt;Solution&lt;/li&gt;
&lt;li&gt;CTA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Voice Layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TTS / cloned voice&lt;/li&gt;
&lt;li&gt;keep sentences short&lt;/li&gt;
&lt;li&gt;natural tone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Video Layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;avatar or stock visuals&lt;/li&gt;
&lt;li&gt;sync with audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Editing Layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;captions&lt;/li&gt;
&lt;li&gt;transitions&lt;/li&gt;
&lt;li&gt;pacing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What breaks&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Long scripts&lt;br&gt;
→ poor pacing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generic output&lt;br&gt;
→ low engagement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No structure&lt;br&gt;
→ unusable video&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not video generation.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;content pipeline engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Full breakdown with screenshot check here - &lt;a href="https://elevoras.com/ugc-ads-2025-automate-videos-with-ai-save-100-hours/" rel="noopener noreferrer"&gt;UGC Ads 2025: Automate Videos With AI (Save 100+ Hours)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ad creatives&lt;/li&gt;
&lt;li&gt;content agencies&lt;/li&gt;
&lt;li&gt;social media automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anyone here using AI for ad creatives at scale?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automate Blog Publishing with n8n + AI + WordPress (Full Workflow) published: true</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Mon, 27 Apr 2026 14:31:45 +0000</pubDate>
      <link>https://dev.to/grewup/automate-blog-publishing-with-n8n-ai-wordpress-full-workflowpublished-true-56cl</link>
      <guid>https://dev.to/grewup/automate-blog-publishing-with-n8n-ai-wordpress-full-workflowpublished-true-56cl</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this builds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A complete automated blog pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetch trending content&lt;/li&gt;
&lt;li&gt;generate AI articles&lt;/li&gt;
&lt;li&gt;create images&lt;/li&gt;
&lt;li&gt;publish to WordPress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Scheduler (RSS)
↓
Filter topics
↓
AI content generation
↓
Image generation
↓
WordPress publish
↓
Tracking`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Fetch content (RSS)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pull from news sources&lt;/li&gt;
&lt;li&gt;filter last 24 hours&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Topic filtering&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove irrelevant content&lt;/li&gt;
&lt;li&gt;keep niche-specific topics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — AI blog generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;intro&lt;/li&gt;
&lt;li&gt;structured body&lt;/li&gt;
&lt;li&gt;conclusion&lt;/li&gt;
&lt;li&gt;SEO metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Image generation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate featured image&lt;/li&gt;
&lt;li&gt;attach to post&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Publish via WordPress API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;json&lt;br&gt;
{&lt;br&gt;
  "title": "Generated Title",&lt;br&gt;
  "content": "AI content",&lt;br&gt;
  "status": "publish"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;



**Step 6 — Tracking layer**

Store:

topic
publish date
URL


**What breaks**
1. Generic content

Fix: enforce structure

2. Duplicate posts

Fix: tracking layer

3. SEO issues

Fix: add metadata + structure

For full breakdown with screenshot and workflow template check out [Automate Your Blog with AI : The Complete N8N News-to-WordPress Tutorial](https://elevoras.com/automate-your-blog-with-ai-the-complete-n8n-news-to-wordpress-tutorial/)

**Key insight**

This is not content generation.

This is content infrastructure.


**Use cases**

- niche blogs

- affiliate sites



**Question**

Anyone running AI content pipelines in production?

Curious about scaling + SEO impact.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>n8nbrightdatachallenge</category>
      <category>automation</category>
    </item>
    <item>
      <title>Automate Instagram Comments with n8n + AI (Full Workflow + Real Issues)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Sun, 26 Apr 2026 11:03:16 +0000</pubDate>
      <link>https://dev.to/grewup/automate-instagram-comments-with-n8n-ai-full-workflow-real-issues-57c9</link>
      <guid>https://dev.to/grewup/automate-instagram-comments-with-n8n-ai-full-workflow-real-issues-57c9</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this builds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An automated system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monitors Instagram comments&lt;/li&gt;
&lt;li&gt;generates contextual AI replies&lt;/li&gt;
&lt;li&gt;optionally sends DMs&lt;/li&gt;
&lt;li&gt;tracks everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Basically:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;comment → response → conversation → lead&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Instagram Comment Trigger
↓
Fetch Post + Comment Data
↓
Filter (duplicates / spam)
↓
AI Response Generator
↓
Post Reply (Graph API)
↓
Send DM (optional)
↓
Store in DB / Google Sheets`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Trigger (Monitor Comments)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Instagram Graph API.&lt;/p&gt;

&lt;p&gt;Setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;poll every 2–5 minutes&lt;/li&gt;
&lt;li&gt;fetch latest posts&lt;/li&gt;
&lt;li&gt;extract new comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why polling?&lt;/p&gt;

&lt;p&gt;Because real-time webhook setup is more complex and not required for most use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Filtering Layer (Critical)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before doing anything, filter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;already replied comments&lt;/li&gt;
&lt;li&gt;duplicate users&lt;/li&gt;
&lt;li&gt;spam comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you skip this:&lt;br&gt;
→ your workflow will reply multiple times to the same user&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Extract Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From each comment, extract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;comment_text&lt;/span&gt;
&lt;span class="nx"&gt;username&lt;/span&gt;
&lt;span class="nx"&gt;post_caption&lt;/span&gt;

&lt;span class="nx"&gt;Why&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;matters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="nx"&gt;AI&lt;/span&gt; &lt;span class="nx"&gt;without&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;generic&lt;/span&gt; &lt;span class="nx"&gt;replies&lt;/span&gt;
&lt;span class="nx"&gt;AI&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;relevant&lt;/span&gt; &lt;span class="nx"&gt;replies&lt;/span&gt;


&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="nx"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;AI&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="nx"&gt;Generation&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;

&lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;{{ comment_text + post_caption }}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
System prompt example:

You are a helpful assistant replying to Instagram comments.

- Keep replies under 2 sentences
- Be natural and conversational
- Avoid generic responses
- Match context of the post

Output:

short reply
human-like tone
contextual response


**Step 5 — Post Reply**

Use Facebook Graph API:

POST /{comment_id}/replies

Payload:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "message": "AI generated reply"&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

This posts directly under the comment.


**Step 6 — DM Automation (Optional but Powerful)**

Trigger DMs based on:

keywords (e.g. "price", "link")
or every comment

Examples:

send product link
send lead magnet
send onboarding message

This is where conversions actually happen.


**Step 7 — Tracking Layer**

Store data in:

Google Sheets
Airtable
Database

Track:

username
comment
reply_sent
dm_sent
timestamp

Why?

prevents duplicates
builds lead database
helps debugging


**What breaks (real issues)**
1. Duplicate replies

Cause:

no tracking

Fix:

always store processed comments
2. Generic AI responses

Cause:

no context

Fix:

include post caption + intent
3. API limits

Instagram Graph API has:

rate limits
permission restrictions

Fix:

throttle requests
batch processing
4. Delay vs real-time

Polling = delay (2–5 min)

Tradeoff:

simpler setup
good enough for most use cases


**Key insight**

Most people think this is an "automation problem".

It’s not.

It’s a context + control problem.

Bad input → bad replies → low engagement


**Where this is useful**
creators (engagement boost)
agencies (lead generation)
businesses (auto support)


**Final workflow (simplified)**
Comment
 → Filter
 → Generate reply
 → Post reply
 → Send DM
 → Store data


Anyone here running Instagram automation at scale?

Curious about:

rate limit handling
better DM logic
spam avoidance strategies

Drop your setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build a Voice Cloning Auto-Reply Bot with n8n + ElevenLabs (Real Workflow, Not Theory)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Sat, 25 Apr 2026 17:27:22 +0000</pubDate>
      <link>https://dev.to/grewup/build-a-voice-cloning-auto-reply-bot-with-n8n-elevenlabs-real-workflow-not-theory-2n26</link>
      <guid>https://dev.to/grewup/build-a-voice-cloning-auto-reply-bot-with-n8n-elevenlabs-real-workflow-not-theory-2n26</guid>
      <description>&lt;p&gt;Most “&lt;strong&gt;AI voice bot&lt;/strong&gt;” tutorials show the result.&lt;/p&gt;

&lt;p&gt;Very few show what actually breaks when you try to build one.&lt;/p&gt;

&lt;p&gt;This is a full working workflow using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;n8n (automation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ElevenLabs (voice cloning)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI model (response generation)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And more importantly , what you need to get right for it to actually work in real use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we’re building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A system that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receives a message&lt;/li&gt;
&lt;li&gt;Generates a contextual AI response&lt;/li&gt;
&lt;li&gt;Converts it into a cloned voice&lt;/li&gt;
&lt;li&gt;Sends the audio back automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;customer support automation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;voice assistants&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creator voice replies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agency workflows&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Input (Webhook / App)
        ↓
AI Response (LLM)
        ↓
ElevenLabs (Text → Speech)
        ↓
Output (API / App / Messaging)`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Webhook (Input Layer)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In n8n:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add a Webhook node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable POST requests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tell me about your service"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why webhook?&lt;/p&gt;

&lt;p&gt;Because it allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;app integrations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API triggers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scalable input&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — AI Response Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an AI node (OpenAI / OpenRouter).&lt;/p&gt;

&lt;p&gt;Input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jinja"&gt;&lt;code&gt;`&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nv"&gt;json.message&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;System prompt (critical)&lt;/p&gt;

&lt;p&gt;This is where most people mess up.&lt;/p&gt;

&lt;p&gt;Bad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;long paragraphs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;generic responses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;no tone control&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;short replies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;defined tone&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;controlled output&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`You are a helpful assistant.

- Keep responses under 3 sentences
- Use natural conversational tone
- Avoid long explanations`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This directly affects voice quality later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — ElevenLabs Voice Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;p&gt;HTTP Request node&lt;br&gt;
OR&lt;br&gt;
dedicated integration&lt;br&gt;
API structure (simplified):&lt;br&gt;
POST &lt;a href="https://api.elevenlabs.io/v1/text-to-speech/%7Bvoice_id%7D" rel="noopener noreferrer"&gt;https://api.elevenlabs.io/v1/text-to-speech/{voice_id}&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{ $json.output }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eleven_multilingual_v2"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Headers:&lt;/p&gt;

&lt;p&gt;xi-api-key&lt;br&gt;
content-type&lt;/p&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;p&gt;audio stream / file&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Output Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Options depend on use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;return audio via API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;send via WhatsApp / Telegram&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attach in app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;auto reply system&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example (basic API response):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"audio_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generated_audio.mp3"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full Workflow Logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Webhook&lt;br&gt;
 → AI Node&lt;br&gt;
 → ElevenLabs&lt;br&gt;
 → Response&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually breaks (real issues)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Long AI responses = bad audio&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Problem:&lt;/p&gt;

&lt;p&gt;sounds robotic&lt;br&gt;
unnatural pacing&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

&lt;p&gt;limit output length&lt;br&gt;
enforce short responses&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Latency issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Flow delay:&lt;/p&gt;

&lt;p&gt;AI response&lt;br&gt;
voice generation&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;slow replies&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

&lt;p&gt;reduce token usage&lt;br&gt;
optimize prompts&lt;br&gt;
avoid unnecessary steps&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Voice quality problems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Common issues:&lt;/p&gt;

&lt;p&gt;inconsistent tone&lt;br&gt;
unnatural pauses&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

&lt;p&gt;use clean training data&lt;br&gt;
adjust ElevenLabs settings&lt;br&gt;
test multiple voice configs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cost scaling&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’re paying for:&lt;/p&gt;

&lt;p&gt;AI tokens&lt;br&gt;
voice generation&lt;/p&gt;

&lt;p&gt;Bad setup:&lt;/p&gt;

&lt;p&gt;long responses → higher cost&lt;/p&gt;

&lt;p&gt;Good setup:&lt;/p&gt;

&lt;p&gt;short + precise outputs&lt;br&gt;
Important design insight&lt;/p&gt;

&lt;p&gt;Most people think this is a “voice problem”.&lt;/p&gt;

&lt;p&gt;It’s not.&lt;/p&gt;

&lt;p&gt;It’s a text control problem.&lt;/p&gt;

&lt;p&gt;If your text output is bad:&lt;br&gt;
→ your voice output will be worse&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where this becomes powerful&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once stable, you can extend this to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multi-language voice bots&lt;/li&gt;
&lt;li&gt;memory-based assistants&lt;/li&gt;
&lt;li&gt;CRM integrations&lt;/li&gt;
&lt;li&gt;lead qualification systems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Final thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This workflow is simple on paper:&lt;/p&gt;

&lt;p&gt;Text → AI → Voice → Output&lt;/p&gt;

&lt;p&gt;But the quality depends entirely on:&lt;/p&gt;

&lt;p&gt;how you control responses&lt;br&gt;
how you handle latency&lt;br&gt;
how you structure the flow&lt;/p&gt;

&lt;p&gt;The difference between a demo and a usable system is in these details.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want the full breakdown check out - &lt;a href="https://elevoras.com/build-voice-clone-bot-n8n-elevenlabs-automation-2026/" rel="noopener noreferrer"&gt;Build Voice Clone Bot : n8n + ElevenLabs Automation 2026&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Anyone here running voice-based automation in production?&lt;/p&gt;

&lt;p&gt;Curious how you’re handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;latency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scaling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;real-time responses&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to compare setups 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Emergent AI Pricing Explained Credits, Plans &amp; How Not to Waste Money</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Fri, 24 Apr 2026 14:22:54 +0000</pubDate>
      <link>https://dev.to/grewup/emergent-ai-pricing-explained-credits-plans-how-not-to-waste-money-ddc</link>
      <guid>https://dev.to/grewup/emergent-ai-pricing-explained-credits-plans-how-not-to-waste-money-ddc</guid>
      <description>&lt;p&gt;&lt;strong&gt;The credit problem nobody warns you about&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're coming to Emergent from flat-rate tools — GitHub Copilot, Cursor, Replit's base tier — the pricing model will catch you off guard.&lt;br&gt;
Emergent isn't $20/month = unlimited. It's $20/month = 100 credits. And credits are consumed every time the AI does work: generating a feature, debugging an error, refactoring a component, loading project context.&lt;br&gt;
There's no upfront price list. No console that tells you "this prompt will cost 18 credits." You build, you spend, you find out at the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the credit cost map I put together from actual usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`TASK                              CREDIT COST
─────────────────────────────────────────────
Landing page + contact form       10–20 credits
User authentication (OAuth)       25–40 credits
Multi-file debugging session      15–30 credits
Full styling refactor             30–50 credits
Stripe payment integration        35–60 credits`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ranges exist because detailed prompts cost more than vague ones. "Add login" costs less than "Add login with Google OAuth, session management, error states, and post-auth redirect." Precision in your prompt = more computation = more credits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where credits actually disappear&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Context loading scales with project size. Emergent reads your entire project before making changes — this is what enables it to modify multi-file logic correctly. But as your codebase grows, every action costs more because context is larger.&lt;/p&gt;

&lt;p&gt;Debug loops are the silent budget drain. Identify bug → generate fix → test → secondary error → fix again. That's 30–50 credits per loop. Multiple loops on a complex bug can cost as much as building the original feature.&lt;/p&gt;

&lt;p&gt;"Quick changes" aren't quick credit-wise. Asking for a small tweak on a large project still triggers full project context loading. There's no "lightweight mode."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The math that matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standard breaks even with Pro at ~150 credits/month. Above that, Pro saves money per credit.&lt;br&gt;
Team only makes sense for genuine multi-developer workflows. Solo builders pay ~$100/month for collaboration features they don't use.&lt;br&gt;
Unused credits expire monthly. Don't over-subscribe. Start at Standard, track for 30 days, then decide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The decision framework in code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`function pickEmergentPlan(monthlyCredits, teamSize) {
  if (teamSize &amp;gt;= 3) return "Team";
  if (monthlyCredits &amp;gt; 150) return "Pro";
  if (monthlyCredits &amp;gt; 0) return "Standard";
  return "Free (demo only)";
}

// Add 30% buffer for debugging
const estimatedCredits = featureCost * 1.3;
const plan = pickEmergentPlan(estimatedCredits, 1);`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Discount code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you pick a plan: ELEVORAS at checkout = 5% off Standard, Pro, and Team. Applies every billing cycle as long as your subscription is active. Cancel and resubscribe = need to re-enter.&lt;/p&gt;

&lt;p&gt;vs. alternatives (developer perspective)&lt;br&gt;
Replit: Better community, better for projects requiring real developer control. "Unlimited" throttles on heavy compute. Real cost at serious usage: $50+/month.&lt;/p&gt;

&lt;p&gt;Bolt: No-credit flat rate is good for prototyping at volume. Lock-in is the problem — exporting a Bolt app to your own infra requires refactoring. Plan for that time cost.&lt;br&gt;
Lovable: Superior reasoning for complex logic. $40/month for 200 credits. Worth it for production-grade apps where correctness matters more than speed.&lt;/p&gt;

&lt;p&gt;Emergent's actual advantage for developers: Exported codebase is clean, readable, and deployable anywhere. No proprietary runtime. You own what you build.&lt;br&gt;
Full breakdown + discount code at elevoras.com — link in bio.&lt;br&gt;
Drop questions about specific use case credit costs below — happy to share the estimates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Build a 24/7 Facebook Messenger AI Chatbot With n8n (Full Setup — No Code)</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Wed, 22 Apr 2026 09:17:25 +0000</pubDate>
      <link>https://dev.to/grewup/build-a-247-facebook-messenger-ai-chatbot-with-n8n-full-setup-no-code-5fg9</link>
      <guid>https://dev.to/grewup/build-a-247-facebook-messenger-ai-chatbot-with-n8n-full-setup-no-code-5fg9</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this builds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Facebook Messenger chatbot that responds to every incoming message automatically, 24/7, using an AI agent connected to your Facebook Business Page via n8n. Customers message your page — they receive an intelligent, context-aware reply within 30 seconds, whether you are online or not.&lt;/p&gt;

&lt;p&gt;Workflow JSON download: Available on the blog&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Facebook Messenger message received
        ↓
n8n Webhook (GET + POST — allow multiple HTTP methods)
        ↓
IF node — hub.mode = "subscribe" AND hub.verify_token = [your token]
  ├── TRUE → Respond to Webhook with hub.challenge (verification)
  └── FALSE → Extract message from POST body
        ↓
AI Agent node (OpenRouter)
  — reads sender ID + message text
  — generates contextual reply
        ↓
HTTP Request → Facebook Graph API
  POST /me/messages → send reply to sender`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Create your Facebook Developer App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to developers.facebook.com and create an account if you do not have one.&lt;br&gt;
Click My Apps → Create App.&lt;/p&gt;

&lt;p&gt;App configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`App type:    Business
App name:    [Your Business] AI Assistant
Portfolio:   Select yours, or "No business portfolio selected"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: Do not overthink the naming. You can modify everything later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Switch app to Live mode (most tutorials skip this)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your app starts in Development mode — only you can test it. Real customers cannot interact with it until you switch to Live.&lt;br&gt;
Before switching, you need a Privacy Policy URL. Facebook verifies this automatically.&lt;br&gt;
Fastest method: go to termsfeed.com → generate a free privacy policy → copy the URL.&lt;br&gt;
In your app settings:&lt;/p&gt;

&lt;p&gt;Find "Privacy Policy URL" field → paste your URL&lt;br&gt;
Toggle the mode switch at the top from Development to Live&lt;/p&gt;

&lt;p&gt;Without this step, your chatbot will only work when you are testing it yourself. All live customer interactions will fail silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Create the n8n webhook&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your n8n dashboard → New Workflow → add a Webhook trigger node.&lt;br&gt;
Critical settings in the webhook configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Allow Multiple HTTP Methods: ON  ← most people miss this
HTTP Method:                 GET and POST both selected
Respond:                     Using 'Respond to Webhook' Node`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "Allow Multiple HTTP Methods" toggle is the setting that allows Facebook's verification handshake (GET request) and actual message delivery (POST request) to both hit the same webhook endpoint. Without this, you need two separate webhooks — and the verification fails.&lt;br&gt;
Copy the Production URL from the webhook node. This is what you paste into Facebook next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Add Messenger to your Facebook App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Back in your Facebook Developer dashboard:&lt;/p&gt;

&lt;p&gt;Find the Products section → click Add Product&lt;br&gt;
Find Messenger → click Set up&lt;/p&gt;

&lt;p&gt;Inside the Messenger configuration:&lt;br&gt;
Webhook settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Callback URL:   [paste your n8n Production URL]
Verify Token:   AI-chatbot  (or any string you choose — you will need this exactly in Step 5)`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click Verify and Save. Facebook sends a GET request to your webhook to confirm it is reachable.&lt;br&gt;
Subscribe to message events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`messages:        ON
message_reads:   ON`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate a Page Access Token:&lt;/p&gt;

&lt;p&gt;Select your Business Page from the dropdown&lt;br&gt;
Click Generate Token&lt;br&gt;
Copy the token immediately — it only displays once&lt;br&gt;
Store it securely — you need it in Step 7 to send messages back&lt;/p&gt;

&lt;p&gt;Subscribe your page to the webhook by clicking Add Subscriptions next to your page name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — The verification handshake (where 90% of people get stuck)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Facebook verifies your webhook by sending a GET request with three query parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`hub.mode          = "subscribe"
hub.verify_token  = [the token you set in Facebook]
hub.challenge     = [a random string Facebook wants echoed back]`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your n8n workflow must respond with the exact value of hub.challenge. If it does not, Facebook rejects the webhook and nothing works.&lt;br&gt;
Add an IF node after the webhook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Condition 1: {{ $json.query['hub.mode'] }}         equals  subscribe
Condition 2: {{ $json.query['hub.verify_token'] }}  equals  AI-chatbot
Both conditions must be TRUE`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the TRUE branch — add a "Respond to Webhook" node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Respond with:  Text
Response body: [switch from Fixed to Expression]
Expression:    {{ $json.query['hub.challenge'] }}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This echoes the challenge string back to Facebook, completing verification. Until this works, nothing else in the workflow can run.&lt;br&gt;
Test it: Save the workflow, click Execute Workflow, then go back to Facebook and click Verify and Save on the webhook configuration. If verification fails, check that your IF conditions exactly match the parameters Facebook sends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 — Extract the message from POST requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a customer sends a message, Facebook sends a POST request to your webhook with a JSON body. The message is nested inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;`//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Facebook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Messenger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;webhook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;structure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"messaging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sender"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SENDER_PAGE_SCOPED_ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"recipient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_PAGE_ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1234567890&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"mid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"message_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello, is this available?"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the FALSE branch of your IF node (POST requests that are not verification), add a Set Fields node to extract what you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sender_id:    {{ $json.body.entry[0].messaging[0].sender.id }}
message_text: {{ $json.body.entry[0].messaging[0].message.text }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two fields feed into the AI agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7 — AI Agent node&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an AI Agent node. Connect OpenRouter credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Input:        {{ $json.message_text }}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;System prompt — paste this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`You are a helpful customer service assistant for [Your Business Name].

You respond to Facebook Messenger messages from potential customers 
and existing clients.

Your tone: friendly, professional, helpful. Never robotic.

Key information about our business:
[Add: what you sell, your pricing if public, your hours, 
your location, your main services — whatever customers typically ask about]

If you cannot answer a specific question, tell the customer:
"I'll make sure [Name] gets back to you on this personally — 
usually within a few hours during business hours."

Never make up information you are not sure about.
Keep replies concise — 2-4 sentences maximum.`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Customise the system prompt for your specific business. The more specific the business information, the more useful the responses. Add your FAQs, your pricing tier (if public), your response time commitments, and any questions you regularly receive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8 — Send the reply via Facebook Graph API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`json&lt;br&gt;
Add an HTTP Request node.&lt;/p&gt;

&lt;p&gt;Method:  POST&lt;br&gt;
URL:     &lt;a href="https://graph.facebook.com/v18.0/me/messages" rel="noopener noreferrer"&gt;https://graph.facebook.com/v18.0/me/messages&lt;/a&gt;&lt;br&gt;
Headers:&lt;br&gt;
  Authorization:  Bearer [YOUR_PAGE_ACCESS_TOKEN]&lt;br&gt;
  Content-Type:   application/json&lt;/p&gt;

&lt;p&gt;Body (JSON):&lt;br&gt;
{&lt;br&gt;
  "recipient": {&lt;br&gt;
    "id": "{{ $('Set Fields').first().json.sender_id }}"&lt;br&gt;
  },&lt;br&gt;
  "message": {&lt;br&gt;
    "text": "{{ $json.output }}"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;Replace [YOUR_PAGE_ACCESS_TOKEN] with the token you generated in Step 4.&lt;br&gt;
The sender_id targets the reply to the specific person who sent the message. The $json.output contains the AI agent's response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9 — Activate and test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Toggle the workflow Active (top right — turns blue).&lt;br&gt;
Open your Facebook Business Page. Send a message to your own page from a personal Facebook account. Wait 15–30 seconds. You should receive an AI-generated reply.&lt;br&gt;
If no reply arrives, check the Executions tab in n8n. Each execution log shows exactly which node completed and where the flow stopped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What breaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Facebook verification fails repeatedly: Your IF node conditions are not matching Facebook's query parameters exactly. The parameters are case-sensitive: hub.mode and hub.verify_token with dots, not underscores. Also check that your Respond to Webhook node is on the TRUE branch, not the FALSE branch.&lt;/p&gt;

&lt;p&gt;Messages arrive but no reply is sent: The Page Access Token has expired or is invalid. Facebook page tokens can expire — regenerate it from the Facebook Developer dashboard and update the HTTP Request node. Also confirm the token has pages_messaging permission.&lt;/p&gt;

&lt;p&gt;AI Agent responds but Graph API returns 403: Your app does not have the pages_messaging permission enabled. Go to App Settings → Permissions and Features → search pages_messaging → Request permission.&lt;br&gt;
Workflow triggers on your own page posts, not just messages: You subscribed to more events than needed. In Facebook Messenger webhook settings, ensure only messages and message_reads are enabled. Disable feed, comments, and other event types.&lt;/p&gt;

&lt;p&gt;n8n receives POST but entry[0].messaging is undefined: Facebook occasionally sends other webhook event types (delivery receipts, echo messages). Add a second IF condition before the AI agent: check that $json.body.entry[0].messaging[0].message.text exists and is not null.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Running cost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OpenRouter with GPT-4 mini: approximately $0.001 per message response. 1,000 customer messages per month costs about $1.00 in API credits.&lt;br&gt;
n8n: free self-hosted or free cloud trial.&lt;br&gt;
Facebook API: free.&lt;/p&gt;

&lt;p&gt;The entire chatbot infrastructure costs under $7/month for most small businesses — significantly less than a single missed client.&lt;br&gt;
Workflow JSON at elevoras.com. Import directly into n8n and update the Page Access Token and verify token to your own values.&lt;/p&gt;

&lt;p&gt;Building a variation with memory (tracking conversation history per user)? Drop it in the comments — that is the natural next step and happy to share the memory node setup.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Automate Personalized Cold Email Icebreakers With n8n, 0.3% to 10% Reply Rate</title>
      <dc:creator>Jayanth</dc:creator>
      <pubDate>Tue, 21 Apr 2026 09:43:30 +0000</pubDate>
      <link>https://dev.to/grewup/automate-personalized-cold-email-icebreakers-with-n8n-03-to-10-reply-rate-48pk</link>
      <guid>https://dev.to/grewup/automate-personalized-cold-email-icebreakers-with-n8n-03-to-10-reply-rate-48pk</guid>
      <description>&lt;p&gt;&lt;strong&gt;What this builds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An n8n workflow that takes a list of prospects from Google Sheets, scrapes each prospect's website (homepage plus up to 3 internal pages), uses AI to extract meaningful business insights from each page, generates a hyper-personalised multi-line icebreaker for each prospect, and writes the icebreaker back to the Sheet — ready for your outreach tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"Hey Katie, love how KTL Graphics makes it easy to filter by acreage — 
also a fan of your property update email option. Wanted to run 
something by you..."`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system found acreage filtering and email notification features by actually crawling the website — not from the company name or LinkedIn headline.&lt;/p&gt;

&lt;p&gt;Workflow JSON download: Available on the blog&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Manual Trigger
        ↓
Google Sheets — get all rows
        ↓
Filter — only rows with email AND website URL
        ↓
Loop Over Items (batch size 1)
        ↓
HTTP Request — scrape homepage (HTML)
        ↓
Edit Fields — extract html field
        ↓
Code node — convert to string
        ↓
HTML Extractor — pull all &amp;lt;a href&amp;gt; links
        ↓
Edit Fields — keep: first_name, last_name, email, website_url, links
        ↓
Split Out — one row per link
        ↓
Filter — links starting with /
        ↓
Code node — normalise relative/absolute URLs
        ↓
Remove Duplicates + Limit (max 3 pages)
        ↓
HTTP Request — fetch each internal page
        ↓
HTML to Markdown conversion
        ↓
AI Agent — summarise each page into abstract
        ↓
Merge all abstracts
        ↓
AI Agent — generate icebreaker from all abstracts
        ↓
Google Sheets — write icebreaker back to prospect row`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1 — Google Sheets setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Export your Apollo.io leads (or any source) to Google Sheets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required columns:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="k"&gt;first&lt;/span&gt;&lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="k"&gt;last&lt;/span&gt;&lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="k"&gt;email&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="k"&gt;website&lt;/span&gt;&lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="k"&gt;url&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="k"&gt;icebreaker&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;filled&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow reads from this sheet and writes icebreakers back to the icebreaker column.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Filter node (quality gate)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a Filter node after the Sheets Get Rows node.&lt;br&gt;
Two conditions, both must be true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Condition 1: website_url  exists and is not empty
Condition 2: email        exists and is not empty`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without this filter, the workflow attempts to scrape blank URLs and throws errors that cascade through the rest of the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Loop Over Items (batch size 1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a Loop Over Items node.&lt;/p&gt;

&lt;p&gt;Batch Size: 1&lt;/p&gt;

&lt;p&gt;This processes one prospect at a time. Without it, the workflow tries to process all prospects simultaneously — rate limits on external sites cause failures, and the AI responses get mixed across prospects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Scrape the homepage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an HTTP Request node.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Method:      GET
URL:         {{ $json.website_url }}
Error handling: Continue on error
Redirects:   Follow, max 21`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Continue on error" is critical. Some websites block scraping. Without this setting, one blocked site kills the entire workflow run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Extract and normalise HTML&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an Edit Fields node:&lt;/p&gt;

&lt;p&gt;Field: html → string → {{ $json.data }}&lt;/p&gt;

&lt;p&gt;Add a Code node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`return [{
  json: {
    html: $json.html.toString()
  }
}];`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This converts the raw response body to a usable string&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 — Extract all links from the homepage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an HTML Extractor node.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`CSS Selector:  a
Attribute:     href
Return:        Array
Options:       Trim values + clean text`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pulls every link from the homepage — navigation, footer, internal pages. The homepage alone contains only part of the story. The About page, Services page, and Blog posts are where the personalisation gold lives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7 — Normalise URLs (Code node)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After splitting links into individual rows and filtering for links starting with /, add this Code node to normalise both relative and absolute URLs to relative paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`const items = $input.all();

const updatedItems = items.map((item) =&amp;gt; {
  const link = item?.json?.links;

  if (typeof link === "string") {
    if (link.startsWith("/")) {
      item.json.links = link;
    }
    else if (link.startsWith("http://") || link.startsWith("https://")) {
      try {
        const url = new URL(link);
        let path = url.pathname;
        if (path !== "/" &amp;amp;&amp;amp; path.endsWith("/")) {
          path = path.slice(0, -1);
        }
        item.json.links = path || "/";
      } catch (e) {
        item.json.links = link;
      }
    }
    else {
      item.json.links = link;
    }
  }
  return item;
});

return updatedItems;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this is necessary: Websites use both relative links (/about) and absolute links (&lt;a href="https://example.com/about" rel="noopener noreferrer"&gt;https://example.com/about&lt;/a&gt;). You need both normalised to the same format to deduplicate and combine with the base URL correctly in the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8 — Deduplicate and limit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a Remove Duplicates node (deduplicate on links field) followed by a Limit node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Max items: 3
Keep:      First Items`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three pages per prospect is the sweet spot. Enough to find specific details, not enough to run up excessive API costs or hit rate limits on the target site.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9 — Fetch internal pages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add another HTTP Request node to fetch each filtered internal URL:&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Method: GET&lt;br&gt;
URL:    {{ $json.website_url }}{{ $json.links }}&lt;br&gt;
Error handling: Continue on error&lt;br&gt;
`&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The URL concatenates the base domain from the original lead data with the relative path extracted from the link list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10 — HTML to Markdown&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an HTML to Markdown node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Mode:            HTML to Markdown
HTML:            {{ $json.data ? $json.data : "&amp;lt;div&amp;gt;empty&amp;lt;/div&amp;gt;" }}
Destination Key: data`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Markdown is significantly more token-efficient than HTML for AI processing. Stripping HTML tags reduces the content you are passing to the AI model by 60–80%, which directly reduces API cost and improves the quality of the AI's analysis by removing noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11 — AI page summariser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add an AI Agent node with this system prompt:&lt;/p&gt;

&lt;p&gt;You are a helpful, intelligent website scraping assistant.&lt;/p&gt;

&lt;p&gt;You are provided a Markdown scrape of a website page. &lt;br&gt;
Your task is to provide a two-paragraph abstract of what this page is about.&lt;/p&gt;

&lt;p&gt;Return in this JSON format:&lt;br&gt;
{"abstract":"your abstract goes here"}&lt;/p&gt;

&lt;p&gt;Rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your extract should be comprehensive — similar level of detail 
as an abstract to a published paper.&lt;/li&gt;
&lt;li&gt;Use a straightforward, factual writing style.&lt;/li&gt;
&lt;li&gt;Focus on what is unique or distinctive about this business or page.&lt;/li&gt;
&lt;li&gt;Note any specific features, products, services, or differentiators 
that would be useful for personalised outreach.&lt;/li&gt;
&lt;li&gt;Return ONLY the JSON object. No backticks. No explanation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model: GPT-4 mini via OpenRouter — approximately $0.0003 per page abstract.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 12 — Merge all abstracts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the loop processes all three pages, merge the abstract outputs into a single node. Use a Merge node set to "Combine All Items."&lt;br&gt;
Pass the merged abstracts to the final AI Agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 13 — Icebreaker generator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a final AI Agent node with this system prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`You are an expert cold email copywriter specializing in personalized outreach.

You will receive multiple website page summaries for a prospect company.
Your task is to write a multi-line, personalized icebreaker for a cold email.

Rules:
- Reference 1-2 SPECIFIC details you found on their website
  (features, initiatives, content, language they use about themselves)
- Sound like you actually explored the website — not like you read a summary
- Be conversational, warm, and curious — not salesy
- Keep it to 2-3 sentences maximum
- Address the first_name directly at the start
- End with a natural transition into your pitch ("Wanted to run something by you...")

First name: {{ $('Loop Over Items').first().json.first_name }}
Website summaries: [all abstract outputs concatenated here]

Return ONLY the icebreaker text. No JSON. No explanation.
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 14 — Write back to Google Sheets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a Google Sheets node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Operation:    Update Row
Match on:     email = {{ $json.email }}
Update:
  icebreaker: {{ $json.icebreaker }}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The icebreaker column fills in for each row as the workflow processes it. When the run is complete, your Sheet has a personalised icebreaker for every prospect with a valid website URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What breaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTTP Request returns 403 on most sites: The site is blocking the default n8n user agent. Add a custom header: User-Agent: Mozilla/5.0 (compatible; outreach-research/1.0). This passes most basic anti-scraping checks.&lt;br&gt;
AI Agent returns a JSON error instead of abstract: The page content was empty (HTTP request returned an error page). The {{ $json.data ? $json.data : "&lt;/p&gt;empty" }} expression in the HTML to Markdown node handles this — it passes a dummy div instead of null, which prevents the AI from throwing on empty input.

&lt;p&gt;Loop produces mixed data across prospects: You are not using batch size 1. Set Loop Over Items batch size to exactly 1.&lt;br&gt;
Icebreakers sound generic despite the workflow running: The AI is receiving summaries but not finding distinctive details. Check your Limit node — if it is set to 0 or is missing, you may only be scraping the homepage. Set it to 3 to ensure About and Services pages are included.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Running cost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OpenRouter GPT-4 mini: approximately $0.002 per prospect (3 page abstracts + 1 icebreaker generation).&lt;br&gt;
100 prospects = $0.20 in API costs.&lt;br&gt;
1,000 prospects = $2.00.&lt;/p&gt;

&lt;p&gt;Compare this to $5–$50 per manually researched and written personalised opener. The cost case is immediate.&lt;br&gt;
Workflow JSON at elevoras.com.&lt;br&gt;
What niche are you targeting with cold outreach? Drop it in the comments — happy to suggest prompt adjustments for specific industries.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
