Question · SEO agent, AI & ML
Which AI models does the CMS use?
Answer
Claude drafts and classifies for the SEO agent (the models are set under Automation & AI → AI & drafts; empty uses the deployment's defaults). Gemini generates images when configured in Integrations. AI visibility asks the assistants you switch on.
Where to find it
This page of the admin: /admin/automation. Only admins (and read-only demo accounts) can open it.
Settings on this page
What each setting does and its default. Defaults only: the manual never shows the values saved on a site.
Data sources: Google properties
Which Google properties are read, how far back, and how long data is kept; DataForSEO for volume, difficulty, live rankings and backlinks.
| Setting | What it does | Default |
|---|---|---|
| Gsc Propertygoogle.gscProperty | sc-domain:example.com for a domain property, or the URL-prefix form with a trailing slash. Empty = SEO_GSC_PROPERTY. | empty |
| Ga4 Property Idgoogle.ga4PropertyId | Numeric GA4 property id (Admin → Property details). Empty = SEO_GA4_PROPERTY_ID. | empty |
| Search Typesgoogle.searchTypes | — | web |
| Url Inspection › Enabledgoogle.urlInspection.enabled | — | off |
| Url Inspection › Daily Limitgoogle.urlInspection.dailyLimit | Google allows 2,000 inspections per property per day; keep well below. | 200 |
| Page Speed › Enabledgoogle.pageSpeed.enabled | Needs PAGESPEED_API_KEY in the site's Secret for field (CrUX) data at a useful quota. | off |
Data sources: Sync and retention
Which Google properties are read, how far back, and how long data is kept; DataForSEO for volume, difficulty, live rankings and backlinks.
| Setting | What it does | Default |
|---|---|---|
| Trailing Dayssync.trailingDays | Recent days re-fetched on every sync: Search Console revises its last ~3 days. | 4 |
| Retention Monthssync.retentionMonths | Daily rows older than this are deleted. Year-over-year decay checks need at least 13. | 16 |
| Stale After Hourssync.staleAfterHours | After this long without a good sync, pages show “stale” and SeoDataStale fires. | 48 |
| Max Requests Per Runsync.maxRequestsPerRun | Hard cap on Google API calls per sync run. | 400 |
| Row Limitsync.rowLimit | — | 25000 |
Data sources: DataForSEO (pay as you go; credentials DATAFORSEO_LOGIN / DATAFORSEO_PASSWORD in the site's Secret)
Which Google properties are read, how far back, and how long data is kept; DataForSEO for volume, difficulty, live rankings and backlinks.
| Setting | What it does | Default |
|---|---|---|
| Enableddataforseo.enabled | Master switch. Nothing is bought while off or while the credentials are missing. | off |
| Location Codedataforseo.locationCode | Market for volume and rankings: 2840 United States, 2356 India, 2826 United Kingdom, 2276 Germany. | 2840 |
| Language Codedataforseo.languageCode | — | en |
| Monthly Budget Usddataforseo.monthlyBudgetUsd | Hard cap per calendar month (UTC), counted from the cost DataForSEO returns. 0 = buy nothing. | 5 |
| Keyword Metrics › Enableddataforseo.keywordMetrics.enabled | — | on |
| Keyword Metrics › Max Keywordsdataforseo.keywordMetrics.maxKeywords | Top Search Console queries by impressions (tracked keywords always included) that get volume and difficulty. | 1000 |
| Keyword Metrics › Refresh Daysdataforseo.keywordMetrics.refreshDays | A query's metrics are bought again only after this many days. | 30 |
| Rank Tracking › Enableddataforseo.rankTracking.enabled | — | on |
| Rank Tracking › Weekdaydataforseo.rankTracking.weekday | — | 3 |
| Rank Tracking › Hour Utcdataforseo.rankTracking.hourUtc | — | 5 |
| Rank Tracking › Depthdataforseo.rankTracking.depth | Results checked per tracked keyword; billed per 10. A keyword below this depth shows as not ranking. | 30 |
| Backlinks › Enableddataforseo.backlinks.enabled | The Backlinks API has its own DataForSEO subscription; switch on only once it is active. | off |
| Backlinks › Weekdaydataforseo.backlinks.weekday | — | 0 |
| Backlinks › Hour Utcdataforseo.backlinks.hourUtc | — | 5 |
Schedules: Schedules (UTC; weekday 0 = Sunday)
When the web worker runs each job (UTC). With SEO_ORCHESTRATOR=crewai the agent's CronJobs own the flow jobs instead.
| Setting | What it does | Default |
|---|---|---|
| Gsc Daily › Enabledschedules.gscDaily.enabled | — | on |
| Gsc Daily › Hour Utcschedules.gscDaily.hourUtc | — | 6 |
| Ga4 Daily › Enabledschedules.ga4Daily.enabled | — | on |
| Ga4 Daily › Hour Utcschedules.ga4Daily.hourUtc | — | 6 |
| Technical Weekly › Enabledschedules.technicalWeekly.enabled | — | on |
| Technical Weekly › Weekdayschedules.technicalWeekly.weekday | — | 1 |
| Technical Weekly › Hour Utcschedules.technicalWeekly.hourUtc | — | 3 |
| Recommendations Weekly › Enabledschedules.recommendationsWeekly.enabled | — | on |
| Recommendations Weekly › Weekdayschedules.recommendationsWeekly.weekday | — | 1 |
| Recommendations Weekly › Hour Utcschedules.recommendationsWeekly.hourUtc | — | 7 |
| Reports Weekly › Enabledschedules.reportsWeekly.enabled | — | on |
| Reports Weekly › Weekdayschedules.reportsWeekly.weekday | — | 1 |
| Reports Weekly › Hour Utcschedules.reportsWeekly.hourUtc | — | 8 |
| Reports Monthly › Enabledschedules.reportsMonthly.enabled | — | on |
| Reports Monthly › Day Of Monthschedules.reportsMonthly.dayOfMonth | — | 2 |
| Reports Monthly › Hour Utcschedules.reportsMonthly.hourUtc | — | 8 |
Scoring & rules: Scoring weights (relative; renormalised when an input is missing)
How recommendations are found and ranked (docs/seo/SCORING.md).
| Setting | What it does | Default |
|---|---|---|
| Search Opportunityweights.searchOpportunity | Demand involved (impressions, log-scaled). | 30 |
| Ranking Opportunityweights.rankingOpportunity | How close the page is to a better result. | 20 |
| Relevanceweights.relevance | How directly the site's own content is concerned. | 20 |
| Quality Gapweights.qualityGap | How far the current state is from good. | 15 |
| Trendweights.trend | Size of a decline (decay). | 10 |
| Effortweights.effort | Ease of the fix: cheap fixes score higher. | 5 |
Scoring & rules: Rule thresholds
How recommendations are found and ranked (docs/seo/SCORING.md).
| Setting | What it does | Default |
|---|---|---|
| Low Ctr Min Impressionsthresholds.lowCtrMinImpressions | A query needs at least this many impressions (28 days) before a low CTR counts. | 200 |
| Low Ctr Ratiothresholds.lowCtrRatio | Flag when CTR < expected CTR for the position × this ratio. | 0.6 |
| Striking Min Impressionsthresholds.strikingMinImpressions | — | 100 |
| Striking Position Minthresholds.strikingPositionMin | Striking-distance band: lowest average position. | 5 |
| Striking Position Maxthresholds.strikingPositionMax | Striking-distance band: highest average position. | 20 |
| Decay Min Clicksthresholds.decayMinClicks | Pages need at least this many clicks in the earlier window to be checked for decay. | 20 |
| Decay Drop Ratiothresholds.decayDropRatio | A click drop of this share (0.3 = 30 %) counts as decay. | 0.3 |
| Gap Min Impressionsthresholds.gapMinImpressions | Minimum demand for a content-gap recommendation. | 50 |
| Max Links Per Pagethresholds.maxLinksPerPage | Internal-link suggestions per article. | 5 |
| Band Highthresholds.bandHigh | Score at or above this is “high”. | 0.66 |
| Band Mediumthresholds.bandMedium | Score at or above this is “medium”. | 0.4 |
| Brand Termsthresholds.brandTerms | Queries containing these are excluded from low-CTR and gap rules. | jithendar |
Content & links: Internal linking limits (conservative by default)
Keyword opportunities, internal-linking limits and search-engine submission.
| Setting | What it does | Default |
|---|---|---|
| Enabledlinks.enabled | — | on |
| Max New Per Draftlinks.maxNewPerDraft | — | 3 |
| Words Per Linklinks.wordsPerLink | — | 250 |
| Min Words Betweenlinks.minWordsBetween | — | 100 |
| Max Inbound Per Target Per Runlinks.maxInboundPerTargetPerRun | — | 5 |
| Min Relevancelinks.minRelevance | — | 0.12 |
| Anchor Min Wordslinks.anchorMinWords | — | 2 |
| Anchor Max Wordslinks.anchorMaxWords | — | 6 |
| Auto › Enabledlinks.auto.enabled | — | on |
| Auto › Weekdaylinks.auto.weekday | — | 2 |
| Auto › Hour Utclinks.auto.hourUtc | — | 9 |
| Auto › Max Articles Per Runlinks.auto.maxArticlesPerRun | — | 5 |
| Auto › Max External Per Articlelinks.auto.maxExternalPerArticle | — | 2 |
| Auto › Cooldown Dayslinks.auto.cooldownDays | — | 30 |
| Check › Enabledlinks.check.enabled | — | on |
| Check › Weekdaylinks.check.weekday | — | 3 |
| Check › Hour Utclinks.check.hourUtc | — | 4 |
| Check › Max External Per Runlinks.check.maxExternalPerRun | — | 400 |
| Check › Recheck Dayslinks.check.recheckDays | — | 7 |
Content & links: Search-engine submission (kill switch: SEO_SUBMISSION_ENABLED)
Keyword opportunities, internal-linking limits and search-engine submission.
| Setting | What it does | Default |
|---|---|---|
| Index Nowsubmission.indexNow | — | on |
| Google Sitemapsubmission.googleSitemap | — | on |
| Url Inspectionsubmission.urlInspection | — | on |
| Inspection Delay Hourssubmission.inspectionDelayHours | — | 60 |
Content & links: Keyword opportunities
Keyword opportunities, internal-linking limits and search-engine submission.
| Setting | What it does | Default |
|---|---|---|
| Brand Regexkeywords.brandRegex | — | jithendar |
| Rising Min Growthkeywords.risingMinGrowth | — | 0.5 |
| Declining Positionskeywords.decliningPositions | — | 3 |
| Tracked Alert Positionskeywords.trackedAlertPositions | — | 3 |
| Classify With Llmkeywords.classifyWithLlm | — | on |
| Cluster Similaritykeywords.clusterSimilarity | — | 0.5 |
AI & drafts: LLM enrichment (optional; off by default)
Claude drafting (always stops at human review), the optional explanation model, and AI visibility (are AI assistants citing the site?).
| Setting | What it does | Default |
|---|---|---|
| Enabledllm.enabled | — | off |
| Providerllm.provider | — | openai |
| Modelllm.model | — | empty |
| Base Urlllm.baseUrl | Only for OpenAI-compatible endpoints (e.g. Ollama in the cluster). | empty |
| Regionllm.region | — | us-east-1 |
| Timeout Msllm.timeoutMs | — | 30000 |
| Max Output Tokensllm.maxOutputTokens | — | 900 |
| Daily Request Limitllm.dailyRequestLimit | Requests per day for the optional explanation model; 0 = none. | 100 |
AI & drafts: Claude drafts (automation stops at “ready for review”; empty models/budget = environment defaults)
Claude drafting (always stops at human review), the optional explanation model, and AI visibility (are AI assistants citing the site?).
| Setting | What it does | Default |
|---|---|---|
| Enableddrafts.enabled | — | on |
| Draft Modeldrafts.draftModel | — | empty |
| Classify Modeldrafts.classifyModel | — | empty |
| Monthly Budget Usddrafts.monthlyBudgetUsd | 0 = SEO_LLM_MONTHLY_BUDGET_USD (default $15). The environment value is a ceiling this cannot raise. | 0 |
| Effortdrafts.effort | — | medium |
| Max Output Tokensdrafts.maxOutputTokens | — | 16000 |
| Max Rewrite Ratiodrafts.maxRewriteRatio | A draft may change at most this share of the article's text. | 0.25 |
| Auto Eligible › Title metadrafts.autoEligible.title_meta | — | on |
| Auto Eligible › Striking expansiondrafts.autoEligible.striking_expansion | — | on |
| Auto Eligible › Freshnessdrafts.autoEligible.freshness | — | on |
| Auto Eligible › Internal linksdrafts.autoEligible.internal_links | — | on |
| Auto Eligible › Alt textdrafts.autoEligible.alt_text | — | on |
| Auto Eligible › Faq headingsdrafts.autoEligible.faq_headings | — | on |
| Auto Eligible › New articledrafts.autoEligible.new_article | — | off |
| News › Enableddrafts.news.enabled | — | on |
| News › Categoriesdrafts.news.categories | — | title_meta, alt_text, internal_links |
| Weekly › Enableddrafts.weekly.enabled | — | on |
| Weekly › Weekdaydrafts.weekly.weekday | — | 2 |
| Weekly › Hour Utcdrafts.weekly.hourUtc | — | 4 |
| Weekly › Max Articlesdrafts.weekly.maxArticles | — | 20 |
| Digest › Enableddrafts.digest.enabled | — | on |
| Digest › Weekdaydrafts.digest.weekday | — | 6 |
| Digest › Hour Utcdrafts.digest.hourUtc | — | 5 |
| Digest › Recipientsdrafts.digest.recipients | — | none |
AI & drafts: AI visibility (weekly prompts to AI assistants with web search; API keys only in the site's Secret)
Claude drafting (always stops at human review), the optional explanation model, and AI visibility (are AI assistants citing the site?).
| Setting | What it does | Default |
|---|---|---|
| EnabledaiVisibility.enabled | Master switch for the weekly run. Each assistant also needs its switch below and its API key. | off |
| WeekdayaiVisibility.weekday | — | 4 |
| Hour UtcaiVisibility.hourUtc | — | 6 |
| Max PromptsaiVisibility.maxPrompts | — | 25 |
| Monthly Budget UsdaiVisibility.monthlyBudgetUsd | Hard cap per calendar month (UTC) across all assistants; the run stops before a call that would cross it. | 10 |
| Cost Per Answer UsdaiVisibility.costPerAnswerUsd | ChatGPT, Perplexity and Gemini do not return a price: each answer is counted at this estimate. Set it from their pricing. | 0.03 |
| Brand NamesaiVisibility.brandNames | Names that count as a mention besides the site name and host, e.g. the author's name. | none |
| Providers › ClaudeaiVisibility.providers.claude | — | on |
| Providers › ChatgptaiVisibility.providers.chatgpt | — | off |
| Providers › PerplexityaiVisibility.providers.perplexity | — | off |
| Providers › GeminiaiVisibility.providers.gemini | — | off |
| Providers › Google ai overviewaiVisibility.providers.google_ai_overview | The AI Overview on Google's results page, read through DataForSEO (needs its credentials; billed by DataForSEO, counted here). | off |
| Models › ClaudeaiVisibility.models.claude | Anthropic model id (web search needs a current model). | claude-opus-5-5 |
| Models › ChatgptaiVisibility.models.chatgpt | OpenAI model id with web search support; required to switch ChatGPT on. | empty |
| Models › PerplexityaiVisibility.models.perplexity | Perplexity Sonar model id (sonar, sonar-pro). | sonar |
| Models › GeminiaiVisibility.models.gemini | Gemini model id with Google Search grounding; required to switch Gemini on. | empty |
Crawler: Technical crawler
Limits for the technical SEO crawl of this site.
| Setting | What it does | Default |
|---|---|---|
| Requests Per Secondcrawler.requestsPerSecond | Politeness limit against your own site. | 1 |
| Max Pagescrawler.maxPages | — | 500 |
| Timeout Mscrawler.timeoutMs | — | 10000 |
| Max Bytescrawler.maxBytes | — | 2000000 |
| Max Redirectscrawler.maxRedirects | — | 5 |
Reports: Reports (email only after recipients are set and email is enabled)
Weekly and monthly report e-mail.
| Setting | What it does | Default |
|---|---|---|
| Email Enabledreports.emailEnabled | — | off |
| Recipientsreports.recipients | — | none |