Affinity Design
Agency Guide

SEO Agent

Always-on SEO optimization worker with autonomous sub-agents, auto-blogger, and campaign lifecycle

Overview

The SEO Agent is an always-on optimization worker for a connected website. It reads SEO reporting data, site content, keyword opportunities, prior action history, and operator-submitted ideas — then chooses the next executable SEO action within budget and safety limits.

The agent can:

  • Audit technical and content health
  • Research keywords, SERPs, and competitors
  • Build topical maps and content clusters
  • Draft SEO blog posts through the auto-blogger
  • Optimize money pages
  • Apply or recommend technical SEO fixes
  • Monitor reports for ranking, traffic, and striking-distance changes
  • Record every action into campaign and action history for review

Think of the SEO agent as a loop, not a one-shot generator. It continuously watches reporting data, queues campaigns, analyzes situations, runs actions, and measures outcomes.

Runtime Loop

The runtime processes work asynchronously through a worker heartbeat:

  1. Queue — A campaign is queued by an admin trigger, manual request, or SEO reporting alert
  2. Lease & start — The worker heartbeat claims the campaign and sets runtime to running
  3. Situation analysis — Loads current domain state, reporting trends, previous actions, site context, and memory
  4. Action context — Builds the executable action catalog, verifying each action has real inputs (due keyword, target URL, audit findings)
  5. Strategy — Chooses one executable action or returns none when no safe action is ready
  6. Sub-agent dispatch — The selected action runs with resolved inputs
  7. Website handoff — If the action changes site content, it hands off to website execution (blog drafts → WordPress draft jobs)
  8. Evaluation — Records results, updates keyword timestamps, appends action history, checks budget/duration/cancellation
  9. Loop or complete — The graph loops for another action or completes the campaign with a report
  10. Outcome measurement — Later reporting data is compared against baseline so the agent learns
  11. Alert scan — Continues watching for position drops, traffic cliffs, and striking-distance surges

Runtime States

StateMeaning
idleNo active campaign
queuedCampaign accepted, waiting for worker
runningWorker owns the lease, actively executing
cancellingCancellation requested, stops at next safe boundary

Only one active campaign per SEO agent at a time.

Sub-Agents

ActionWorkerPurpose
auditAuditorRefresh technical/content health and identify findings
researchResearcherGather keyword, SERP, and competitor context
topographyTopographyBuild or refine topical clusters and site structure
blog-writeBlog WriterProduce or update informational content tied to executable keyword context
money-pageMoney PageImprove high-intent pages tied to executable URL context
technical-seoTechnical SEOApply or recommend technical fixes (requires completed audit with actionable findings)
noneStrategy onlyExplicitly take no action when no safe high-value action is executable

Aliases like auto-blogger, blogger, auditor, and topographer normalize to the supported runtime actions.

Strategy never chooses blog-write or money-page without executable inputs. If inputs are missing, the runtime returns none instead of attempting a partial action.

Action Outputs

ActionIntended Output
auditAudit record with score, findings, and summary of site health
researchKeyword, SERP, and competitor research payload used for planning
topographyUpdated topical map or cluster structure
blog-writeContent generation or update result tied to a specific keyword opportunity
money-pagePage optimization result tied to a specific URL and commercial intent
technical-seoTechnical remediation result or structured set of fixes

Auto-Blogger

The auto-blogger is the blog-write sub-agent. It does not blindly invent posts — it uses executable keyword context from DataForSEO, Google Search Console, tracked keywords, and operator-submitted ideas.

Auto-Blogger Loop

  1. Select a due keyword candidate (weighted by priority, ranking opportunity, intent, freshness)
  2. Skip keywords recently drafted to avoid repeated posts
  3. Build a content brief from cluster context, internal link opportunities, and SERP/research data
  4. Generate the blog draft, title, slug, meta title, meta description, FAQ/article schema, and review notes
  5. Queue a WebsiteExecutionJob with operation: "write_entity", postType: "post", status: "draft"
  6. Attach client asset reference as a WordPress featured image when featuredAssetRef or assetRefs are provided
  7. Save keyword timestamps (lastSelectedAt, lastDraftedAt)
  8. The reporting loop measures rankings and traffic later before strategy repeats or changes direction

Publishing remains an operator decision unless the website execution policy is changed elsewhere. Blog posts are queued as WordPress drafts by default, not published live.

Keyword Ideas & Scheduling

Operators can influence the agent without editing database records directly.

Submit Keyword Ideas

POST /admin/seo/agents/:id/keyword-ideas

Fields: keyword, proposedAction, intent, priority, scheduledFor, url, clusterSlug, and notes.

  • Future-dated ideas are held until due
  • Higher priority due ideas receive a stronger score in action selection
  • Submitted ideas are stored as manual SeoKeyword records with operator tags and scheduling metadata

Inspect Action Context

GET /admin/seo/agents/:id/action-context

See what the runtime currently considers executable or blocked, including candidates for blog writing, money-page work, and technical SEO.

The admin SEO detail page exposes this in the Keywords tab.

Keyword Hit List & Maintenance

The Hit List (SEO ▸ Keywords ▸ Hit List) is the single committed master list for a client's keyword work — every keyword the agent or an operator has research has been through the same pipeline lands here, alongside the Saved Keywords research library it's promoted from.

Before a keyword can claim a hit-list candidate slot, an LLM relevance check screens out GSC queries that share a word with the site but have no commercial tie to the business (e.g. a school or an unrelated app name that happens to match a query). Screened-out keywords stay in the agent's working set — they just don't clutter the curated hit list.

  • Stages: candidate → proposed → approved → scheduled → drafting → published → live, with content type (blog post / service page / local page), schedule, published URL, and per-channel distribution chips.
  • One master list. Agent research, operator-submitted keyword ideas, and the Hit List page all write into the same pipeline — a submitted idea shows up on the Hit List immediately as a candidate, not just once the agent acts on it.
  • Promote to hit list — a row action on the Saved Keywords tab (or from the Hit List tab directly) that moves a keyword into the build pipeline and queues it into the agent's working set.
  • Remove from hit list — a row action on the Hit List tab that resets a keyword's stage back to none and pulls it out of the agent's working set, without deleting the underlying research row. Use the Saved Keywords delete action instead to archive a keyword's research history entirely.
  • Manual pipeline correction — if a build genuinely published but the Hit List never picked it up, open the keyword in the Saved Keywords editor and use the Stage select and Published URL field to correct it by hand instead of waiting on support. Marking a keyword newly published/live this way stamps its publish date automatically, and the fix shows up on both the Saved Keywords and Hit List tabs right away.
  • Distribute fans a published keyword across channels (blog, GMB, Facebook/Instagram/LinkedIn/Pinterest, newsletter) using the client's connected accounts; unconnected channels show as skipped, not failed.
  • Autopilot (per agent, off by default) auto-promotes the strongest fresh candidates into the build pipeline within configured volume/difficulty/pace thresholds, instead of waiting for operator review.

Publishing or promoting a keyword to published/live auto-enrolls it in rank tracking by default. An hourly scheduled check keeps position history up to date automatically after that, so the maintenance watchers below always have fresh data to work from.

Maintenance Watchers

Once a keyword is published/live, the agent keeps watching it instead of moving on:

WatcherWhat It Catches
Hit-list decayPublished keywords whose ranking position dropped week-over-week, or that have sat 30+ days with no clicks and no progress
Index coveragePublished pages Google can't or won't index — Soft 404s, robots.txt blocks, crawled-but-not-indexed

Both watchers feed the same alert scan that already watches for position drops and traffic cliffs, so a maintenance campaign can be queued automatically when a published page needs attention — and that campaign is built to fix or refresh the specific flagged page rather than propose generic new content. Once a decay or index-coverage alert queues a campaign, it won't queue another one for the same condition for 7 days, since these are slow-moving issues that don't need a fresh campaign every scan cycle.

The index-coverage watcher's result also shows up directly on the Hit List row as a badge next to the published link (Indexed / Not indexed yet / the specific issue, e.g. Soft 404), so you don't have to wait for an alert to see it.

Triggering a rank check manually on a config tracking more than 15 keywords now starts it in the background instead of blocking the request — the page shows it as started and keeps polling until results are in, rather than risking a timeout on a long serial SERP run.

Budget & Safety

Launch safety boundaries protect against unbounded execution:

  • API responses redact WordPress, Rank Math, and DataForSEO secrets
  • Generic agent updates cannot overwrite runtime state, campaign history, budget config, alert config, or initial audit state
  • Budget and alert values are validated and bounded before they can affect a campaign
  • Unknown sub-agent names fail clearly instead of pretending an action ran
  • Full campaigns stop at cancellation-safe boundaries
  • Blog posts are queued as WordPress drafts through website execution, not published live by default
  • WordPress edits go through bounded website execution jobs with target constraints and preview metadata
  • Elementor smart edits remain widget-scoped and backup-aware

The SEO agent's detail header shows a running-cost stat (spend against budget) alongside the same in-place rename affordance available on other agents — see Creating & Configuring Agents.

Budget Controls

PUT /admin/seo/agents/:id/budget

Change action, token, cost, duration, and cooldown caps.

Alert Controls

PUT /admin/seo/agents/:id/alerts

Change alert thresholds only. This does not function as a scheduling endpoint.

Campaign Lifecycle

StepDescription
QueueAPI accepts the request, stores runtime state as queued
Lease & startWorker claims ownership, sets running, records heartbeat data
DecideSituation and strategy nodes choose the highest-value executable action
DispatchRuntime invokes the matching worker with resolved inputs
EvaluateResults recorded in action history and used for future strategy context
Continue or stopWorker loops for another action or completes the campaign
CancelQueued campaigns cancel immediately; running campaigns transition to cancelling and stop at next safe boundary

Operator API Reference

EndpointPurpose
POST /admin/seo/agents/:id/triggerRun a specific sub-agent or queue a full campaign
POST /admin/seo/agents/:id/campaignQueue a manual full campaign
POST /admin/seo/agents/:id/campaign/cancelRequest cancellation
GET /admin/seo/agents/:id/runtimeInspect current runtime state, current work, recent actions, audit trail
GET /admin/seo/agents/:id/campaignsInspect campaign history
GET /admin/seo/agents/:id/actionsInspect action history with pagination

WordPress & MCP Integration

  • WordPress REST writes and reads through the SEO WordPress connector
  • Rank Math and Yoast-compatible meta fields are sent with blog draft jobs
  • Rank Math redirects are supported when the site exposes the namespace
  • Elementor smart edits available through the WordPress connector with constrained edit behavior
  • Website execution previews and runs SEO-originated WordPress draft jobs
  • Client asset library references resolve through website asset consumers and upload into WordPress media
  • MCP WordPress and image-generation features can create or reference assets the SEO flow later uses for posts

Agent Model Provider

The SEO agent defaults to Gemini but can be switched per agency to OpenAI or Claude (Anthropic) at Admin → Config → LLMS. GLM (z.ai) is not offered for this role — a full campaign fires many calls in a time-boxed run, and GLM's reasoning latency risks a timeout. Grounded research calls (Google Search retrieval) stay pinned to Gemini regardless of the selected provider, since grounding is Gemini-native. Leave it on the default unless you have a specific reason to change it.

On this page