Landing page audit agent
This page explains how a landing page audit agent reviews the messaging, CTAs, claims compliance, link validity, and conversion elements of your own and competitor landing pages under a read-only grant, and returns an audit report with page sources. After reading it, you will understand which modules this scenario needs, how the permission boundary narrows, and why data like brand rules belongs in a policy store rather than Memory.
Use case
Marketing teams need to check landing pages against product positioning, brand voice, compliance requirements, and conversion goals before publishing. With many pages and frequent redesigns, manually checking copy consistency, claim wording, link validity, and conversion elements page by page is slow and error-prone — and handing CMS preview access to an ungoverned script means unreleased content can leak.
Typical triggers:
- A new campaign is about to launch, and every landing page needs a pre-publish audit within a business day.
- Positioning or pricing changed, and all existing pages must be swept for stale claims and dead links.
- A competitor redesigned, and your pages need a messaging and conversion-element gap check.
Engineering challenges
- High volume, high miss cost: dozens of pages × four dimensions (copy, claims, links, conversion elements). Manual spot checks always leave blind spots, and an out-of-bounds claim reaching production is a compliance incident.
- Evidence is hard to organize: every finding needs "which page, which version, when" — scattered screenshots and links cannot support later review.
- Borrowed CMS preview access is too broad: an editor account can see every collection and carries edit and publish permissions, while the audit only needs to read the pages under review.
Module composition
| Module | Role | Notes |
|---|---|---|
| GenAuth | Core | Read-only delegation, revocation, and the audit chain for authorized pages such as CMS previews. |
| Web Agent | Core | Controlled sessions extract headlines, CTAs, claims, and link status page by page, keeping a screenshot and source per page; public competitor pages can be supplemented with WebSearch. |
| GUMem | Optional | Only stores reviewer-confirmed long-term preferences (for example, preferred rewrite tone). Brand rules and forbidden claims are versioned policy — keep them in your policy store and inject them per version. They are not Memory. |
Permission and delegation boundaries
The Agent holds no inherent permissions. The effective authority for each audit is the intersection of three sets: what the user actually holds ∩ what was explicitly delegated for this task ∩ what the enterprise has approved. Applied here:
- The delegated scope covers only "read the specified pages, CMS previews, and competitor comparison pages" — no editing, publishing, or CMS configuration changes.
- Delegation credentials are short-lived; minute-level validity is recommended for a single audit, with re-delegation after expiry.
- The user or an administrator can revoke the grant at any time; new page reads fail immediately after revocation.
- Out-of-scope attempts (for example, a CMS collection outside the delegated list) are rejected and recorded — the audit chain covers all attempts, not just successful actions.
Note: the SDK example requests product-level scopes (such as webagent.do_anything:read). Fine-grained boundaries — domain lists, page ranges, action whitelists — are enforced by the GenAuth Agent Profile or your policy layer, not by the task prompt; that configuration is not shown on this page. See Delegate token and attenuation for the full semantics.
Workflow
The user provides the list of landing pages or CMS preview links to audit and picks the review dimensions.
GenAuth issues a least-privilege, read-only delegation credential for this task.
Your app loads the current version of brand rules, forbidden claims, and conversion-element checks from the policy store and injects them into the task.
Web Agent opens each target page, extracts headlines, CTAs, proof points, and pricing claims, and keeps a screenshot and source URL per page.
Checkpoint: When a CMS preview hits a login wall, CAPTCHA, or risk-control page, the Web Agent should escalate to a human instead of silently bypassing it.
Web Agent checks in-page link validity and conversion-element completeness; public competitor pages are extracted for comparison as needed.
The Agent aggregates findings per page — copy inconsistencies, out-of-bounds claims, dead links, missing conversion elements — each with page source, screenshot evidence, and the policy version.
The Agent returns the review checklist, findings, rewrite suggestions, and source list with an audit id; the report and screenshots are archived to your audit storage.
Checkpoint: Every finding in the report should trace back to a concrete page source and screenshot; conclusions without evidence should not enter the deliverable.
Example code
The example below wires this scenario into your backend with the official Qoni SDK (@qoniai/qoni): silent delegation → load brand policy from your policy store → one doAnything.run() for the page-by-page audit with screenshot evidence → parse and validate the report.
import { Qoni, QoniScopes } from '@qoniai/qoni'
const qoni = new Qoni({
accessKey: process.env.QONI_ACCESS_KEY!,
secretKey: process.env.QONI_SECRET_KEY!,
})
export async function auditLandingPages(userId: string, pages: string[]) {
// 1. Silent delegation: public pages and pre-authorized CMS previews,
// no interactive consent required
const { data: grant } = await qoni.delegateToken({
user: { id: userId },
agent: 'landing-page-audit',
scopes: [QoniScopes.DO_ANYTHING_READ, QoniScopes.DO_ANYTHING_MANAGE],
})
// 2. Before the run: load the current brand policy from YOUR policy store
// (this is versioned policy, not Memory)
const policy = await loadBrandPolicy() // e.g. { version: '2026-08', forbiddenClaims: [...], voice: ... }
// 3. One call runs the audit: evidence per page, report only
const run = await qoni.doAnything.run({
token: grant.token,
prompt: `
Audit the following landing pages: ${pages.join(', ')}.
For each page, extract the headline, CTAs, proof points and pricing claims,
check link validity and conversion elements, and keep a screenshot and
the source URL as evidence for every finding.
Return findings as a JSON array of
{ page, issue, quote, ruleId, sourceUrl } objects.
Report only. Do not edit pages, publish content or change CMS settings,
and never send unreleased page content to external services.
Brand policy (version ${policy.version}):
${JSON.stringify(policy)}
`,
capture: { screenshots: true },
})
const result = await run.wait({
// CMS preview hits a login wall / CAPTCHA / risk control: escalate to a human
onInteraction: (interaction) => notifyUserActionRequired(interaction),
})
// 4. Parse and validate the output contract on the app side:
// findings without a source never reach the report
const findings = parseFindings(result.output).filter(
(f) => f.sourceUrl && f.ruleId,
)
return {
findings,
artifacts: result.artifacts, // screenshots, archived to audit storage
policyVersion: policy.version,
audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
}
}The output structure is a contract set by the task prompt: here it is an array of { page, issue, quote, ruleId, sourceUrl }, parsed and validated by parseFindings on the app side, and any entry missing sourceUrl or ruleId is dropped. The SDK itself returns the generic RunResult (runId, status, output, artifacts, and so on).
Data and rule boundaries
This scenario touches four kinds of data; only the last belongs in GUMem:
- Versioned rules: brand voice, forbidden claims, conversion-element checklists — managed by version in your policy store, referenced by version number in every report.
- Business state: audit reports, findings, page screenshots — archived to your audit storage for review and traceability.
- Audit records: the delegation and behavior chain formed by
grantIdandauditId— maintained by GenAuth. - User Memory (optional): reviewer-confirmed long-term preferences, such as rewrite-tone preferences — this is where GUMem fits; a one-off audit neither recalls nor writes back by default.
Failure handling
| Situation | Recommended handling |
|---|---|
| CMS preview login state expires | Suspend the task, notify the user to sign in again, and resume from the checkpoint. |
| Page structure changes break extraction | Treat it as a failure and replay the session recording; never emit findings without evidence. |
| Request for a CMS collection outside the grant | Reject and record it; the attempted access remains visible in the audit chain. |
| An output entry lacks a source or rule id | App-side validation drops the entry and the report notes how many were dropped. |
Production notes
Never send unreleased page content to ungoverned external services. Rewrite suggestions must keep the original page source. The Agent only outputs reports and suggestions — it does not modify live pages or CMS content; any page change is made manually by the content owner based on the report and then reviewed. Extraction of public competitor pages should respect the target site's terms of service and be rate-limited.
Next steps
- Read the Quickstart to run the shortest path for Agent identity and delegation.
- Read Authorization and browser sandbox for the security boundaries of controlled sessions.
- Continue with the Brand consistency agent for an adjacent scenario.