openapi: 3.0.3
info:
title: Account Account API Ranking History 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: Ranking History API
paths:
/v2/historic/getHistoricRankingsForDomain:
get:
operationId: HistoricRanking_GetHistoricRankingsForDomain_GET
summary: Get Domain Ranking History
description: 'Returns historical organic ranking data for a domain across multiple keywords within a specified date range. Track position changes, click gains/losses, and ranking trends over time to analyze SEO performance.
[Visualize this API live on SpyFu](https://www.spyfu.com/seo/ranking-history/domain?expandChart=false&searchType=MostValuable&includeAnyTerm=true&query=example.com&sidebarContext=topics) _(TODO – verify)_'
parameters:
- name: domain
in: query
description: Domain to analyze ranking history for.
required: true
schema:
type: string
example: example.com
example: example.com
- name: queryType
in: query
description: Type of ranking analysis to perform.
schema:
type: string
enum:
- MostValuable
- FellFromTop10
- MadeTheTop10
- NewKeywords
- NoLongerRanks
- GainedRanks
- LostRanks
- GainedClicks
- LostClicks
example: MostValuable
example: MostValuable
- name: startDate
in: query
description: Beginning date for range
schema:
type: string
format: date-time
example: 2025-01
example: 2025-01
- name: endDate
in: query
description: Ending date for range
schema:
type: string
format: date-time
example: 2025-07
example: 2025-07
- 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: startRank.min
in: query
description: Filter to keywords where the domain/URL starting rank position is ≥ this value for the selected date range (1 = best/top organic result).
schema:
type: number
format: float
- name: startRank.max
in: query
description: Filter to keywords where the domain/URL starting rank position is ≤ this value for the selected date range (1 = best/top organic result).
schema:
type: number
format: float
- name: endRank.min
in: query
description: Filter to keywords where the domain/URL ending rank position is ≥ this value for the selected date range (1 = best/top organic result).
schema:
type: number
format: float
- name: endRank.max
in: query
description: Filter to keywords where the domain/URL ending rank position is ≤ this value for the selected date range (1 = best/top organic result).
schema:
type: number
format: float
- name: endRankChange.min
in: query
description: Filter to keywords where the rank improved by at least this many positions between the start and end of the date range (end_rank_change ≥ value). Positive values mean moved up; negative values mean moved down.
schema:
type: number
format: float
- name: endRankChange.max
in: query
description: Filter to keywords where the rank change was at most this many positions between the start and end of the date range (end_rank_change ≤ value). Positive values mean moved up; negative values mean moved down.
schema:
type: number
format: float
- 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
- 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
- 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
- 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
- name: searchVolume.min
in: query
description: Filter to keywords where monthly search volume (Google) is ≥ this value.
schema:
type: number
format: float
- name: searchVolume.max
in: query
description: Filter to keywords where monthly search volume (Google) is ≤ this value.
schema:
type: number
format: float
- 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: Field to sort by
schema:
type: string
enum:
- ClicksChange
- EndClicks
- StartRank
- EndRank
- RankChange
- 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: 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: sortOrder
in: query
description: Order to sort by
schema:
type: string
enum:
- Ascending
- Descending
responses:
'200':
description: Successfully retrieved domain ranking history data
content:
application/json:
schema:
type: object
properties:
resultCount:
description: Number of results returned
type: integer
format: int32
readOnly: true
example: 100
results:
type: array
items:
type: object
properties:
keyword:
type: string
nullable: true
historicalRanks:
type: object
additionalProperties:
type: integer
format: int32
nullable: true
startRank:
type: integer
format: int32
nullable: true
endRank:
type: integer
format: int32
nullable: true
rankChange:
type: integer
format: int32
nullable: true
endClicks:
type: integer
format: int64
clicksChange:
type: integer
format: int64
searchVolume:
type: integer
format: int64
nullable: true
additionalProperties: false
readOnly: true
nullable: true
totalVolume:
type: integer
format: int64
readOnly: true
totalClicks:
type: integer
format: int64
readOnly: true
totalClicksChange:
type: integer
format: int64
readOnly: true
totalRankChange:
type: integer
format: int64
readOnly: true
rankAverage:
type: number
format: double
readOnly: true
rankAverageChange:
type: number
format: double
readOnly: true
totalMatchingResults:
type: integer
format: int64
readOnly: true
additionalProperties: false
'400':
description: Invalid request parameters or date range
'401':
description: User failed authorization
'500':
description: Server error while processing ranking history data
tags:
- Ranking History API
/v2/historic/getHistoricRankingsForKeywordOnDomains:
get:
operationId: HistoricRanking_GetHistoricRankingsForKeywordOnDomains_GET
summary: Get Keyword Domain Rankings
description: 'Returns historical organic ranking data for a specific keyword across multiple specified domains within a date range. Compare how different domains have performed for the same keyword over time.
[Visualize this API live on SpyFu](https://www.spyfu.com/keyword/ranking-history?query=example%20keyword) _(TODO – verify)_'
parameters:
- name: keyword
in: query
description: Keyword to analyze ranking history for.
required: true
schema:
type: string
example: best running shoes
- name: domains
in: query
description: Comma-separated list of domains to compare rankings for.
required: true
schema:
type: string
example: example.com,competitor1.com,competitor2.com
- name: startDate
in: query
description: Beginning date for range
schema:
type: string
format: date-time
example: 2025-01
example: 2025-01
- name: endDate
in: query
description: Ending date for range
schema:
type: string
format: date-time
example: 2025-07
example: 2025-07
- 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 keyword ranking history across specified domains
content:
application/json:
schema:
type: object
properties:
resultCount:
description: Number of results returned
type: integer
format: int32
readOnly: true
example: 100
results:
type: array
items:
type: object
properties:
domain:
type: string
nullable: true
keyword:
type: string
nullable: true
results:
type: object
additionalProperties:
type: integer
format: int32
nullable: true
additionalProperties: false
nullable: true
additionalProperties: false
'400':
description: Invalid request parameters, keyword, or domain list
'401':
description: User failed authorization
'500':
description: Server error while processing ranking history data
tags:
- Ranking History API
/v2/historic/getHistoricRankingsForDomainOnKeywords:
get:
operationId: HistoricRanking_GetHistoricRankingsForDomainOnKeywords_GET
summary: Get Domain Keyword Rankings
description: 'Returns historical organic ranking data for a specific domain across multiple specified keywords within a date range. Analyze how a domain''s positions have changed over time for your target keyword list.
[Visualize this API live on SpyFu](https://www.spyfu.com/seo/ranking-history/domain?expandChart=false&searchType=MostValuable&includeAnyTerm=true&query=example.com&sidebarContext=topics) _(TODO – verify)_'
parameters:
- name: domain
in: query
description: Domain to analyze ranking history for.
required: true
schema:
type: string
example: example.com
- name: keywords
in: query
description: Comma-separated list of keywords to analyze rankings for.
required: true
schema:
type: string
example: best running shoes,nike shoes,athletic footwear
- name: startDate
in: query
description: Beginning date for range
schema:
type: string
format: date-time
example: 2025-01
example: 2025-01
- name: endDate
in: query
description: Ending date for range
schema:
type: string
format: date-time
example: 2025-07
example: 2025-07
- 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
x-enumDescriptions:
AR: Argentina
AT: Austria
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
responses:
'200':
description: Successfully retrieved domain ranking history for specified keywords
content:
application/json:
schema:
type: object
properties:
resultCount:
description: Number of results returned
type: integer
format: int32
readOnly: true
example: 100
results:
type: array
items:
type: object
properties:
domain:
type: string
nullable: true
keyword:
type: string
nullable: true
results:
type: object
additionalProperties:
type: integer
format: int32
nullable: true
additionalProperties: false
nullable: true
additionalProperties: false
'400':
description: Invalid request parameters, domain, or keyword list
'401':
description: User failed authorization
'500':
description: Server error while processing ranking history data
tags:
- Ranking History 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 pageAB12WXY/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. StringToSign =
HTTP-Verb + "\n" +
Timestamp + "\n" +
UrlPath + "\n"
QueryParameters;
byte[] SecretKeyBytes = UTF-8-Encoding-Of( Upper-Case-Of( SECRET_KEY ) );
byte[] StringToSignBytes = UTF-8-Encoding-Of( StringToSign );
Signature = Base64( HMAC-SHA256( SecretKeyBytes, StringToSignBytes ) );
Authentication: UserName:Signature
name: Authentication
in: header