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:
- Queue — A campaign is queued by an admin trigger, manual request, or SEO reporting alert
- Lease & start — The worker heartbeat claims the campaign and sets runtime to
running - Situation analysis — Loads current domain state, reporting trends, previous actions, site context, and memory
- Action context — Builds the executable action catalog, verifying each action has real inputs (due keyword, target URL, audit findings)
- Strategy — Chooses one executable action or returns
nonewhen no safe action is ready - Sub-agent dispatch — The selected action runs with resolved inputs
- Website handoff — If the action changes site content, it hands off to website execution (blog drafts → WordPress draft jobs)
- Evaluation — Records results, updates keyword timestamps, appends action history, checks budget/duration/cancellation
- Loop or complete — The graph loops for another action or completes the campaign with a report
- Outcome measurement — Later reporting data is compared against baseline so the agent learns
- Alert scan — Continues watching for position drops, traffic cliffs, and striking-distance surges
Runtime States
| State | Meaning |
|---|---|
idle | No active campaign |
queued | Campaign accepted, waiting for worker |
running | Worker owns the lease, actively executing |
cancelling | Cancellation requested, stops at next safe boundary |
Only one active campaign per SEO agent at a time.
Sub-Agents
| Action | Worker | Purpose |
|---|---|---|
audit | Auditor | Refresh technical/content health and identify findings |
research | Researcher | Gather keyword, SERP, and competitor context |
topography | Topography | Build or refine topical clusters and site structure |
blog-write | Blog Writer | Produce or update informational content tied to executable keyword context |
money-page | Money Page | Improve high-intent pages tied to executable URL context |
technical-seo | Technical SEO | Apply or recommend technical fixes (requires completed audit with actionable findings) |
none | Strategy only | Explicitly 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
| Action | Intended Output |
|---|---|
audit | Audit record with score, findings, and summary of site health |
research | Keyword, SERP, and competitor research payload used for planning |
topography | Updated topical map or cluster structure |
blog-write | Content generation or update result tied to a specific keyword opportunity |
money-page | Page optimization result tied to a specific URL and commercial intent |
technical-seo | Technical 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
- Select a due keyword candidate (weighted by priority, ranking opportunity, intent, freshness)
- Skip keywords recently drafted to avoid repeated posts
- Build a content brief from cluster context, internal link opportunities, and SERP/research data
- Generate the blog draft, title, slug, meta title, meta description, FAQ/article schema, and review notes
- Queue a
WebsiteExecutionJobwithoperation: "write_entity",postType: "post",status: "draft" - Attach client asset reference as a WordPress featured image when
featuredAssetReforassetRefsare provided - Save keyword timestamps (
lastSelectedAt,lastDraftedAt) - 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
SeoKeywordrecords 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
noneand 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:
| Watcher | What It Catches |
|---|---|
| Hit-list decay | Published keywords whose ranking position dropped week-over-week, or that have sat 30+ days with no clicks and no progress |
| Index coverage | Published 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
| Step | Description |
|---|---|
| Queue | API accepts the request, stores runtime state as queued |
| Lease & start | Worker claims ownership, sets running, records heartbeat data |
| Decide | Situation and strategy nodes choose the highest-value executable action |
| Dispatch | Runtime invokes the matching worker with resolved inputs |
| Evaluate | Results recorded in action history and used for future strategy context |
| Continue or stop | Worker loops for another action or completes the campaign |
| Cancel | Queued campaigns cancel immediately; running campaigns transition to cancelling and stop at next safe boundary |
Operator API Reference
| Endpoint | Purpose |
|---|---|
POST /admin/seo/agents/:id/trigger | Run a specific sub-agent or queue a full campaign |
POST /admin/seo/agents/:id/campaign | Queue a manual full campaign |
POST /admin/seo/agents/:id/campaign/cancel | Request cancellation |
GET /admin/seo/agents/:id/runtime | Inspect current runtime state, current work, recent actions, audit trail |
GET /admin/seo/agents/:id/campaigns | Inspect campaign history |
GET /admin/seo/agents/:id/actions | Inspect 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.
