Landing Page Writer
[Live] ·
agent__landing-page-writer· Claude Sonnet 4.6
Writes conversion-optimised landing page copy — from hero headline to FAQ — structured for a specific offer, audience, and page goal, with social proof placeholders drawn from real client data.
Overview
| Function | Write conversion-optimised landing page copy for a specific offer, audience, and page goal |
| Type | Worker — Content |
| Model | Claude Sonnet 4.6 |
| Queue | agent__landing-page-writer |
| Concurrency | 1 |
| Timeout | 5 min |
| Est. cost / task | ~$0.60 |
| Plan | Pro+ |
Triggers
| Trigger type | When | Who initiates |
|---|---|---|
| Activity Planner dispatch | Enqueued as part of a campaign launch pipeline — typically after a campaign brief is approved | Activity Planner |
| Rejection re-run | DM reviewer rejects; wakeReason: "rejection" re-enqueues with reviewerFeedback | DM reviewer |
Input
interface ActivityJobData {
activityId: string;
tenantId: string;
wakeReason?: "rejection";
reviewerFeedback?: string; // only present on rejection re-runs
}The worker reads additional context from the DB at runtime:
Activity.label— the page topic/titleActivity.inputPayload— optional key/value hints from the activity planner (e.g. target audience, primary CTA)ClientContext.content— tenant background (brand voice, products, audience)AgentConfig.systemPrompt— the prompt template (seeded; editable in manage portal)- RAG: top-5 results from
search({ agentRole: "landing-page-writer", query: label })— brand docs, website, published content
Output
The agent returns structured markdown with seven ## section blocks. These are parsed by parseSections() and stored as a sections JSON field on the LandingPage DB record.
## Hero
# Main headline (benefit-led, 6–12 words)
Subheadline paragraph — expands the headline, 1–2 sentences.
## Problem
# Problem section heading
Pain point paragraph(s) or bullet list.
## Solution
# Solution heading
How the product/service solves the problem.
## Features
# Features heading
- Feature one: benefit framing
- Feature two: benefit framing
...
## Social Proof
# Testimonials heading
- "[TESTIMONIAL: outcome + name + company]"
...
## FAQ
### Question one?
Answer one.
### Question two?
Answer two.
## CTA
# Final CTA headline
Supporting copy paragraph.
**Meta Title:** <title>
**Meta Description:** <description>The sections are rendered into a self-contained HTML page by renderLandingPageHtml() in packages/common/src/landing-page-html.ts.
Sample output excerpt (actual format)
## Hero
# Stop Losing Customers to ChatGPT — Get Found on Every AI Platform
AI search engines are answering your customers' questions right now. Leadmetrics' AI Search
Optimisation puts your business in front of buyers the moment they ask — on ChatGPT, Gemini,
Bing Copilot, and Meta AI.
## Problem
# Your Competitors Are Already There
- Buyers are skipping Google and asking AI directly — and AI is recommending your competitors
- Most businesses have no visibility into what AI says about them
- Traditional SEO doesn't translate to AI answer engines
## Features
# Everything You Need to Dominate AI Search
- GEO Optimisation: Structured content that AI engines extract and cite
- AEO Coverage: Question-answer pairs that surface in conversational AI results
- Competitor Gap Analysis: See what AI says about your rivals — and how to beat them
- Monthly Visibility Reports: Track your AI share of voice across all platforms
**Meta Title:** AI Search Optimisation for Indian Businesses | Leadmetrics
**Meta Description:** Get your business found on ChatGPT, Gemini, and Bing Copilot.
Leadmetrics is India's all-in-one GEO/AEO platform for SMEs and in-house teams.How It Works
-
Load activity and context. Reads the
Activityrecord, tenantClientContext, and theAgentConfig.systemPromptfrom the DB. Runs a RAG query using the activity label as the search term. -
Build prompt.
buildPrompt()concatenates: system prompt → client context → RAG context → input hints → (on rejection) reviewer feedback → output format instructions. -
Execute Claude. Calls the Claude adapter with a 5-minute timeout. Progress events are published via SSE as tool calls are made.
-
Parse output.
parseSections()splits the markdown into seven named sections.extractTitle(),extractMetaTitle(),extractMetaDescription(), andslugify()pull page metadata. -
Save LandingPage. Creates (or updates, on rejection) a
LandingPagerecord withstatus: "dm_review". SetsActivity.status = "awaiting_approval". -
Notify. Publishes an in-app notification to DM reviewers:
"Landing page '[title]' is ready for DM review.".
HTML Rendering
renderLandingPageHtml() in packages/common/src/landing-page-html.ts converts the stored sections into a self-contained HTML file (inline CSS, no CDN, no JS) with seven section renderers:
| Section | Renderer | Layout |
|---|---|---|
| hero | renderHero() | Full-width gradient, centred H1 + subheadline + CTA button |
| problem | renderProblem() | Auto-fill card grid with ✕ icons |
| solution | renderSolution() | Purple box, full-width |
| features | renderFeatures() | Auto-fill card grid with emoji icons |
| socialProof | renderSocialProof() | Quote card grid |
| faq | renderFaq() | Stacked accordion-style items, max-width 700px |
| cta | renderCta() | Full-width gradient, centred H2 + button |
Label normalisation: normalizeLabels() runs as a preprocessing step in parse() to handle legacy output where Claude emitted H1: / **H1:** / Subheadline: labels instead of markdown headings. This ensures pages saved before the April 2026 prompt fix still render correctly.
System Prompt
The live system prompt is seeded via packages/db/src/seed.ts and stored in AgentConfig (role: landing-page-writer). It can be edited in the Manage portal under Agents.
Key rules in the prompt:
- Seven sections in order: Hero → Problem → Solution → Features → Social Proof → FAQ → CTA
- Use
#for the main headline within each section; plain paragraphs for subheadlines - Use
-bullet points for feature/benefit lists - No element labels (
**H1:**,**Subheadline:**,**CTA Button:**) — write content directly - Benefit-led headlines; “you” language throughout
Skills Injected
| Skill file | Purpose |
|---|---|
landing_page_principles.md | Above-fold structure, trust signals, CTA hierarchy, conversion optimisation |
seo_writing_guide.md | Keyword placement, heading hierarchy, meta descriptions |
HITL Gates
| Gate | Who | Platform | Trigger |
|---|---|---|---|
| DM review | DM reviewer | DM portal /landing-pages | Auto on generation; LandingPage.status = "dm_review" |
| Client approval | Client | Dashboard /landing-pages/[id] | After DM approves; LandingPage.status = "client_review" |
Rejection at either gate re-enqueues the worker with wakeReason: "rejection" and the reviewer’s notes. The LandingPage version increments on each revision.
RAG Usage
| Dataset | Query | When used |
|---|---|---|
| All datasets for this tenant | "[activity.label] landing page" | Always — top-5 results injected as knowledge base context |
Cost Profile
| Avg input tokens | ~6,000 (system prompt + client context + RAG + hints) |
| Avg output tokens | ~1,500 (seven markdown sections) |
| Est. cost / task | ~$0.60 |
| Credits charged | 3 credits (type: landing_page) |
Error Handling
| Error | Response |
|---|---|
AgentConfig missing system prompt | Throws immediately — "No systemPrompt configured for agent role landing-page-writer" |
| Claude output < 200 chars | Activity + Deliverable set to failed; job throws |
| Claude execution fails | Activity + Deliverable set to failed; credits released |
| RAG fetch fails | Warning logged; proceeds without RAG context |