Skip to content

MCP and API

MCP and API tool reference

Every tool the SEOForge MCP server offers, grouped by toolset, with the arguments each one takes.

Tools fall into two groups: the core tools, which are always loaded, and the toolset tools, which you choose with ?toolsets= on the MCP server URL.

Core tools#

These are always available over MCP, whatever toolsets you load. Over REST, each one has its own endpoint, listed in the REST API reference.

Read#

ToolWhat it returns
list_projectsYour projects and their IDs. Start here
get_project_overviewOne project with article counts by status and tracked keyword count
get_project_settingsBrand, audience, tone of voice and linking rules
list_articlesArticles, filtered by status, 25 at a time (up to 100)
get_articleOne article, including its full Markdown content and meta tags
get_article_performanceGoogle clicks, impressions, CTR and position for your published articles. Accepts compare_to: previous_period or previous_year
get_search_trafficSite-wide Search Console trend, top pages and top queries. Defaults to the last 90 days
get_page_queriesThe search queries one URL ranks for
get_analytics_overviewGoogle Analytics sessions, engagement, key events and revenue over time
get_landing_pagesAnalytics per landing page. Defaults to organic search traffic
get_traffic_sourcesWhere visitors come from
get_key_eventsConversions by event
get_audienceCountries, devices and other visitor details
get_realtimeVisitors in the last 30 minutes
list_tracked_keywordsYour Rank Tracker keywords and their latest positions
get_keyword_rank_historyWeekly positions for one keyword, up to 52 checks
get_content_planContent plan items, filtered by status and date
get_jobThe status of a long-running job, such as article generation

Write#

These need a Read & write key.

ToolWhat it does
add_content_plan_itemAdds a keyword to the content plan, with an optional title, date, priority (0–100), notes and length
update_content_plan_itemChanges a plan item. Status can be set to planned or skipped
generate_articleStarts writing an article and returns a job_id. Counts toward your monthly articles
update_articleEdits an article's content, title, meta title or meta description. The previous version is saved, and the live page doesn't change until you republish
add_tracked_keywordsAdds up to 100 keywords to the Rank Tracker. Defaults to United States, English, desktop
remove_tracked_keywordStops tracking a keyword. Its rank history is kept

Toolset tools#

Each tool below can also be called over REST with POST /api/v1/tools/{name}, using the same arguments as a JSON body. Most data tools also accept location, language, device, limit, offset, max_age and fresh; those aren't repeated in each list.

content

Articles, content plan and writing actions.Loaded by default

refresh_articleRead & write key

Rewrite an existing article as a new draft revision (async → job_id; check with get_job, usually 1-3 minutes). scope: full (improve the whole article), sections (change only what the plan/instructions say, keep the rest) or meta (title, meta title and meta description only). Uses the refresh plan from plan_content_refresh and the project's brand, tone and linking rules; keeps images, videos and markdown structure, never invents links. The previous content is saved as a version first. Publishing stays separate: the live page is unchanged until the article is republished.

Arguments (4)
  • article_id string, required — Article ID from list_articles
  • refresh_plan_id string — refresh_plan_id from plan_content_refresh
  • scope full | sections | meta — Default full
  • instructions string — Extra instructions (e.g. content to merge in from consolidation_plan)
generate_schemaRead & write key

Build JSON-LD structured data for an article from its data (no AI): BlogPosting/Article with headline, description, image, dates, author and publisher, BreadcrumbList (when published), FAQPage (from an FAQ section) and VideoObject (from embedded YouTube videos). Saves it on the article in SEOForge and returns a ready <script> tag. SEOForge's publishing integrations don't output it yet, so add the tag to the page (or an SEO plugin) yourself.

Arguments (5)
  • article_id string, required — Article ID from list_articles
  • types array — Types to include (default: BlogPosting + BreadcrumbList, plus FAQPage / VideoObject when found)
  • author_name string — Author shown as a Person (default: the brand as Organization)
  • author_url string — Author profile page URL
  • save boolean — Save on the article (default true); false only returns it

insights

Analyses that combine data and recommend actions (start here).Loaded by default

find_striking_distance

Queries close to page 1 or the top 3 (average position ~8-20 with real impressions), ranked by clicks to gain at position 3. Each finding names the ranking page (and SEOForge article when it's ours); recommended_actions point to create_content_brief and update_article. From Search Console, no data cost.

Arguments (6)
  • days number — Length of the period in days (default 28; 90 for cannibalization)
  • end_date string — Last day of the period, YYYY-MM-DD (default: the latest day with Search Console data)
  • url_contains string — Only pages whose URL contains this text, e.g. '/blog/'
  • min_position number — Lowest average position to include (default 8)
  • max_position number — Highest average position to include (default 20)
  • min_impressions number — Minimum impressions in the period (default 1.5 × days, at least 10)
find_declining_pages

Pages losing clicks or average position vs the previous period (or the same period last year), biggest loss first, with a likely cause (lost rankings, lower demand, lower CTR) and the queries that dropped. Refresh candidates → plan_content_refresh / refresh_article. From Search Console, no data cost.

Arguments (6)
  • days number — Length of the period in days (default 28; 90 for cannibalization)
  • end_date string — Last day of the period, YYYY-MM-DD (default: the latest day with Search Console data)
  • url_contains string — Only pages whose URL contains this text, e.g. '/blog/'
  • compare_to previous_period | previous_year — Default previous_period
  • min_clicks number — Minimum clicks in the previous period (default 10)
  • min_drop_pct number — Minimum click drop as a fraction, e.g. 0.2 = 20% (default 0.2)
find_low_ctr_pages

Pages that get impressions but far fewer clicks than their positions usually earn (CTR-by-position curve), with the queries behind the gap. When a stored SERP exists for those queries, says whether AI Overviews, featured snippets, ads, local packs or shopping results likely explain it. Title/meta fixes → suggest_titles / update_article. From Search Console, no data cost.

Arguments (5)
  • days number — Length of the period in days (default 28; 90 for cannibalization)
  • end_date string — Last day of the period, YYYY-MM-DD (default: the latest day with Search Console data)
  • url_contains string — Only pages whose URL contains this text, e.g. '/blog/'
  • min_impressions number — Minimum page impressions in the period (default 200)
  • max_ctr_ratio number — Flag pages whose clicks are at most this share of expected (default 0.5)
find_cannibalization

Queries where two or more of our URLs each get a real share of impressions (they compete with each other), with severity and the page pairs that clash most → consolidation_plan. From Search Console, no data cost.

Arguments (5)
  • days number — Length of the period in days (default 28; 90 for cannibalization)
  • end_date string — Last day of the period, YYYY-MM-DD (default: the latest day with Search Console data)
  • url_contains string — Only pages whose URL contains this text, e.g. '/blog/'
  • min_impressions number — Minimum query impressions in the period (default 50)
  • min_share number — Share of a query's impressions a page needs to count as competing (default 0.1)
analyze_serp

What it takes to rank for a keyword, and whether we can: intent, SERP features (AI Overview, featured snippet, People Also Ask...), dominant content type/format, typical word count of the top pages, each top-10 domain's strength vs ours, and a 0-100 rankability score with reasons. About $0.03-0.05 uncached (1 SERP, keyword metrics, backlink ranks, up to 10 page parses).

Arguments (5)
  • keyword string, required — Target keyword
  • analyze_pages number — Top results to parse for word counts (default 5; 0 skips)
  • load_ai_overview boolean — Wait for Google's AI Overview (default true, +$0.002)
  • domain string — Domain to compare (default: the project's website)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
create_content_brief

Brief for an article targeting a keyword, from the top-ranking pages: target length, outline (H2/H3 sections most top pages cover), terms they use, questions to answer (People Also Ask + question keywords), related keywords, and our articles to link to. Includes writer_notes ready for generate_article / add_content_plan_item.

Arguments (3)
  • keyword string, required — Target keyword
  • pages number — Top results to parse (default 5)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
score_content

Score one of our articles (0-100) against what ranks for its keyword: sections, terms and questions the top pages cover that it doesn't, and length vs the top pages. Builds the brief first (same cost as create_content_brief; cached). Fixes → update_article.

Arguments (6)
  • article_id string — Article ID from list_articles
  • url string — Live URL of an article published through SEOForge (instead of article_id)
  • content string — Markdown to score instead of a saved article (needs keyword)
  • keyword string — Keyword to score against (default: the article's primary keyword)
  • pages number — Top results to compare with (default 5)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
cluster_keywords

Group keywords that belong on the same page: keywords whose Google top 10 share at least `threshold` URLs. Each cluster has a primary keyword, total volume and the page to target (our ranking page, an existing article, a planned item, or new). One SERP per keyword (max 50, ~$0.002 each uncached); use dry_run first.

Arguments (3)
  • keywords array, required — Keywords to cluster (2-50)
  • threshold number — Shared top-10 URLs needed to group keywords (default 3)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
prioritize_keywords

Which keywords first: opportunity score from volume × CTR gain at a reachable position × ease (difficulty vs our domain strength, current rankings from the rank tracker and Search Console) × intent fit. Returns estimated extra clicks per month per keyword.

Arguments (4)
  • keywords array, required — Keywords to rank (max 200)
  • intents array — Intents that fit the site (default informational + commercial)
  • domain string — Domain whose strength to use (default: the project's website)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
traffic_potential

Traffic you could get from ranking #1 for a keyword, beyond its own volume: estimated monthly organic traffic of the top-ranking page(s) across all their keywords, plus the parent topic (the top page's biggest keyword). 1 SERP + 1 ranked-keywords call per page.

Arguments (3)
  • keyword string, required — Target keyword
  • pages number — Top results to measure (default 1)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
build_content_planWrites only with dry_run: false

What to write next: keyword ideas from seeds and/or the keyword gap vs competitors → drop what we already have or planned → prioritize → cluster (one item per cluster) → proposed plan items with title, type, supporting keywords, priority and dates. dry_run (default true) only proposes; dry_run: false adds them via add_content_plan_item (read & write key). Pass `items` from a dry run to add exactly those with no data cost. estimate_only returns the USD estimate without calling providers.

Arguments (13)
  • seeds array — Topics / seed keywords
  • competitors array — Competitor domains for the keyword gap (max 3)
  • max_items number — Plan items to propose (default 10)
  • min_volume number — Minimum monthly searches
  • max_difficulty number — Maximum keyword difficulty
  • intents array — Intents that fit the site (default informational + commercial)
  • cluster boolean — Group candidates by SERP overlap (default true; costs one SERP per candidate clustered)
  • max_serp number — Candidates to cluster, i.e. SERPs fetched (default 20)
  • start_date string — First scheduled date (default tomorrow)
  • per_week number — Items per week when scheduling (default 2)
  • items array — Exact items to add (e.g. from a dry run); skips the analysis
  • estimate_only boolean — Only return the USD estimate
  • dry_run boolean — Default true: propose without writing. false adds the items (needs the write scope)
topic_map

Full map of a topic: keyword ideas clustered into pillar and supporting pages, which ones we rank for / have an article for / planned / miss, and how the top competitors cover them. Fetches max_serp SERPs (default 20); use dry_run first. Missing clusters → build_content_plan.

Arguments (7)
  • topic string, required — Topic or seed keyword
  • max_keywords number — Keyword ideas to pull (default 50)
  • max_serp number — Top keywords by volume to cluster, one SERP each (default 20)
  • threshold number — Shared top-10 URLs to group keywords (default 3)
  • min_volume number
  • domain string — Our domain (default: the project's website)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
find_serp_feature_opportunities

Keywords where we rank in the top 10 but don't own a SERP feature (featured snippet, People Also Ask, AI Overview citation, videos, images, top stories), with the format change that could win it. From stored SERPs for tracked and Search Console keywords (free); fetch_missing pulls fresh SERPs for keywords without one (costs, use dry_run).

Arguments (4)
  • max_position number — Only keywords where we rank at or above this (default 10)
  • min_impressions number — Search Console queries need this many impressions in 28 days (default 20)
  • fetch_missing number — Fetch up to this many SERPs for keywords with no stored SERP (default 0)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
suggest_titles

Title and meta description options for a page, built from the queries it gets Search Console impressions for and the titles that rank for its top query. Shows which queries the current title misses. Feeds update_article (meta_title / meta_description).

Arguments (5)
  • article_id string — Article ID
  • url string — Page URL (instead of article_id)
  • include_serp boolean — Look at ranking titles for the top query (default true, one SERP ~$0.002)
  • days number — Search Console window (default 90)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
find_competitors

Who the project really competes with in Google: domains ranking across its tracked and Search Console keywords (or, without keywords, organic competitors of its domain), split into business competitors and content sites (publishers, forums, directories/review sites, marketplaces, reference, social/video) with the signals behind each call. recommended_actions → keyword_gap, backlink_gap, broken_link_opportunities. DataForSEO Labs, ~$0.02.

Arguments (4)
  • keywords array — Keywords to compare on (default: tracked + Search Console keywords)
  • source keywords | domain | both — keywords: SERP competitors on our keywords; domain: Labs competitors of our domain (default keywords when there are 3+)
  • include_content_sites boolean — Also list content sites (default true, up to 15)
  • dry_run boolean — Return a USD cost estimate without calling the data provider
keyword_gap

Keywords competitors rank for that we don't (missing), or where a competitor is on page 1 well ahead of us (behind), scored 0-100 (volume, difficulty, how many competitors rank, intent) and grouped into topic clusters. Competitor-branded keywords are left out by default. recommended_actions → build_content_plan, add_content_plan_item, create_content_brief. DataForSEO Labs, one or two calls per competitor (dry_run for an estimate).

Arguments (7)
  • competitors array — Competitor domains (default: the project's saved competitors, else the top business competitors found in search)
  • include_worse boolean — Also find keywords where we rank but a competitor is on page 1 at least 3 places ahead (default true)
  • min_volume number — Minimum monthly search volume
  • include_branded boolean — Keep keywords naming a competitor's brand (default false)
  • view clusters | keywords — Return topic clusters (default) or individual keywords
  • pool number — Keywords fetched per competitor, by volume (default 200)
  • dry_run boolean — Return a USD cost estimate without calling the data provider
find_unlinked_mentions

Pages that mention the brand but don't link to the project's site, by authority (negative or spammy mentions ranked lower) - the easiest link requests. Uses DataForSEO Content Analysis and Backlinks, ~$0.08. Outreach itself is manual.

Arguments (4)
  • brand string — Brand name to search for (default: the project's brand name)
  • include_domain_linked boolean — Also show pages on sites that link to us from another page (default false)
  • pool number — Mentions fetched (one per domain, by domain rank; default 100)
  • dry_run boolean — Return a USD cost estimate without calling the data provider
project_report

What happened this week/month and what should we do? Search Console clicks and impressions vs the previous period, rank changes (entered/left top 10, biggest moves), Google Analytics sessions and key events, alerts, annotations, Google updates, striking-distance and declining pages, and the top 5 actions as tool calls. No data cost.

Arguments (1)
  • period week | month — Default week (7 days); month = 28 days
plan_content_refresh

What to change in an article to win back or gain rankings: queries it lost and queries it gets but doesn't cover (Search Console), how the SERP changed since publishing (stored snapshots), sections / questions / terms the top results cover that it doesn't (create_content_brief), dated years and statistics, broken outbound links, and title/meta ideas. Saves the plan and returns refresh_plan_id for refresh_article. Paid parts (brief ~$0.02-0.03, link checks ~$0.000125 each) are cached; dry_run first.

Arguments (9)
  • article_id string — Article ID from list_articles
  • url string — Live URL of an article published through SEOForge (instead of article_id)
  • keyword string — Keyword to compare against (default: the article's primary keyword)
  • days number — Search Console window, compared with the window before (default 90)
  • include_brief boolean — Compare with the top results (default true; paid)
  • pages number — Top results to parse for the brief (default 5)
  • check_links boolean — Check outbound links for errors (default true; paid, tiny)
  • max_links number — Outbound links to check (default 25)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
check_content_quality

Does an article show Google's quality signals? Checks author byline, sources cited, broken outbound links, internal links, freshness of dates and statistics, structure, readability (Flesch), image alt text, structured data and meta tags, on the SEOForge draft and (when published) the live page. Returns pass/warn/fail per check, a score, and fixes. Live page analysis and link checks cost ~$0.003 or less (cached).

Arguments (6)
  • article_id string — Article ID from list_articles
  • url string — Live URL of an article published through SEOForge (instead of article_id)
  • analyze_live boolean — Also analyze the live page (default true when published)
  • check_links boolean — Check outbound links for errors (default true)
  • max_links number — Outbound links to check (default 25)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
find_zombie_pages

Pages with almost no search traffic over 6+ months (Search Console, plus SEOForge articles Google never showed), each with a verdict: improve, merge (into a similar stronger page), redirect (similar page and it has backlinks) or noindex, and the reason. Uses internal links from the latest site audit when there is one; include_backlinks adds DataForSEO backlink counts (paid, dry_run first).

Arguments (10)
  • days number — Window (default 180)
  • max_clicks number — A page is a zombie at or below this many clicks (default about 1 per month)
  • min_age_days number — Skip SEOForge articles published more recently (default 90)
  • compare_previous boolean — Check whether pages had traffic in the window before (default true)
  • include_backlinks boolean — Fetch backlinks per page from DataForSEO (default false; paid)
  • max_backlink_checks number — Pages to check backlinks for (default 50)
  • include_internal_links boolean — Use internal links from the latest site audit (default true)
  • verdict improve | merge | redirect | noindex — Only this verdict
  • url_contains string — Only pages whose URL contains this
  • dry_run boolean — Return the estimated cost in USD without calling data providers
consolidation_plan

How to merge cannibalizing and weak pages: groups of pages (from find_cannibalization and find_zombie_pages, or the urls you pass), which page to keep, which to merge and 301 or to differentiate, a redirect map, and the queries and sections to carry over into the kept page (→ refresh_article). Backlinks per URL from DataForSEO (default on, ~$0.04; dry_run first).

Arguments (5)
  • urls array — Pages to consolidate (default: found automatically)
  • days number — Search Console window (default 90)
  • include_zombies boolean — Also group low-traffic pages with a similar stronger page (default true)
  • include_backlinks boolean — Backlinks per URL (default true; paid)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
measure_change_impact

Did our changes work? For article changes made through the API (update_article, refresh_article, generate_schema; see api_changes), compares the page's Search Console clicks, impressions and position in equal windows before and after the change went live (its next publish), relative to the whole site's trend, and summarizes which kinds of change pay off. Also shows site-wide before/after around annotations. Free.

Arguments (5)
  • article_id string — Only this article's changes
  • window_days number — Days before and after (default 28)
  • since string — Changes made on/after this date (default one year back)
  • change_types array — Only these actions, e.g. ['refresh_article']
  • include_annotations boolean — Also measure site-wide changes around annotations (default true)
content_roi

Which articles and content types pay off? Per SEOForge article: Search Console clicks, traffic value (clicks × keyword CPC from DataForSEO, cached 30 days), Google Analytics organic sessions, key events and revenue, and ROI when you pass cost_per_article; plus totals per content type and topic. CPCs cost ~$0.01-0.08 uncached; dry_run first, or include_value: false for free data only.

Arguments (5)
  • days number — Window (default 90)
  • cost_per_article number — Production cost per article in USD, for ROI
  • include_value boolean — Value clicks at their keywords' CPC (default true; paid)
  • max_keywords number — Top queries to price (default 200)
  • dry_run boolean — Return the estimated cost in USD without calling data providers
find_indexing_issues

Which pages aren't in Google, and why. Inspects a capped set of URLs with Search Console URL Inspection (URLs you pass, articles published in the last 30 days, pages that lost traffic, then top pages), and reports unindexed pages with Google's reason, Google-chosen canonical mismatches, sitemap URLs that redirect/404, sitemap errors and crawl-level redirects/non-indexable pages from the latest site audit. recommended_actions → submit_sitemap, internal_link_suggestions, update_article. Free (Search Console quota: 2,000 inspections/day, cached 3 days); dry_run previews the URL list.

Arguments (5)
  • urls array — Specific URLs to inspect first
  • max_inspections number — Max URLs to inspect in this call (default 25)
  • new_days number — Articles published in this many days count as new (default 30)
  • include_audit boolean — Also report crawl redirects / 4xx / non-indexable pages from the latest site audit (default true)
  • dry_run boolean — Only list the URLs that would be inspected and today's quota
core_web_vitals_priorities

Which slow pages cost the most traffic. Checks the top pages by Search Console clicks against real-user Core Web Vitals (CrUX: LCP, INP, CLS), runs Lighthouse on failing or no-data pages, and returns failing pages ranked by clicks × severity, failing templates (by URL section) and the most common Lighthouse issues. Lighthouse runs are paid (~$0.004 each, capped by lab_pages); use dry_run for the estimate.

Arguments (5)
  • max_pages number — Top pages by clicks to check (default 10)
  • lab_pages number — Max Lighthouse lab runs (default 3; 0 = field data only)
  • form_factor phone | desktop — Default phone
  • days number — Search Console period for traffic, in days (default 28)
  • dry_run boolean — Return the pages and the cost estimate without calling providers
check_structured_data

Is our schema markup valid, and which rich-result types are missing? Validates JSON-LD/microdata from the latest site audit and reads Google's detected rich results (URL Inspection) for a capped set of pages (URLs you pass, crawled pages with markup errors, recent SEOForge articles, top pages). Returns errors per page and expected-but-missing types (Article, author, BreadcrumbList, VideoObject, Organization) → generate_schema. Free.

Arguments (5)
  • urls array — Specific URLs to check first
  • max_pages number — Max pages to check (default 10)
  • inspect boolean — Also use Google's URL Inspection rich-result data (default true; uses quota for uncached URLs)
  • audit_id string — Audit ID from start_site_audit (default: the project's latest audit)
  • days number — Search Console period for picking top pages (default 28)
check_hreflang

Are language/country versions set up correctly? From the latest site audit's hreflang tags: invalid language/region codes, missing return links, hreflang pointing to redirected, broken or non-canonical URLs, missing self-references and conflicting codes. Needs a site audit (start_site_audit); no extra data cost.

Arguments (2)
  • audit_id string — Audit ID from start_site_audit (default: the project's latest audit)
  • max_links number — Max hreflang links to read from the crawl (default 5000)

monitoring

Alerts, annotations, rank changes, reports.Add with ?toolsets=monitoring

explain_rank_change

Why did we move for this keyword? Compares the stored Google SERP before and after (who entered/left the top 10, new SERP features, our URL switching, how much the whole SERP moved) and lines it up with our change log, annotations, confirmed Google updates and backlink changes. Returns likely_causes and recommended_actions. Uses stored rank-tracker / serp_search snapshots (free); include_backlinks adds DataForSEO backlink history (~$0.04).

Arguments (4)
  • keyword string, required — The keyword (tracked, or searched with serp_search for this project)
  • date_from string — Compare from the snapshot on/before this date (default: the second-latest snapshot)
  • date_to string — Compare to the latest snapshot on/before this date (default: the latest)
  • include_backlinks boolean — Also fetch backlink history from DataForSEO (paid)
serp_volatility

Is the whole SERP shaking (algorithm update) or just us? Volatility (0-100) per tracked keyword between consecutive weekly snapshots, by date and project-wide, with a verdict per keyword (serp_wide_move, just_us, ...) and overlapping Google updates. Free: uses stored rank-tracker snapshots.

Arguments (2)
  • days number — Look-back window in days (default 30)
  • keywords array — Only these tracked keywords
algorithm_update_impact

How did a Google core/spam update affect us? Search Console clicks and positions in equal windows before the rollout and after it ended: verdict, winners and losers by page, by site section and by query type (branded, question, long/short tail), plus tracked keyword moves. Defaults to the latest confirmed core update (list_google_updates). No data cost.

Arguments (5)
  • update_id string — id from list_google_updates
  • name string — Or part of the update's name, e.g. 'March 2026 core'
  • start_date string — Or a custom rollout start
  • end_date string — Custom rollout end (with start_date)
  • window_days number — Days compared on each side (default 14)
competitor_content_watch

What are competitors publishing, and is it ranking? Per competitor (project competitors or the ones given, max 5): pages that newly entered their top pages by traffic since the last run, pages gaining keywords, and newly ranking keywords, flagged when our content plan or articles already cover them. Stores a snapshot each run (first run = baseline). DataForSEO Labs, ~$0.03 per competitor; dry_run shows the estimate.

Arguments (3)
  • competitors array — Competitor domains (default: the project's saved competitors)
  • pages number — Top pages to compare per competitor (default 100)
  • dry_run boolean — Only estimate the cost
audit_priorities

Which technical issues matter most? Takes the latest site audit's issues (start_site_audit) and ranks them by the Search Console clicks and impressions of the pages they affect, with the top affected pages and the tool to fix each.

Arguments (3)
  • audit_id string — Audit id (default: the latest)
  • max_issues number — Issues to examine, most severe first (default 10)
  • days number — Search Console window for page traffic (default 28)
add_annotationRead & write key

Add a dated note to the project's timeline (e.g. 'migrated to new theme', 'started link campaign') so explain_rank_change, algorithm_update_impact and project_report can take it into account.

Arguments (3)
  • text string, required — What happened
  • date string — When it happened (default today)
  • source user | agent — Who is adding it (default agent)
list_annotations

Notes on the project's timeline, newest first; optionally with the API change log and Google updates in the same range.

Arguments (4)
  • date_from string — From this date
  • date_to string — To this date
  • include_changes boolean — Also list changes made through the API (api_changes)
  • include_google_updates boolean — Also list Google updates in the range
create_alertRead & write key

Create an alert rule, checked after each data refresh (hourly). Types: clicks_drop (Search Console clicks in the last 7 days fell by at least threshold % vs the 7 days before; default 20 percent); rank_drop (A tracked keyword lost at least threshold positions (or fell out of the top 100) in its latest check; default 5 positions); keyword_lost_top10 (At least threshold tracked keywords left the top 10 in their latest check; default 1 keywords); new_lost_backlinks (Referring domains changed by at least threshold (gained or lost) between the last two backlink snapshots; default 5 referring domains); indexing_issue (The latest site audit has at least threshold more pages with critical issues (broken, 4xx/5xx, non-indexable, redirect loops) than the previous one; default 1 pages). Delivered by email (to a project member), Slack incoming webhook or a JSON webhook (public https only).

Arguments (5)
  • type clicks_drop | rank_drop | keyword_lost_top10 | new_lost_backlinks | indexing_issue, required
  • threshold number — See type (default per type)
  • keyword string — rank_drop / keyword_lost_top10: only this tracked keyword
  • channel email | slack | webhook, required — email (a project member's address), slack (incoming webhook URL) or webhook (https URL that receives JSON)
  • target string, required — Email address, https://hooks.slack.com/... URL, or public https webhook URL
list_alerts

The project's alert rules (targets masked) and the available alert types.

delete_alertRead & write keyDeletes data

Delete an alert rule (its past events are deleted with it).

Arguments (1)
  • alert_id string, required — id from list_alerts
list_alert_events

Alerts that fired, newest first, with details and delivery status.

Arguments (2)
  • alert_id string — Only this rule's events
  • since string — Only events on/after this date
schedule_reportRead & write key

Send project_report every week (Mondays) or month (the 1st), after 08:00 UTC, by email (to a project member), Slack incoming webhook or a JSON webhook.

Arguments (3)
  • frequency weekly | monthly — Default weekly
  • channel email | slack | webhook, required — email (a project member's address), slack (incoming webhook URL) or webhook (https URL that receives JSON)
  • target string, required — Email address, https://hooks.slack.com/... URL, or public https webhook URL
list_scheduled_reports

The project's scheduled reports (targets masked), with when each was last sent and any delivery error.

delete_scheduled_reportRead & write keyDeletes data

Stop and delete a scheduled report.

Arguments (1)
  • schedule_id string, required — id from list_scheduled_reports
list_google_updates

Confirmed Google Search ranking updates (core and spam) from the Google Search Status Dashboard, newest first, with rollout start/end. Use an id with algorithm_update_impact.

Arguments (3)
  • type core | spam | other — Default core + spam
  • since string — Only updates starting on/after this date
  • include_other boolean — Also crawling/indexing/serving incidents

indexing

Google indexing, sitemaps and Core Web Vitals.Add with ?toolsets=indexing

inspect_url

Google's view of one of the project's URLs (Search Console URL Inspection): indexed or not and why, last crawl, Google-chosen vs declared canonical, rich results detected. Cached for 3 days; Google allows 2,000 inspections per property per day.

Arguments (1)
  • url string, required — A URL in the project's Search Console property
list_sitemaps

Sitemaps Google Search Console knows for the project: last submitted and downloaded, errors, warnings and URL counts.

submit_sitemapRead & write key

Submit or resubmit a sitemap to Google Search Console so Google recrawls it (e.g. after publishing or updating articles). Needs a read & write API key.

Arguments (1)
  • sitemap_url string, required — Absolute sitemap URL in the project's property, e.g. https://example.com/sitemap.xml
get_core_web_vitals

Real-user Core Web Vitals (LCP, INP, CLS, plus FCP and TTFB) at the 75th percentile from the Chrome UX Report, for a URL or a whole origin (default: the project's site), optionally with up to 40 weekly points. Falls back to Lighthouse lab data when there's no real-user data.

Arguments (5)
  • url string — A single page
  • origin string — A whole site, e.g. https://example.com (default: the project's website)
  • form_factor phone | desktop | tablet | all — Default phone
  • history boolean — Include the weekly history (CrUX History API)
  • lab boolean — Also run Lighthouse for lab metrics and improvement opportunities

serp

Search results (Google, Bing, YouTube, ...).Add with ?toolsets=serp

serp_search_batch

Search results for up to 100 keywords at once in DataForSEO's cheaper queued mode (async). Returns a job_id; get_job returns per-keyword top results and SERP features when ready (usually a few minutes). Use dry_run first to see the cost.

Arguments (7)
  • keywords array, required
  • engine google | bing | yahoo | youtube | baidu | naver | seznam — Search engine (default google). baidu, naver and seznam are queued only and return a job_id
  • type organic | news | images | maps | local_finder | ai_mode | shopping | videos — Result type (default organic). google: organic, news, images, maps, local_finder, ai_mode, shopping, videos; bing/yahoo/youtube/baidu/naver/seznam: organic
  • depth number — Results to fetch (default 10). Billed per 10 results (Naver: 15); use dry_run first above 10
  • load_ai_overview boolean — Google organic: wait for asynchronously loaded AI Overviews (+$0.002)
  • priority normal | high — high = faster queue at 2x price
  • dry_run boolean — Return the estimated cost in USD without calling the provider
serp_history

Past SERPs for a keyword: the project's stored snapshots (rank tracker checks and serp_search results, free) and/or DataForSEO Labs Google history (~12 months, paid). Each snapshot has the top results, our position and SERP features.

Arguments (8)
  • keyword string, required
  • source stored | labs | all — stored (default, needs project_id), labs (Google, paid) or all
  • engine google | bing | yahoo | youtube | baidu | naver | seznam — For stored snapshots (default google)
  • date_from string — YYYY-MM-DD
  • date_to string — YYYY-MM-DD
  • domain string — Domain to report our_position for (default: the project's domain)
  • top number — Results per snapshot (default 10)
  • dry_run boolean — Return the estimated cost in USD without calling the provider
serp_autocomplete

Google autocomplete suggestions for a keyword (DataForSEO, or serper.dev).

Arguments (4)
  • keyword string, required
  • provider auto | dataforseo | serper
  • client chrome | chrome-omni | gws-wiz | gws-wiz-serp | youtube — DataForSEO autocomplete client (youtube = YouTube suggestions)
  • cursor_pointer number — Cursor position in the keyword (DataForSEO)
youtube_video

Details, subtitles (transcript text) or comments for one YouTube video.

Arguments (4)
  • video_id string, required — Video ID or YouTube URL
  • include array — Default ["info"]; each part is a separate paid call
  • subtitles_language string — Original subtitles language code
  • max_chars number — Transcript length cap (default 8000)

keywords

Keyword metrics, ideas and trends.Add with ?toolsets=keywords

keyword_metrics

Search volume, 12-month trend, CPC, competition, keyword difficulty, intent and average backlinks of the top 10 for up to 700 keywords. Google via DataForSEO Labs (or fresh Google Ads volume with source google_ads); Bing via Bing Ads.

Arguments (5)
  • keywords array, required
  • engine google | bing
  • source labs | google_ads — Google only: labs (default, includes difficulty and intent) or google_ads (fresh volume/CPC)
  • include_clickstream boolean — Labs: add clickstream-based volume (doubles the price)
  • dry_run boolean — Return the estimated cost in USD without calling the provider
keyword_ideas

Keyword ideas from seed keywords with metrics. mode: ideas (same topic, up to 200 seeds), suggestions (contain the seed), related (Google 'related searches'), questions (question phrasing). Filter by min_volume / max_difficulty.

Arguments (7)
  • seeds array, required — ideas: up to 200; other modes: up to 5 (one paid call each)
  • mode ideas | suggestions | related | questions
  • min_volume number
  • max_difficulty number
  • include string — Only keywords containing this text
  • exclude string — Drop keywords containing this text
  • dry_run boolean — Return the estimated cost in USD without calling the provider
keywords_for_site

Keywords relevant to a domain or URL, with metrics. Google via Labs (domain) or Google Ads (domain or page); Bing via Bing Ads.

Arguments (5)
  • target string, required — Domain or URL
  • engine google | bing
  • source labs | google_ads — Google only (default labs)
  • min_volume number
  • dry_run boolean — Return the estimated cost in USD without calling the provider
keyword_history

Monthly history of Google search volume, CPC and competition for a keyword (DataForSEO Labs).

Arguments (2)
  • keyword string, required
  • dry_run boolean — Return the estimated cost in USD without calling the provider

domains

Domain and competitor metrics.Add with ?toolsets=domains

domain_overview

Organic overview of a domain in Google: ranking keyword count, estimated monthly traffic (etv) and its value, position distribution and keyword movement. Defaults to the project's domain.

Arguments (1)
  • domain string — Domain like example.com (default: the project's domain)
domain_history

Monthly history of a domain's organic keywords, estimated traffic, top-3 and top-10 counts in Google.

Arguments (3)
  • domain string — Domain (default: the project's domain)
  • date_from string — First month (YYYY-MM-DD)
  • date_to string — Last month (YYYY-MM-DD)
ranked_keywords

Keywords a domain or URL ranks for in Google, with position, ranking URL, volume, CPC, difficulty, intent and estimated traffic. Filter by position, volume, intent or text.

Arguments (9)
  • target string — Domain or absolute URL (default: the project's domain)
  • position_min number
  • position_max number — e.g. 10 for page 1, 20 for striking distance
  • min_volume number
  • max_volume number
  • intent informational | navigational | commercial | transactional
  • contains string — Only keywords containing this text
  • url_contains string — Only keywords where the ranking URL path contains this text
  • order traffic | volume | position — Sort (default traffic)
top_pages

A domain's pages (or subdomains) ranked by estimated organic traffic from Google, with keyword counts and top-10 rankings.

Arguments (2)
  • domain string — Domain (default: the project's domain)
  • mode pages | subdomains — Default pages
competitors

Organic search competitors: for a domain (domains sharing its Google keywords), or for a set of keywords (domains ranking across them). Give `keywords` to use keyword mode; otherwise uses `domain` (default: the project's domain).

Arguments (4)
  • domain string
  • keywords array — Up to 200 keywords (keyword mode)
  • exclude_top_domains boolean — Domain mode: leave out giants like wikipedia.org, amazon.com (default true)
  • exclude_domains array — Domain mode: domains to leave out
domain_intersection

Keywords shared by domains (mode shared), or a keyword gap (mode gap: keywords the other domains rank for and the first domain doesn't). Put your own domain first. One provider call per extra domain (max 6 domains).

Arguments (4)
  • domains array, required — Domains; the first is 'us'. With a project, the project's domain is put first in gap mode (and when only one domain is given)
  • mode shared | gap — Default shared
  • min_volume number
  • dry_run boolean — Return a USD cost estimate without calling the data provider
page_intersection

Keywords several URLs rank for together (mode shared), or keywords competitor URLs rank for and the first URL doesn't (mode gap). Absolute URLs; a trailing /* matches a URL prefix.

Arguments (2)
  • urls array, required — Absolute URLs; in gap mode the first is ours
  • mode shared | gap — Default shared
traffic_estimate

Estimated Google organic traffic for up to 1,000 domains or URLs at once, now or by month (historical: domains only, from Oct 2020).

Arguments (5)
  • targets array, required
  • historical boolean
  • date_from string — Historical: first month (YYYY-MM-DD)
  • date_to string — Historical: last month (YYYY-MM-DD)
  • dry_run boolean — Return a USD cost estimate without calling the data provider

Backlink data.Add with ?toolsets=backlinks

list_referring_domains

Domains linking to a domain or URL, with their rank, backlink count, spam score and first seen / lost dates.

Arguments (5)
  • target string — Domain, subdomain or absolute URL (default: the project's domain)
  • status live | lost | all — Default live
  • order rank | backlinks | first_seen — Default rank
  • include_subdomains boolean — Count subdomains (default true)
  • rank_scale one_thousand | one_hundred — Rank scale for backlink ranks: one_thousand (0-1000, default) or one_hundred (0-100)
list_anchors

Anchor text distribution of a domain's or URL's backlinks: referring domains and backlinks per anchor.

Arguments (4)
  • target string — Domain, subdomain or absolute URL (default: the project's domain)
  • order referring_domains | backlinks — Default referring_domains
  • include_subdomains boolean — Count subdomains (default true)
  • rank_scale one_thousand | one_hundred — Rank scale for backlink ranks: one_thousand (0-1000, default) or one_hundred (0-100)

audit

Page analysis and site audits.Add with ?toolsets=audit

analyze_page

Parse one web page (any site): status, title, meta description, canonical, headings outline, word count, internal/external links, image alt coverage, structured data presence and on-page issues. Fetched by DataForSEO.

Arguments (2)
  • url string, required — Absolute URL of the page
  • javascript boolean — Render JavaScript first (for JS-built pages; costs ~10x more)
start_site_audit

Crawl a site (default: the project's website) and check every page for technical SEO issues. Async: returns a job_id; poll get_job, then use get_site_audit, list_audit_issues and list_audit_pages. Use dry_run to see the estimated cost first.

Arguments (5)
  • target string — Domain to crawl (default: the project's website)
  • max_crawl_pages number — Max pages to crawl (default 500)
  • javascript boolean — Render JavaScript on every page (costs ~10x more)
  • start_url string — Page to start crawling from (default: the homepage)
  • dry_run boolean — Only return the estimated cost
get_site_audit

Summary of the project's latest site audit (or a given one): crawl progress, site checks (SSL, sitemap, robots.txt), on-page score and issue counts.

Arguments (1)
  • audit_id string — Audit ID from start_site_audit (default: the project's latest audit)
list_audit_issues

Issues found by the latest site audit, most severe first, with the number of affected pages. Pass `issue` (a name from this list, e.g. no_title, duplicate_title, broken_links, non_indexable, redirect_chain, is_orphan_page) to list the affected pages.

Arguments (2)
  • audit_id string — Audit ID from start_site_audit (default: the project's latest audit)
  • issue string — Issue name to list affected pages for
list_audit_pages

Pages crawled by the latest site audit with status code, click depth and internal links in/out. Filter by status or depth; sort to find orphan or deep pages.

Arguments (5)
  • audit_id string — Audit ID from start_site_audit (default: the project's latest audit)
  • status_code number — Only pages with this HTTP status, e.g. 404
  • min_depth number — Only pages at least this many clicks from the homepage
  • max_inbound_links number — Only pages with at most this many internal links pointing to them
  • order_by url | depth | inbound_links | onpage_score — depth: deepest first; inbound_links / onpage_score: lowest first
content_mentions

Web pages (news, blogs, forums, ...) that mention a brand or keyword, with domain rank, snippet, date and sentiment. Defaults to the project's name.

Arguments (5)
  • keyword string — Brand or phrase to look for (default: the project's name)
  • exact boolean — Match the exact phrase (default true)
  • page_type ecommerce | news | blogs | message-boards | organization
  • one_per_domain boolean — At most one page per domain
  • exclude_domains array — Domains to leave out, e.g. your own

local

Local search.Add with ?toolsets=local

local_rank_grid

How do we rank on Google Maps across a city? Checks the Maps results at a grid of points around a centre (3×3, 5×5 or 7×7, spacing_km apart): rank per point, average rank, where we're in the top 3 and the top competitors. dry_run is true by default and returns the cost (~$0.002 per point); pass dry_run=false to run.

Arguments (12)
  • keyword string, required — Local search, e.g. 'dentist'
  • lat number, required — Grid centre latitude
  • lng number, required — Grid centre longitude
  • grid_size union — Points per side (default 5)
  • spacing_km number — Distance between points (default 1 km)
  • zoom number — Google Maps zoom (default 14)
  • depth number — Results per point (default 20)
  • business_name string — Our business name as on Google Maps
  • business_domain string — Our website domain (default: the project's)
  • place_id string — Our Google place_id, most reliable match
  • cid string — Our Google CID
  • dry_run boolean — Default true: estimate only