SpyFu Keyword Research API API

The Keyword Research API API from SpyFu — 7 operation(s) for keyword research api.

OpenAPI Specification

spyfu-keyword-research-api-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Account Account API Keyword 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: Keyword Research API
paths:
  /v2/related/getKeywordExpansions:
    get:
      operationId: RelatedKeywordsV2Api_GetKeywordExpansions_GET
      summary: Get Keywords, All Sorts
      description: 'Performs 5 types of keyword research via keywordSearchType parameter: PhraseMatch (thematic similarities), Questions (interrogative queries), AlsoBuysAdsFor (co-targeted PPC terms), AlsoRanksFor (co-ranking SEO terms), Transactions (commercial intent). Set keywordSearchType to select method.'
      parameters:
      - name: query
        in: query
        description: The keyword to query for.
        required: true
        schema:
          type: string
          example: shoes
        example: shoes
      - name: keywordSearchType
        in: query
        description: 'Required. Selects keyword research method: PhraseMatch=thematically related, Questions=interrogative forms, AlsoBuysAdsFor=keywords co-targeted in ads, AlsoRanksFor=keywords co-ranking organically, Transactions=purchase-intent keywords. Each returns different keyword relationships.'
        required: true
        schema:
          type: string
          default: PhraseMatch
          enum:
          - AlsoBuysAdsFor
          - AlsoRanksFor
          - PhraseMatch
          - Questions
          - Transactions
          x-enum-descriptions:
            AlsoBuysAdsFor: Returns keywords that advertisers commonly target together with the query keyword in PPC campaigns. Analyzes co-targeting patterns in paid search advertising.
            AlsoRanksFor: Returns keywords that websites ranking for the query keyword also rank for organically. Analyzes co-ranking patterns in organic search results.
            PhraseMatch: Returns keywords thematically and semantically related to the query keyword. Finds terms with similar meaning, context, or category associations.
            Questions: Returns question-format keywords related to the query topic. Includes who, what, when, where, why, how queries that users search.
            Transactions: Returns keywords with commercial/transactional intent related to the query. Identifies buying-signal terms like buy, price, deal, discount, review.
          example: PhraseMatch
        example: PhraseMatch
      - 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: searchVolume.min
        in: query
        description: Filter by the number of searches done this past month on Google.
        schema:
          type: number
          format: float
      - name: searchVolume.max
        in: query
        description: Filter by the number of searches done this past month on Google.
        schema:
          type: number
          format: float
      - name: liveSearchVolume.min
        in: query
        description: Filter by the number of searches done this past month on Google. This value is refreshed each month.
        schema:
          type: number
          format: float
      - name: liveSearchVolume.max
        in: query
        description: Filter by the number of searches done this past month on Google. This value is refreshed each month.
        schema:
          type: number
          format: float
      - name: keywordDifficulty.min
        in: query
        description: Filter by how difficult it is to rank on this keyword.  This can also be called Ranking Difficulty.
        schema:
          type: number
          format: float
      - name: keywordDifficulty.max
        in: query
        description: Filter by how difficult it is to rank on this keyword.  This can also be called Ranking Difficulty.
        schema:
          type: number
          format: float
      - name: costPerClick.min
        in: query
        description: Filter by the average cost per click.  This will use the keyword matching option selected in `costPerClickOption`
        schema:
          type: number
          format: float
      - name: costPerClick.max
        in: query
        description: Filter by the average cost per click.  This will use the keyword matching option selected in `costPerClickOption`
        schema:
          type: number
          format: float
      - name: costPerClickOption
        in: query
        description: Cost per click keyword matching option to filter results by.
        schema:
          type: string
          enum:
          - Broad
          - Exact
          - Phrase
          example: Broad
        example: Broad
      - name: wordCount.min
        in: query
        description: Filter by the number of words in the keyword.
        schema:
          type: number
          format: float
      - name: wordCount.max
        in: query
        description: Filter by the number of words in the keyword.
        schema:
          type: number
          format: float
      - name: clicks.min
        in: query
        description: Filter by the number of total monthly clicks on the SERP for this keyword--organic and paid.
        schema:
          type: number
          format: float
      - name: clicks.max
        in: query
        description: Filter by the number of total monthly clicks on the SERP for this keyword--organic and paid.
        schema:
          type: number
          format: float
      - name: isQuestion
        in: query
        description: Filter on if the keyword is a question.
        schema:
          type: boolean
          default: false
          example: false
        example: false
      - name: isTransactionalIntent
        in: query
        description: Filter on if the keyword has transactional intent.
        schema:
          type: boolean
          default: false
          example: false
        example: false
      - name: serpFirstResult
        in: query
        description: 'Filter to keywords where this specific domain ranks #1 in organic search results. Useful for identifying keywords where a particular competitor dominates.'
        schema:
          type: string
          example: example.com
      - name: mobileSearchesPercentage.min
        in: query
        description: Filter by the percentage of searches that are done on mobile devices.
        schema:
          type: number
          format: float
      - name: mobileSearchesPercentage.max
        in: query
        description: Filter by the percentage of searches that are done on mobile devices.
        schema:
          type: number
          format: float
      - name: desktopSearchesPercentage.min
        in: query
        description: Filter by the percentage of searches that are done on desktop devices.
        schema:
          type: number
          format: float
      - name: desktopSearchesPercentage.max
        in: query
        description: Filter by the percentage of searches that are done on desktop devices.
        schema:
          type: number
          format: float
      - name: notClickedSearchesPercentage.min
        in: query
        description: 'Filter by the percentage of searches that are not clicked.

          Some keyword searches supply clear information in a featured snippet or similar displays. They don''t require a click to get the information. Those will have higher percentages in this metric.'
        schema:
          type: number
          format: float
      - name: notClickedSearchesPercentage.max
        in: query
        description: 'Filter by the percentage of searches that are not clicked.

          Some keyword searches supply clear information in a featured snippet or similar displays. They don''t require a click to get the information. Those will have higher percentages in this metric.'
        schema:
          type: number
          format: float
      - name: paidClickSearchPercentage.min
        in: query
        description: Filter by the percentage of clicks that go to ads.
        schema:
          type: number
          format: float
      - name: paidClickSearchPercentage.max
        in: query
        description: Filter by the percentage of clicks that go to ads.
        schema:
          type: number
          format: float
      - name: organicClicksSearchPercentage.min
        in: query
        description: Filter by the percentage of clicks that go to organic results, not ads.
        schema:
          type: number
          format: float
      - name: organicClicksSearchPercentage.max
        in: query
        description: Filter by the percentage of clicks that go to organic results, not ads.
        schema:
          type: number
          format: float
      - name: monthlyCost.min
        in: query
        description: Filter by the monthly cost of the keyword.  This will use the keyword matching option selected in `monthlyCostOption`
        schema:
          type: number
          format: float
      - name: monthlyCost.max
        in: query
        description: Filter by the monthly cost of the keyword.  This will use the keyword matching option selected in `monthlyCostOption`
        schema:
          type: number
          format: float
      - name: monthlyCostOption
        in: query
        description: Monthly Cost keyword matching option to filter results by.
        schema:
          type: string
          enum:
          - Broad
          - Exact
          - Phrase
          example: Broad
        example: Broad
      - name: rankingHomepages.min
        in: query
        description: Homepages on the SERP range to filter results by.
        schema:
          type: number
          format: float
      - name: rankingHomepages.max
        in: query
        description: Homepages on the SERP range to filter results by.
        schema:
          type: number
          format: float
      - name: adCount.min
        in: query
        description: Filter by the number of total advertisers
        schema:
          type: number
          format: float
      - name: adCount.max
        in: query
        description: Filter by the number of total advertisers
        schema:
          type: number
          format: float
      - 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 by.
        schema:
          type: string
          default: null
          enum:
          - SearchVolume
          - LiveSearchVolume
          - RankingDifficulty
          - TotalMonthlyClicks
          - PercentMobileSearches
          - PercentDesktopSearches
          - PercentSearchesNotClicked
          - PercentPaidClicks
          - PercentOrganicClicks
          - BroadCostPerClick
          - PhraseCostPerClick
          - ExactCostPerClick
          - BroadMonthlyClicks
          - PhraseMonthlyClicks
          - ExactMonthlyClicks
          - BroadMonthlyCost
          - PhraseMonthlyCost
          - ExactMonthlyCost
          - PaidCompetitors
          - RankingHomepages
          x-enumDescriptions:
            SearchVolume: Monthly search volume
            LiveSearchVolume: Real-time search volume data
            RankingDifficulty: SEO competition difficulty score
            TotalMonthlyClicks: Estimated total monthly clicks
            PercentMobileSearches: Percentage of searches from mobile devices
            PercentDesktopSearches: Percentage of searches from desktop devices
            PercentSearchesNotClicked: Percentage of searches resulting in no clicks
            PercentPaidClicks: Percentage of clicks going to paid results
            PercentOrganicClicks: Percentage of clicks going to organic results
            BroadCostPerClick: Broad match cost per click estimate
            PhraseCostPerClick: Phrase match cost per click estimate
            ExactCostPerClick: Exact match cost per click estimate
            BroadMonthlyClicks: Estimated monthly clicks for broad match
            PhraseMonthlyClicks: Estimated monthly clicks for phrase match
            ExactMonthlyClicks: Estimated monthly clicks for exact match
            BroadMonthlyCost: Estimated monthly cost for broad match
            PhraseMonthlyCost: Estimated monthly cost for phrase match
            ExactMonthlyCost: Estimated monthly cost for exact match
            PaidCompetitors: Number of paid search competitors
            RankingHomepages: Number of homepages ranking organically
          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
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  resultCount:
                    description: Number of results returned
                    type: integer
                    format: int32
                    readOnly: true
                    example: 100
                  totalMatchingResults:
                    description: "The total number of results available that matches the query including\r\nitems that might not be included in the returned results/page."
                    type: integer
                    format: int64
                    readOnly: true
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        keyword:
                          description: By looking at strong competitors in this niche and their most trusted keywords over time, we suggest similar keywords here that we found to be profitable for your competition.
                          type: string
                          nullable: true
                          example: red shoes
                        searchVolume:
                          description: This is the estimated number of times this past month that people have searched this keyword. The numbers reflect searches done in the US on Google.com (or in the UK on Google.co.uk if you are looking at UK data). We blend data from multiple sources to give a truer snapshot of activity on this keyword.
                          type: integer
                          format: int64
                          nullable: true
                          example: 266000
                        liveSearchVolume:
                          description: This metric displays a more likely SV based on recent trends or out-of-date estimates. The original volume remains unchanged in any domain's rolled-up metrics.
                          type: integer
                          format: int64
                          nullable: true
                          example: 82000
                        rankingDifficulty:
                          description: We've calculated how difficult it would be to rank on this keyword. The score is based on a scale of 0-100 (with 100 being the most difficult to rank for). Compare this number to other keywords you're targeting to get an idea of how to prioritize your SEO campaign.
                          type: integer
                          format: int32
                          nullable: true
                          example: 98
                        totalMonthlyClicks:
                          description: This is the total number of all clicks (organic and paid) made on the SERP over the past month.
                          type: integer
                          format: int64
                          nullable: true
                          example: 219000
                        percentMobileSearches:
                          description: When we have a breakdown of how many of the searches for this keyword come from mobile vs desktop, we will show it here.
                          type: number
                          format: double
                          nullable: true
                          example: 0.52009505
                        percentDesktopSearches:
                          description: When we have a breakdown of how many of the searches for this keyword come from desktop vs mobile, we will show it here.
                          type: number
                          format: double
                          nullable: true
                          example: 0.47990492
                        percentSearchesNotClicked:
                          description: Some SERPs return enough information that the user does not have to click any results. There might also be unexpected results that cause the user to abandon the SERP without any clicks. This is the rate that searchers leave the page without clicking any result.
                          type: number
                          format: double
                          nullable: true
                          example: 0.1792681
                        percentPaidClicks:
                          description: Of all clicks made to this keyword's SERP, this percentage measures how many went to the paid ads.
                          type: number
                          format: double
                          nullable: true
                          example: 0.52188635
                        percentOrganicClicks:
                          description: Of all clicks made to this keyword's SERP, this percentage measures how many went to organic results.
                          type: number
                          format: double
                          nullable: true
                          example: 0.47811362
                        broadCostPerClick:
                          description: "This is the average amount an advertiser pays Google anytime someone clicks their ad on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 0.73
                        phraseCostPerClick:
                          description: "This is the average amount an advertiser pays Google anytime someone clicks their ad on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 0.67
                        exactCostPerClick:
                          description: "This is the average amount an advertiser pays Google anytime someone clicks their ad on this keyword. These costs fluctuate depending on many factors, so keep that in mind when you are estimating larger budgets.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 0.65
                        broadMonthlyClicks:
                          description: Estimated monthly clicks for broad match advertising on this keyword, calculated from search volume and expected click-through rates.
                          type: number
                          format: float
                          nullable: true
                          example: 57019.8
                        phraseMonthlyClicks:
                          description: Estimated monthly clicks for phrase match advertising on this keyword, calculated from search volume and expected click-through rates.
                          type: number
                          format: float
                          nullable: true
                          example: 42150.3
                        exactMonthlyClicks:
                          description: Estimated monthly clicks for exact match advertising on this keyword, calculated from search volume and expected click-through rates.
                          type: number
                          format: float
                          nullable: true
                          example: 29094.6
                        broadMonthlyCost:
                          description: "Our estimate of what an advertiser would spend, on average, to advertise on this keyword each month.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 41604.9
                        phraseMonthlyCost:
                          description: "Our estimate of what an advertiser would spend, on average, to advertise on this keyword each month.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 25542
                        exactMonthlyCost:
                          description: "Our estimate of what an advertiser would spend, on average, to advertise on this keyword each month.\r\n<p>These costs can vary depending on how specific (exact match vs. phrase match vs. broad match) the search is.</p>"
                          type: number
                          format: double
                          nullable: true
                          example: 19041.6
                        paidCompetitors:
                          description: This is the total number of advertisers we've seen over the last 14 months for this keyword. It's helpful to know how competitive the field is and how many advertisers have tested this keyword over time.
                          type: integer
                          format: int32
                          nullable: true
                          example: 15
                        distinctCompetitors:
                          description: This is the list of distinct advertisers we've seen over the last 14 months for this keyword.
                          type: array
                          items:
                            type: string
                          nullable: true
                        rankingHomepages:
                          description: We roll up the number of home pages that rank within the first 50 results for this keyword. (It doesn't count ads, only organic results.) A homepage might be "https://webmd.com" vs a longer path like "https://www.webmd.com/fitness-exercise".
                          type: integer
                          format: int32
                          nullable: true
                          example: 8
                        serpFeaturesCsv:
                          description: Comma-separated list of SERP features present for this keyword (e.g., Images, Videos, Maps, Shopping), indicating competition for organic real estate.
                          type: string
                          nullable: true
                          example: Images,Maps
                        serpFirstResult:
                          description: Domain name of the top-ranking organic result for this keyword, useful for identifying category leaders.
                          type: string
                          nullable: true
                          example: example.com
                        isQuestion:
                          description: Indicates whether this keyword is phrased as a question (who, what, when, where, why, how).
                          type: boolean
                          example: false
                        isNotSafeForWork:
                          description: Indicates whether this keyword is flagged as containing adult or inappropriate content.
                          type: boolean
                          example: false
                      additionalProperties: false
                    readOnly: true
                    nullable: true
                additionalProperties: false
        '400':
          description: Bad Request
        '401':
          description: User failed authorization
        '500':
          description: Internal Server Error
      tags:
      - Keyword Research API
  /v2/related/getRelatedKeywords:
    get:
      operationId: RelatedKeywordsV2Api_GetRelatedKeywords_GET
      summary: Get Related Keywords
      description: 'Returns thematically related keywords that share similar categories and themes with your seed keyword. This endpoint helps expand your keyword reach with relevant, competitive terms to broaden your content strategy and advertising opportunities.


        [Visualize this API live on SpyFu](https://www.spyfu.com/keyword/related?query=running+shoes)'
      parameters:
      - name: query
        in: query
        description: Seed keyword to find thematically related keywords for.
        required: true
        schema:
          type: string
          example: running shoes
        example: running shoes
      - 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: searchVolume.min
        in: query
        description: Filter by the number of searches done this past month on Google.
        schema:
          type: number
          format: float
      - name: searchVolume.max
        in: query
        description: Filter by the number of searches done this past month on Google.
        schema:
          type: number
          format: float
      - name: liveSearchVolume.min
        in: query
        description: Filter by the number of searches done this past month on Google. This value is refreshed each month.
        schema:
          type: number
          format: float
      - name: liveSearchVolume.max
        in: query
        description: Filter by the number of searches done this past month on Google. This value is refreshed each month.
        schema:
          type: number
          format: float
      - name: keywordDifficulty.min
        in: query
        description: Filter by how difficult it is to rank on this keyword.  This can also be called Ranking Difficulty.
        schema:
          type: number
          format: float
      - name: keywordDifficulty.max
        in: query
        description: Filter by how difficult it is to rank on this keyword.  This can also be called Ranking Difficulty.
        schema:
          type: number
          format: float
      - name: costPerClick.min
        in: query
        description: Filter by the average cost per click.  This will use the keyword matching option selected in `costPerClickOption`
        schema:
          type: number
          format: float
      - name: costPerClick.max
        in: query
        description: Filter by the average cost per click.  This will use the keyword matching option selected in `costPerClickOption`
        schema:
          type: number
          format: float
      - name: costPerClickOption
        in: query
        description: Cost per click keyword matching option to filter results by.
        schema:
          type: string
          enum:
          - Broad
          - Exact
          - Phrase
          example: Broad
        example: Broad
      - name: wordCount.min
        in: query
        description: Filter by the number of words in the keyword.
        schema:
          type: number
          format: float
      - name: wordCount.max
        in: query
        description: Filter by the number of words in the keyword.
        schema:
          type: number
          format: float
      - name: clicks.min
        in: query
        description: Filter by the number of total monthly clicks on the SERP for this keyword--organic and paid.
        schema:
          type: number
          format: float
      - name: clicks.max
        in: query
        description: Filter by the number of total monthly clicks on the SERP for this keyword--organic and paid.
        schema:
          type: number
          format: float
      - name: isQuestion
        in: query
        description: Filter on if the keyword is a question.
        schema:
          type: boolean
          default: false
          example: false
        example: false
      - name: isTransactionalIntent
        in: query
        description: Filter on if the keyword has transactional intent.
        schema:
          type: boolean
          default: false
          example: false
        example: false
      - name: serpFirstResult
        in: query
        description: 'Filter to keywords where this specific domain ranks #1 in organic search results. Useful for identifying keywords where a particular competitor dominates.'
        schema:
          type: string
          example: example.com
      - name: mobileSearchesPercentage.min
        in: query
        description: Filter by the percentage of searches that are done on mobile devices.
        schema:
          type: number
          form

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