SpyFu SEO Research API API

The SEO Research API API from SpyFu — 17 operation(s) for seo research api.

OpenAPI Specification

spyfu-seo-research-api-api-openapi.yml Raw ↑
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.).  <a href='https://developer.spyfu.com/reference/adhistoryapi_getdomainadhistory_get#/'>All Countries</a>
        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 

# --- truncated at 32 KB (402 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spyfu/refs/heads/main/openapi/spyfu-seo-research-api-api-openapi.yml