openapi: 3.0.3 info: title: Account Account API SEO Research API API version: v2 servers: - url: https://api.spyfu.com/apis/accounts_api security: - Basic_Authentication_Token: [] - Query_Parameter_Token: [] - HMAC_Authentication_Header: [] tags: - name: SEO Research API paths: /v2/seo/getMostValuableKeywords: get: operationId: OrganicSerpApi_GetMostValuableKeywords_GET summary: Get Most Valuable Keywords description: 'Returns keywords that generate the highest organic click volume for a domain. This endpoint identifies the most traffic-driving keywords to reveal a domain''s most valuable SEO assets and content opportunities. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=mostvaluable&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort results by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved the most valuable keywords by organic click volume. Returns a paginated list of keywords prioritized by traffic value and search data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getNewlyRankedKeywords: get: operationId: OrganicSerpApi_GetNewlyRankedKeywords_GET summary: Get Newly Ranked Keywords description: 'Returns keywords where a domain recently achieved rankings in the top 100 organic search results. This endpoint identifies fresh ranking opportunities to reveal new content successes and emerging SEO momentum. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=newlyranked&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort results by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved keywords with new rankings in the top 100. Returns a paginated list of keywords showing fresh ranking achievements and search data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getGainedRanksKeywords: get: operationId: OrganicSerpApi_GetGainedRanksKeywords_GET summary: Get Gained Ranks Keywords description: 'Returns keywords where a domain, path, subdomain, page or full URL improved its organic search ranking positions compared to the previous month. This endpoint identifies the biggest ranking gains to reveal successful SEO efforts and content optimizations. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=gainedranks&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update(positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getLostRanksKeywords: get: operationId: OrganicSerpApi_GetLostRanksKeywords_GET summary: Get Lost Ranks Keywords description: 'Returns keywords where a domain''s organic search ranking positions declined compared to the previous month. This endpoint identifies ranking losses that remain within the top 100 results to reveal content that needs SEO attention. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=lostranks&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA x-enumDescriptions: AR: Argentina AU: Australia BE: Belgium BR: Brazil CA: Canada CH: Switzerland DE: Germany DK: Denmark ES: Spain FR: France IE: Ireland IN: India IT: Italy JP: Japan MX: Mexico NL: Netherlands 'NO': Norway NZ: New Zealand PL: Poland PT: Portugal SE: Sweden SG: Singapore TR: Turkey UA: Ukraine UK: United Kingdom US: United States ZA: South Africa example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved keywords with declined organic rankings. Returns a paginated list of keywords showing ranking losses and search data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getGainedClicksKeywords: get: operationId: OrganicSerpApi_GetGainedClicksKeywords_GET summary: Get Gained Clicks Keywords description: 'Returns keywords where a domain, path, subdomain, page or full URL experienced increased organic clicks compared to the previous month. This endpoint identifies the biggest click improvements to reveal rising content opportunities and successful SEO changes. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=gainedclicks&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getLostClicksKeywords: get: operationId: OrganicSerpApi_GetLostClicksKeywords_GET summary: Get Lost Clicks Keywords description: 'Returns keywords where a domain experienced decreased organic clicks compared to the previous month. This endpoint identifies the biggest click losses to reveal content that needs attention or competitive pressure points. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=lostclicks&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA x-enumDescriptions: AR: Argentina AU: Australia BE: Belgium BR: Brazil CA: Canada CH: Switzerland DE: Germany DK: Denmark ES: Spain FR: France IE: Ireland IN: India IT: Italy JP: Japan MX: Mexico NL: Netherlands 'NO': Norway NZ: New Zealand PL: Poland PT: Portugal SE: Sweden SG: Singapore TR: Turkey UA: Ukraine UK: United Kingdom US: United States ZA: South Africa example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved keywords with decreased organic clicks. Returns a paginated list of keywords showing click losses and ranking data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getJustMadeItKeywords: get: operationId: OrganicSerpApi_GetJustMadeItKeywords_GET summary: Get Just Made It Keywords description: 'Returns keywords where a domain achieved first page rankings (top 10 results) this month after not ranking there previously. This endpoint identifies new ranking successes to reveal effective content strategies and emerging opportunities. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=justmadeit&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA x-enumDescriptions: AR: Argentina AU: Australia BE: Belgium BR: Brazil CA: Canada CH: Switzerland DE: Germany DK: Denmark ES: Spain FR: France IE: Ireland IN: India IT: Italy JP: Japan MX: Mexico NL: Netherlands 'NO': Norway NZ: New Zealand PL: Poland PT: Portugal SE: Sweden SG: Singapore TR: Turkey UA: Ukraine UK: United Kingdom US: United States ZA: South Africa example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved keywords that achieved first page rankings. Returns a paginated list of keywords showing new ranking achievements and search data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getJustFellOffKeywords: get: operationId: OrganicSerpApi_GetJustFellOffKeywords_GET summary: Get Just Fell Off Keywords description: 'Returns keywords where a domain dropped from the first page (top 10 results) compared to the previous month. This endpoint identifies recent ranking losses to reveal content that needs attention or competitive threats. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?includeAnyTerm=true&includeAnyUrl=true&searchType=justfelloff&sidebarContext=filters&query=example.com)' parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com/blog example: example.com/blog - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the domain/url are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 14 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA x-enumDescriptions: AR: Argentina AU: Australia BE: Belgium BR: Brazil CA: Canada CH: Switzerland DE: Germany DK: Denmark ES: Spain FR: France IE: Ireland IN: India IT: Italy JP: Japan MX: Mexico NL: Netherlands 'NO': Norway NZ: New Zealand PL: Poland PT: Portugal SE: Sweden SG: Singapore TR: Turkey UA: Ukraine UK: United Kingdom US: United States ZA: South Africa example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getSeoKeywords: get: operationId: OrganicSerpApi_GetSeoKeywords_GET summary: Get SEO Keywords description: Unified endpoint for SEO keyword analyses. Select an analysis via `searchType` to return gains/losses in clicks, rank movers, page-one entries/exits, newly ranked terms, or top-value keywords -- without switching endpoints. parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: example.com example: example.com - name: searchType in: query description: Type of SEO keyword analysis to perform. Each type provides different insights into keyword performance and ranking changes. required: true schema: type: string default: MostValuable enum: - GainedClicks - GainedRanks - JustFellOff - JustMadeIt - LostClicks - LostRanks - MostValuable - NewlyRanked x-enumDescriptions: GainedClicks: MoM increase in estimated organic clicks. GainedRanks: Largest positive MoM rank change (moved up). JustFellOff: Now <10; was 1-10 last month (fell off page one). JustMadeIt: Now 1-10; was <10 last month (made page one). LostClicks: MoM decrease in estimated organic clicks. LostRanks: Largest negative MoM rank change (moved down). MostValuable: Highest current estimated organic clicks for the domain/URL. NewlyRanked: Unranked last month; now 1-100. example: MostValuable example: MostValuable - name: compareDomain in: query description: Domain to compare against when evaluating where it outranks you and where you outrank it. schema: type: string example: competitor.com example: competitor.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the domain/URL's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the domain/URL rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the domain/URL rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the domain/URL improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position (1 = top organic result) RankChange: Change in organic position from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getOrganicOutrankingKeywords: get: operationId: OrganicSerpApi_GetOrganicOutrankingKeywords_GET summary: Get Organic Outranking Keywords description: Compare two domains' organic rankings in one call. Returns keywords where one domain outranks the other or has just overtaken it, with both sites' ranks, changes, clicks, and URLs. The comparison domain's metrics appear in the your* fields. Choose the mode with keywordSearchType. parameters: - name: query in: query description: Primary domain to analyze. This domain's ranking data appears in the main response fields (rank, rankChange, seoClicks, etc.). Accepts full domains (example.com), complete URLs, subdomains, or specific paths. required: true schema: type: string example: competitor.com example: competitor.com - name: searchType in: query description: 'Required. Chooses the ranking scenario for the query/compareDomain pair and governs how results are interpreted. TheyOutrankYou: keywords where query ranks above compareDomain. TheyJustSurpassedYou: recent crossovers where query moved ahead.' required: true schema: type: string default: TheyOutrankYou enum: - TheyOutrankYou - TheyJustSurpassedYou x-enum-descriptions: TheyOutrankYou: Keywords where the query domain ranks higher than compareDomain now. To see where a competitor outranks you, put competitor in query and your site in compareDomain. TheyJustSurpassedYou: Keywords where the query domain recently overtook compareDomain in rank. Highlights fresh shifts. To see where a competitor just passed you, put competitor in query and your site in compareDomain. example: TheyOutrankYou example: TheyOutrankYou - name: compareDomain in: query description: Domain to compare against. This domain's ranking data appears in the 'your' response fields (yourRank, yourRankChange, yourUrl). The endpoint shows where the query domain currently outranks this comparison domain. required: true schema: type: string example: yourdomain.com example: yourdomain.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the query domain's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the query domain's rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the query domain's rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the query domain improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the query domain's month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position for the query domain (1 = top organic result) RankChange: Change in organic position for the query domain from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the query domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks for the query domain from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getWhereTheyOutRankYou: get: operationId: OrganicSerpApi_GetKeywordsWhereTheyOutRankYou_GET summary: Get Where They Outrank You Keywords description: 'Returns keywords where the query domain currently outranks the comparison domain in organic search results. This endpoint identifies competitive gaps where one domain holds a better position than another, providing insights into competitor strengths and opportunities for improvement. The response includes both domains'' ranking data, with the comparison domain''s metrics appearing in the ''your'' fields (yourRank, yourRankChange, yourUrl). Use this to analyze competitive positioning, identify content gaps, and discover opportunities where competitors are winning. **Common Usage Patterns:** - Put competitor in `query` and your domain in `compareDomain` to see where they outrank you - Put your domain in `query` and competitor in `compareDomain` to see where you outrank them [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?query=example.com) _(TODO - verify)_' parameters: - name: query in: query description: Primary domain to analyze. This domain's ranking data appears in the main response fields (rank, rankChange, seoClicks, etc.). Accepts full domains (example.com), complete URLs, subdomains, or specific paths. required: true schema: type: string example: competitor.com example: competitor.com - name: compareDomain in: query description: Domain to compare against. This domain's ranking data appears in the 'your' response fields (yourRank, yourRankChange, yourUrl). The endpoint shows where the query domain currently outranks this comparison domain. required: true schema: type: string example: yourdomain.com example: yourdomain.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the query domain's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the query domain's rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the query domain's rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the query domain improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the query domain's month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position for the query domain (1 = top organic result) RankChange: Change in organic position for the query domain from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the query domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks for the query domain from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: OK content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getWhereTheyJustSurpassedYou: get: operationId: OrganicSerpApi_GetKeywordsWhereTheyJustSurpassedYou_GET summary: Get Where They Just Surpassed You Keywords description: 'Returns keywords where the query domain recently surpassed the comparison domain in organic search rankings. This endpoint identifies competitive shifts where one domain has overtaken another, either through ranking improvements, competitor declines, or both. The response includes both domains'' ranking data, with the comparison domain''s metrics appearing in the ''your'' fields (yourRank, yourRankChange, yourUrl). Use this to monitor competitive threats or analyze successful competitor strategies. **Common Usage Patterns:** - Put competitor in `query` and your domain in `compareDomain` to see where they''re overtaking you - Put your domain in `query` and competitor in `compareDomain` to see where you''re gaining ground [Visualize this API live on SpyFu](https://www.spyfu.com/seo/keywords/domain?query=example.com)' parameters: - name: query in: query description: Primary domain to analyze. This domain's ranking data appears in the main response fields (rank, rankChange, seoClicks, etc.). Accepts full domains (example.com), complete URLs, subdomains, or specific paths. required: true schema: type: string example: competitor.com example: competitor.com - name: compareDomain in: query description: Domain to compare against. This domain's ranking data appears in the 'your' response fields (yourRank, yourRankChange, yourUrl). The endpoint shows where the query domain just surpassed this comparison domain. required: true schema: type: string example: yourdomain.com example: yourdomain.com - name: includeTerms in: query description: Comma-separated list of terms that must be present in the keyword. schema: type: string example: hosting,domain,website - name: includeAnyTerm in: query description: 'Used with includeTerms. If true: match any term (OR). If false: require all terms (AND).' schema: type: boolean default: false example: false - name: excludeTerms in: query description: Comma-separated list of terms to exclude from results (e.g., branded or irrelevant terms). schema: type: string example: free,cheap,discount - name: excludeHomepageKeywords in: query description: If true, exclude keywords where the query domain's homepage (root domain, e.g., example.com) ranks; if false, include all. schema: type: boolean default: false example: false example: false - name: searchVolume.min in: query description: Filter to keywords where monthly search volume (Google) is ≥ this value. schema: type: number format: float example: 1000 example: 1000 - name: searchVolume.max in: query description: Filter to keywords where monthly search volume (Google) is ≤ this value. schema: type: number format: float example: 50000 example: 50000 - name: keywordDifficulty.min in: query description: Filter to keywords where the keyword difficulty score is ≥ this value (0-100; higher = harder to rank). schema: type: number format: float example: 30 example: 30 - name: keywordDifficulty.max in: query description: Filter to keywords where the keyword difficulty score is ≤ this value (0-100; higher = harder to rank). schema: type: number format: float example: 70 example: 70 - name: rank.min in: query description: Filter to keywords where the query domain's rank position is ≥ this value (1 = best/top organic result). schema: type: number format: float example: 1 example: 1 - name: rank.max in: query description: Filter to keywords where the query domain's rank position is ≤ this value (1 = best/top organic result). schema: type: number format: float example: 10 example: 10 - name: rankChange.min in: query description: Filter to keywords where the query domain improved by at least this many positions vs. the previous month (rank_change ≥ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 5 example: 5 - name: rankChange.max in: query description: Filter to keywords where the query domain's month-over-month rank change is at most this many positions (rank_change ≤ value). Positive values mean moved up; negative values mean moved down. schema: type: number format: float example: 20 example: 20 - name: costPerClick.min in: query description: Filter to keywords where the average cost per click (CPC) is ≥ this value. schema: type: number format: float example: 1 example: 1 - name: costPerClick.max in: query description: Filter to keywords where the average cost per click (CPC) is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: costPerClickOption in: query description: Match type for CPC filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: seoClicks.min in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≥ this value. schema: type: number format: float example: 100 example: 100 - name: seoClicks.max in: query description: Filter to keywords where estimated monthly organic clicks (SEO clicks) to the query domain are ≤ this value. schema: type: number format: float example: 1000 example: 1000 - name: seoClicksChange.min in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≥ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 10 example: 10 - name: seoClicksChange.max in: query description: Filter to keywords where the query domain's month-over-month change in estimated organic clicks is ≤ this value. Positive values indicate click gains; negative values indicate click losses. schema: type: number format: float example: 500 example: 500 - name: percentMobileSearches.min in: query description: Filter to keywords where the mobile search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentMobileSearches.max in: query description: Filter to keywords where the mobile search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: percentDesktopSearches.min in: query description: Filter to keywords where the desktop search share (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentDesktopSearches.max in: query description: Filter to keywords where the desktop search share (%) is ≤ this value (range 0-100). schema: type: number format: float example: 50 example: 50 - name: percentNotClicked.min in: query description: Filter to keywords where the percentage of searches with no click is ≥ this value (range 0-100). schema: type: number format: float example: 10 example: 10 - name: percentNotClicked.max in: query description: Filter to keywords where the percentage of searches with no click is ≤ this value (range 0-100). schema: type: number format: float example: 30 example: 30 - name: percentPaidClicks.min in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≥ this value (range 0-100). schema: type: number format: float example: 20 example: 20 - name: percentPaidClicks.max in: query description: Filter to keywords where the share of SERP clicks going to paid ads (%) is ≤ this value (range 0-100). schema: type: number format: float example: 60 example: 60 - name: percentOrganicClicks.min in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≥ this value (range 0-100). schema: type: number format: float example: 40 example: 40 - name: percentOrganicClicks.max in: query description: Filter to keywords where the share of SERP clicks going to organic results (%) is ≤ this value (range 0-100). schema: type: number format: float example: 80 example: 80 - name: monthlyCost.min in: query description: Filter to keywords where the estimated monthly advertising cost is ≥ this value. schema: type: number format: float example: 100 example: 100 - name: monthlyCost.max in: query description: Filter to keywords where the estimated monthly advertising cost is ≤ this value. schema: type: number format: float example: 5000 example: 5000 - name: monthlyCostOption in: query description: Match type for monthly cost filtering. Broad = includes variations/related terms; Exact = exact keyword only; Phrase = contains the keyword phrase in order (with additional words allowed). schema: type: string enum: - Broad - Exact - Phrase x-enumDescriptions: Broad: Includes keyword variations and related terms Exact: Requires precise keyword match only Phrase: Includes the keyword phrase in order with additional words example: Broad example: Broad - name: paidCompetitors.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 5 example: 5 - name: paidCompetitors.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 50 example: 50 - name: rankingHomepages.min in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≥ this value. schema: type: number format: float example: 2 example: 2 - name: rankingHomepages.max in: query description: Filter to keywords where the number of homepage/root-domain URLs in the top 100 results is ≤ this value. schema: type: number format: float example: 10 example: 10 - name: totalMonthlyClicks.min in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≥ this value. Independent of rank; includes both organic and paid clicks. schema: type: number format: float example: 1000 example: 1000 - name: totalMonthlyClicks.max in: query description: Filter to keywords where total monthly SERP clicks (all domains) are ≤ this value. Includes both organic and paid clicks. schema: type: number format: float example: 10000 example: 10000 - name: adCount.min in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≥ this value. schema: type: number format: float example: 3 example: 3 - name: adCount.max in: query description: Filter to keywords where the number of distinct advertisers observed over the last 6 months is ≤ this value. schema: type: number format: float example: 25 example: 25 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 10000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SearchVolume enum: - SearchVolume - KeywordDifficulty - Rank - RankChange - SeoClicks - SeoClicksChange - PercentMobileSearches - PercentDesktopSearches - PercentNotClicked - PercentPaidClicks - PercentOrganicClicks - BroadCostPerClick - ExactCostPerClick - PhraseCostPerClick - BroadMonthlyCost - ExactMonthlyCost - PhraseMonthlyCost - TotalMonthlyClicks - PaidCompetitors - RankingHomepages x-enumDescriptions: SearchVolume: Number of searches done this past month on Google (or within selected country). Blended from multiple sources for better snapshot of search activity KeywordDifficulty: SEO ranking difficulty score (0-100 scale, higher = more difficult to rank). Based on domain strength, on-page signals like 'keyword in title,' and number of .gov/.edu domains Rank: Organic search result position for the query domain (1 = top organic result) RankChange: Change in organic position for the query domain from previous data update (positive values indicate ranking improvement; negative values indicate moving further down the SERP). SeoClicks: Estimated number of organic clicks the query domain gets from ranking on this keyword SeoClicksChange: Change in estimated organic clicks for the query domain from previous data update PercentMobileSearches: Percentage breakdown of searches from mobile vs desktop devices PercentDesktopSearches: Percentage breakdown of searches from desktop vs mobile devices PercentNotClicked: Rate that searchers leave the SERP without clicking any result PercentPaidClicks: Percentage of SERP clicks that went to paid ads PercentOrganicClicks: Percentage of SERP clicks that went to organic results BroadCostPerClick: Average amount advertisers pay per click for broad match ads on this keyword ExactCostPerClick: Average amount advertisers pay per click for exact match ads on this keyword PhraseCostPerClick: Average amount advertisers pay per click for phrase match ads on this keyword BroadMonthlyCost: Estimated monthly advertising spend for broad match bidding ExactMonthlyCost: Estimated monthly advertising spend for exact match bidding PhraseMonthlyCost: Estimated monthly advertising spend for phrase match bidding TotalMonthlyClicks: Total estimated clicks made on this SERP to any paid or organic results PaidCompetitors: Total number of advertisers seen over the last 6 months for this keyword RankingHomepages: Number of homepage URLs (vs deeper paths) ranking within first 100 results example: SearchVolume example: SearchVolume - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 - name: adultFilter in: query description: Exclude adult keywords considered unsafe for work. schema: type: boolean default: true example: true example: true - name: onlyAdultKeywords in: query description: Only include adult keywords considered unsafe for work. schema: type: boolean default: false example: false example: false - name: exactMatch in: query description: "Indicates whether to apply exact match filtering for the query.\r\nThis parameter will result in **only** exact matches,\r\nmeaning protocols (http/https) and trailing slashes **must** be included.\r\nFor example, a query of \"https://example.com/blog\" will not match\r\n- \"example.com/blog\"\r\n- \"https://example.com/blog/\"" schema: type: boolean responses: '200': description: Successfully retrieved keywords that dropped from the first page. Returns a paginated list of keywords showing ranking declines and search data. content: application/json: schema: description: Response wrapper containing organic SERP keyword results with comprehensive SEO metrics and pagination metadata. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of organic search keywords with comprehensive SEO metrics including rankings, click estimates, and SERP analysis data. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string readOnly: true nullable: true example: running shoes topRankedUrl: description: The highest ranking URL from this domain for this specific keyword. type: string readOnly: true nullable: true example: https://example.com/best-running-shoes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 readOnly: true example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 readOnly: true nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 readOnly: true nullable: true example: 700000 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 readOnly: true example: 69 broadCostPerClick: description: Average cost per click for broad match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 phraseCostPerClick: description: Average cost per click for phrase match advertising on this keyword. type: number format: double readOnly: true nullable: true example: 0.28 exactCostPerClick: description: Average cost per click for exact match advertising on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets. type: number format: double readOnly: true nullable: true example: 0.28 seoClicks: description: Estimated monthly organic clicks this domain receives from this keyword based on current ranking position. type: integer format: int64 readOnly: true example: 3000 seoClicksChange: description: Change in estimated organic clicks compared to the previous measurement period. type: integer format: int64 readOnly: true nullable: true example: -600 totalMonthlyClicks: description: Total number of clicks (organic and paid combined) on search results for this keyword in the past month. type: integer format: int64 readOnly: true nullable: true example: 647000 percentMobileSearches: description: Percentage of searches for this keyword that come from mobile devices. type: number format: double readOnly: true nullable: true example: 0.4 percentDesktopSearches: description: Percentage of searches for this keyword that come from desktop devices. type: number format: double readOnly: true nullable: true example: 0.6 percentNotClicked: description: Percentage of searches where users leave the SERP without clicking any result. type: number format: double readOnly: true nullable: true example: 0.075 percentPaidClicks: description: Percentage of total SERP clicks that go to paid ads. type: number format: double readOnly: true nullable: true example: 0.079 percentOrganicClicks: description: Percentage of total SERP clicks that go to organic search results. type: number format: double readOnly: true nullable: true example: 0.921 broadMonthlyCost: description: 'Estimated monthly advertising cost for broad match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 6043.5 phraseMonthlyCost: description: 'Estimated monthly advertising cost for phrase match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5695.5 exactMonthlyCost: description: 'Estimated monthly advertising cost for exact match bidding on this keyword from the #2 position.' type: number format: double readOnly: true nullable: true example: 5392.5 paidCompetitors: description: Total number of advertisers observed purchasing ads for this keyword over the last 14 months. type: integer format: int32 readOnly: true nullable: true example: 0 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 readOnly: true nullable: true example: 10 yourRank: description: The comparison domain's organic search position for this keyword (1 = top organic result). This field represents the rank of the domain specified in the 'compareDomain' parameter, allowing direct comparison with the primary query domain's rank. type: integer format: int32 nullable: true example: 5 yourRankChange: description: Change in the comparison domain's organic position from the previous data update. Positive values indicate the comparison domain moved up in rankings; negative values indicate it moved down. This shows how the comparison domain's performance has changed over time. type: integer format: int32 nullable: true example: -3 yourUrl: description: The specific URL from the comparison domain that ranks for this keyword. This shows which page on the comparison domain is competing for this search term, providing insights into their content strategy. type: string readOnly: true nullable: true example: https://comparedomain.com/blog additionalProperties: false description: Represents an organic search keyword with comprehensive SEO metrics including rankings, click estimates, costs, and SERP analysis data. readOnly: true nullable: true totalMatchingResults: description: Total number of organic keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 75000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., invalid domain format, pageSize exceeds maximum, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SEO keyword data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getSerpAnalysisKeywords: get: operationId: OrganicSerpApi_GetSerpAnalysisKeywords_GET summary: 'Get SERP Analysis for Keyword ' description: 'Returns detailed search engine results page (SERP) analysis for a specific keyword, showing all domains ranking in positions 1-100. This endpoint provides comprehensive ranking data updated monthly to reveal the competitive landscape for any keyword. [Visualize this API live on SpyFu](https://www.spyfu.com/keyword/serp-analysis?query=example%20keyword)' parameters: - name: keyword in: query description: Keyword to analyze for SERP ranking data. required: true schema: type: string example: electric car example: electric car - name: pageSize in: query description: Number of ranking results to return (maximum 105 for top 100+ positions). schema: type: integer format: int32 default: 105 maximum: 105 minimum: 1 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US responses: '200': description: Successfully retrieved SERP analysis data for the keyword. Returns ranking positions 1-100+ with domain URLs, titles, and competitive metrics. content: application/json: schema: description: Response wrapper containing SERP analysis keyword results with detailed ranking data and competitive landscape insights. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of keywords with detailed SERP analysis including ranking data, search volume metrics, and competitive landscape insights. type: array items: type: object properties: keyword: description: The keyword for which this domain ranks organically in the top 100 search results. type: string nullable: true example: running shoes domain: description: The domain name that ranks for this keyword in organic search results. type: string nullable: true example: example.com url: description: The specific URL from this domain that ranks for this keyword. type: string nullable: true example: https://example.com/blog title: description: The page title of the ranking URL as it appears in search results. type: string nullable: true example: Best Running Shoes for Athletes rank: description: Current organic search position for this keyword (1 = top position). type: integer format: int32 example: 7 rankChange: description: Change in ranking position since the previous measurement period (positive values indicate ranking improvement; negative values indicate moving further down the SERP). type: integer format: int32 nullable: true example: -3 searchVolume: description: Monthly search volume for this keyword based on Google search data across the selected country/region. type: integer format: int64 nullable: true example: 700000 rankingHomepages: description: Number of domain homepages (vs. deeper pages) ranking in the top 100 organic results for this keyword. type: integer format: int32 nullable: true example: 10 keywordDifficulty: description: SEO difficulty score (1-100) indicating how challenging it would be to rank organically for this keyword, with 100 being most difficult. type: integer format: int32 example: 69 dateSearched: description: Date when this keyword was first discovered and added to SpyFu's database. type: string format: date-time example: '2024-09-26T10:30:00Z' additionalProperties: false description: Represents a keyword with detailed SERP analysis including ranking data, search volume metrics, and competitive landscape insights. readOnly: true nullable: true totalMatchingResults: description: Total number of keywords available that match the query criteria, including results not included in the current page. type: integer format: int64 readOnly: true example: 25000 additionalProperties: false '400': description: Bad Request - Invalid parameters provided (e.g., missing keyword, invalid pageSize, or invalid country code) '401': description: Unauthorized - Invalid API credentials or insufficient permissions to access SERP analysis data '500': description: Internal Server Error - A server-side error occurred while processing the request tags: - SEO Research API /v2/seo/getLiveSeoStats: get: operationId: OrganicSerpApi_GetLiveSeoStats_GET summary: Get Live SEO Stats description: Returns live, aggregated SEO metrics for a given domain, subdomain, path, or URL. Results summarize current organic visibility and traffic estimates derived from up-to-date SERP data. Updated continuously (~every 15 seconds), 24/7/365. parameters: - name: query in: query description: Domain, URL, subdomain, or path to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), specific paths (example.com/products/), or individual pages. required: true schema: type: string example: domain.com/blog example: domain.com - name: countryCode in: query description: Country to get results for. schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US responses: '200': description: OK content: application/json: schema: type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 1 domain: description: Root domain for the results type: string readOnly: true nullable: true example: example.com url: description: URL for the results type: string readOnly: true nullable: true example: https://example.com/blog totalOrganicResults: description: Total keywords found for domain or URL type: integer format: int64 readOnly: true example: 15420 monthlyOrganicClicks: description: We estimate that the domain or URL should get this many total clicks to its page (per month). type: number format: double readOnly: true example: 125000.5 monthlyOrganicClickValue: description: The estimated value over a month for ranking on the domain or URL. type: number format: double readOnly: true example: 45000.75 totalSearchVolume: description: Sum of monthly search volume across all returned keywords. type: number format: double example: 700000 additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getMostTrafficTopPages: get: operationId: TopPagesApi_GetMostTrafficTopPages_GET summary: Get Highest Traffic Top Pages description: 'Returns the pages that generate the most organic traffic for a domain. This endpoint identifies the highest-performing content by estimated monthly organic clicks, revealing which pages drive the most SEO value and traffic to the site. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/top-pages?query=example.com)' parameters: - name: query in: query description: Domain or URL to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), or specific paths (example.com/products/). required: true schema: type: string example: example.com example: example.com - name: keywordFilter in: query description: Filter to pages that rank for keywords containing this term. Helps narrow results to specific topics or content themes. schema: type: string example: hosting example: hosting - name: seoClicks.min in: query description: Filter to pages where estimated monthly organic clicks are ≥ this value. schema: type: number format: float example: '100' example: '100' - name: seoClicks.max in: query description: Filter to pages where estimated monthly organic clicks are ≤ this value. schema: type: number format: float example: 10000 example: 10000 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 1000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SeoClicks const: SeoClicks x-enumDescriptions: SeoClicks: Estimated monthly organic clicks that each page receives from all of its keyword rankings example: SeoClicks example: SeoClicks - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 responses: '200': description: OK content: application/json: schema: description: Response wrapper containing top pages results with comprehensive SEO performance metrics and traffic analysis. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of top-performing pages with organic traffic estimates, keyword rankings, and competitive performance data. type: array items: type: object properties: title: description: The HTML title tag of the page as it appears in search results. This helps identify the page's content focus and SEO optimization strategy. type: string nullable: true example: Best Running Shoes 2024 - Complete Buyer's Guide url: description: The complete URL of the page that ranks for multiple organic keywords. This shows the specific page driving organic traffic for the domain. type: string nullable: true example: https://example.com/best-running-shoes-2024 keywordCount: description: Total number of unique keywords this page ranks for in the top 100 organic search results. Higher counts indicate broader topical coverage. type: integer format: int64 example: 247 estMonthlySeoClicks: description: Estimated total monthly organic clicks this page receives from all keywords it ranks for. This represents the page's overall organic traffic value. type: integer format: int64 example: 15420 topKeyword: description: The highest-value keyword this page ranks for, typically the term driving the most organic traffic to this specific page. type: string nullable: true example: best running shoes topKeywordPosition: description: 'The organic search position (rank) for the top keyword, where 1 represents the #1 organic result on Google.' type: integer format: int32 example: 3 topKeywordSearchVolume: description: Monthly search volume for the top keyword, showing how many people search for this term each month on Google. type: integer format: int64 nullable: true example: 74000 topKeywordClicks: description: Estimated monthly organic clicks this page receives specifically from its top keyword, based on the keyword's search volume and the page's ranking position. type: integer format: int64 example: 8950 additionalProperties: false description: Represents a top-performing page from a domain's organic search portfolio, including traffic estimates, keyword performance, and the page's most valuable search term. readOnly: true nullable: true additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getNewTopPages: get: operationId: TopPagesApi_GetNewTopPages_GET summary: Get New Top Pages description: 'Returns pages that have recently started generating significant organic traffic for a domain. This endpoint identifies newly discovered high-performing content, revealing fresh opportunities and emerging content strategies that are driving SEO success. [Visualize this API live on SpyFu](https://www.spyfu.com/seo/top-pages/domain?query=example.com) _(TODO - verify)_' parameters: - name: query in: query description: Domain or URL to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), or specific paths (example.com/products/). required: true schema: type: string example: example.com example: example.com - name: keywordFilter in: query description: Filter to pages that rank for keywords containing this term. Helps narrow results to specific topics or content themes. schema: type: string example: hosting example: hosting - name: seoClicks.min in: query description: Filter to pages where estimated monthly organic clicks are ≥ this value. schema: type: number format: float example: '100' example: '100' - name: seoClicks.max in: query description: Filter to pages where estimated monthly organic clicks are ≤ this value. schema: type: number format: float example: 10000 example: 10000 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 1000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SeoClicks const: SeoClicks x-enumDescriptions: SeoClicks: Estimated monthly organic clicks that each new page receives from all of its keyword rankings example: SeoClicks example: SeoClicks - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 responses: '200': description: OK content: application/json: schema: description: Response wrapper containing top pages results with comprehensive SEO performance metrics and traffic analysis. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of top-performing pages with organic traffic estimates, keyword rankings, and competitive performance data. type: array items: type: object properties: title: description: The HTML title tag of the page as it appears in search results. This helps identify the page's content focus and SEO optimization strategy. type: string nullable: true example: Best Running Shoes 2024 - Complete Buyer's Guide url: description: The complete URL of the page that ranks for multiple organic keywords. This shows the specific page driving organic traffic for the domain. type: string nullable: true example: https://example.com/best-running-shoes-2024 keywordCount: description: Total number of unique keywords this page ranks for in the top 100 organic search results. Higher counts indicate broader topical coverage. type: integer format: int64 example: 247 estMonthlySeoClicks: description: Estimated total monthly organic clicks this page receives from all keywords it ranks for. This represents the page's overall organic traffic value. type: integer format: int64 example: 15420 topKeyword: description: The highest-value keyword this page ranks for, typically the term driving the most organic traffic to this specific page. type: string nullable: true example: best running shoes topKeywordPosition: description: 'The organic search position (rank) for the top keyword, where 1 represents the #1 organic result on Google.' type: integer format: int32 example: 3 topKeywordSearchVolume: description: Monthly search volume for the top keyword, showing how many people search for this term each month on Google. type: integer format: int64 nullable: true example: 74000 topKeywordClicks: description: Estimated monthly organic clicks this page receives specifically from its top keyword, based on the keyword's search volume and the page's ranking position. type: integer format: int64 example: 8950 additionalProperties: false description: Represents a top-performing page from a domain's organic search portfolio, including traffic estimates, keyword performance, and the page's most valuable search term. readOnly: true nullable: true additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API /v2/seo/getTopPages: get: operationId: TopPagesApi_GetTopPages_GET summary: Get Top Performing Pages description: 'Returns top organic pages for a domain, subdomain, path, or full URL. Use searchType to choose: MostTraffic (highest estimated SEO clicks) or New (newly gaining traffic). Results include page URL and monthly SEO clicks; optional keywordFilter narrows by ranked keywords.' parameters: - name: query in: query description: Domain or URL to analyze. Accepts full domains (example.com), complete URLs (https://example.com/blog), subdomains (blog.example.com), or specific paths (example.com/products/). required: true schema: type: string example: example.com example: example.com - name: searchType in: query description: 'Required. Selects page analysis type: MostTraffic=pages generating most organic traffic overall, New=pages recently discovered with significant traffic. Determines whether to return established top performers or emerging high-traffic pages.' required: true schema: type: string default: MostTraffic enum: - MostTraffic - New x-enum-descriptions: MostTraffic: Returns pages with highest organic traffic for the query domain/path. Identifies top-performing content by estimated monthly organic clicks. Shows which pages drive most SEO value and traffic to the site. New: Returns pages recently discovered generating significant organic traffic for the query domain/path. Identifies newly successful content and emerging pages. Reveals fresh opportunities and content strategies driving recent SEO growth. example: MostTraffic example: MostTraffic - name: keywordFilter in: query description: Filter to pages that rank for keywords containing this term. Helps narrow results to specific topics or content themes. schema: type: string example: hosting example: hosting - name: seoClicks.min in: query description: Filter to pages where estimated monthly organic clicks are ≥ this value. schema: type: number format: float example: '100' example: '100' - name: seoClicks.max in: query description: Filter to pages where estimated monthly organic clicks are ≤ this value. schema: type: number format: float example: 10000 example: 10000 - name: pageSize in: query description: The maximum number of rows returned. schema: type: integer format: int32 default: 5 maximum: 1000 minimum: 1 example: 5 example: 5 - name: countryCode in: query description: Country market to search. Specifically, this maps to the Google domain version to query against (e.g., google.com for US, google.de for Germany, etc.). All Countries schema: type: string default: US enum: - AR - AT - AU - BE - BR - CA - CH - DE - DK - ES - FR - IE - IN - IT - JP - MX - NL - 'NO' - NZ - PL - PT - SE - SG - TR - UA - UK - US - ZA example: US example: US - name: sortBy in: query description: Column to sort by. schema: type: string default: SeoClicks const: SeoClicks x-enumDescriptions: SeoClicks: Estimated monthly organic clicks that each new page receives from all of its keyword rankings example: SeoClicks example: SeoClicks - name: sortOrder in: query description: Order to sort the results. schema: type: string default: Descending enum: - Ascending - Descending example: Descending example: Descending - name: startingRow in: query description: Row number to start the results with. schema: type: integer format: int32 default: 1 maximum: 10000 minimum: 1 example: 1 example: 1 responses: '200': description: OK content: application/json: schema: description: Response wrapper containing top pages results with comprehensive SEO performance metrics and traffic analysis. type: object properties: resultCount: description: Number of results returned type: integer format: int32 readOnly: true example: 100 results: description: Array of top-performing pages with organic traffic estimates, keyword rankings, and competitive performance data. type: array items: type: object properties: title: description: The HTML title tag of the page as it appears in search results. This helps identify the page's content focus and SEO optimization strategy. type: string nullable: true example: Best Running Shoes 2024 - Complete Buyer's Guide url: description: The complete URL of the page that ranks for multiple organic keywords. This shows the specific page driving organic traffic for the domain. type: string nullable: true example: https://example.com/best-running-shoes-2024 keywordCount: description: Total number of unique keywords this page ranks for in the top 100 organic search results. Higher counts indicate broader topical coverage. type: integer format: int64 example: 247 estMonthlySeoClicks: description: Estimated total monthly organic clicks this page receives from all keywords it ranks for. This represents the page's overall organic traffic value. type: integer format: int64 example: 15420 topKeyword: description: The highest-value keyword this page ranks for, typically the term driving the most organic traffic to this specific page. type: string nullable: true example: best running shoes topKeywordPosition: description: 'The organic search position (rank) for the top keyword, where 1 represents the #1 organic result on Google.' type: integer format: int32 example: 3 topKeywordSearchVolume: description: Monthly search volume for the top keyword, showing how many people search for this term each month on Google. type: integer format: int64 nullable: true example: 74000 topKeywordClicks: description: Estimated monthly organic clicks this page receives specifically from its top keyword, based on the keyword's search volume and the page's ranking position. type: integer format: int64 example: 8950 additionalProperties: false description: Represents a top-performing page from a domain's organic search portfolio, including traffic estimates, keyword performance, and the page's most valuable search term. readOnly: true nullable: true additionalProperties: false '400': description: Bad Request '401': description: User failed authorization '500': description: Internal Server Error tags: - SEO Research API components: securitySchemes: Basic_Authentication_Token: type: http description: 'Basic Authentication is a standard that involves encoding your SPYFU_API_ID:SECRET_KEY into a Base64 string. Your SpyFu API ID and Secret Key can both be found under the Account Settings -> API Usage page. Additionally, you can find the Base64 string has been pre-generated on the same page under Base 64 Key. Finally, this encoded string is sent in the "Authorization" header prefixed with the keyword "Basic":
For example, to authorize as 00000000-0000-0000-0000-000000000000:AB12WXYZ the client would send
Authorization: Basic MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwOkFCMTJXWFla
' scheme: basic Query_Parameter_Token: type: apiKey description: An API key can be added as a query parameter. Your API key is listed as "Secret Key" found under the Account Settings -> API Usage page
For example, to authorize with the API key AB12WXY
/apis/example_api/GetExample?domain=spyfu.com&api_key=AB12WXYZ
name: api_key in: query HMAC_Authentication_Header: type: apiKey description: For even more security, each request can be individually authenticated with a timestamped HMAC (Hash Message Authentication Code) signature. Composed of your secret key, a valid timestamp, the API request path, and all request parameters.

Creating the signature:


Combine the pieces that will be converted into the signature.
StringToSign =
HTTP-Verb + "\n" +
Timestamp + "\n" +
UrlPath + "\n"
QueryParameters;

Create UTF-8 encodings of the above string and of your secret key.
byte[] SecretKeyBytes = UTF-8-Encoding-Of( Upper-Case-Of( SECRET_KEY ) );
byte[] StringToSignBytes = UTF-8-Encoding-Of( StringToSign );

Use an implementation of HMAC256 using your UTF-8 secret key to encode the combined string of your request. This should then be converted to Base64 to finish creating your signature.
Signature = Base64( HMAC-SHA256( SecretKeyBytes, StringToSignBytes ) );

Using the signature:


This signature is then sent in through an Authentication header with your username.
Authentication: UserName:Signature
name: Authentication in: header