Skip to content

Historical SERPs (Live) Fresh

The Historical SERPs endpoint returns complete Google SERP snapshots collected within a specified date range. You get full ranking data including organic positions, featured snippets, knowledge panels, local packs, and all other SERP elements — by month — for the past 12 months.

Endpoint: POST https://api.dataforseo.com/v3/dataforseo_labs/google/historical_serps/live

Use this endpoint to analyze how rankings have changed over time, detect SERP volatility, and study featured snippet ownership history for any keyword.

Data Availability

  • Historical data covers up to 12 months back from the current date.
  • Each result object in the response represents one SERP snapshot (one month).
  • Each SERP item within a snapshot reflects the ranking state at that point in time.

Request Parameters

FieldTypeRequiredDescription
keywordstringYesTarget keyword. Max 700 characters. All %## sequences decoded; + decoded to space.
location_namestringConditionalFull location name (e.g., "United Kingdom"). Required unless location_code is set.
location_codeintegerConditionalLocation code (e.g., 2840 for USA). Required unless location_name is set.
language_namestringConditionalFull language name (e.g., "English"). Required unless language_code is set.
language_codestringConditionalLanguage code (e.g., "en"). Required unless language_name is set.
date_fromstringNoStart of date range. Format: "yyyy-mm-dd". Min: 365 days ago. If omitted, defaults to 365 days back.
date_tostringNoEnd of date range. Format: "yyyy-mm-dd". Defaults to today if omitted.
tagstringNoCustom task identifier. Max 255 characters.

Note: Each Live API call for this endpoint may contain only one task. Rate limit: 2,000 calls/minute, max 30 simultaneous.

Response Structure

Top-Level Task Fields

FieldTypeDescription
tasks[].result[].keywordstringInput keyword (decoded)
tasks[].result[].location_codeintegerLocation from request
tasks[].result[].language_codestringLanguage from request
tasks[].result[].total_countintegerTotal SERP snapshots in database for this query
tasks[].result[].items_countintegerSnapshots returned in this response
tasks[].result[].items[]arrayIndividual SERP snapshots (one per month)

SERP Snapshot Fields (per item)

FieldTypeDescription
datetimestringDate/time of SERP capture in UTC (yyyy-mm-dd hh-mm-ss +00:00)
se_domainstringSearch engine domain used
check_urlstringDirect URL to verify results in search engine
item_typesarrayAll SERP element types present in this snapshot
se_results_countintegerTotal organic results count
items_countintegerNumber of result items in this snapshot
spellobjectAutocorrection info (if search engine corrected the query)
items[]arrayIndividual SERP result elements

SERP Item Types

The item_types array lists all element types present in the snapshot. Possible values include:

answer_box, carousel, multi_carousel, featured_snippet, google_flights, google_reviews, google_posts, images, jobs, knowledge_graph, local_pack, hotels_pack, map, organic, paid, people_also_ask, related_searches, people_also_search, shopping, top_stories, twitter, video, events, mention_carousel, recipes, top_sights, scholarly_articles, popular_products, podcasts, questions_and_answers, find_results_on, stocks_box, visual_stories, commercial_units, local_services, google_hotels, math_solver, ai_overview

Organic Result Fields

FieldTypeDescription
typestringAlways "organic"
rank_groupintegerPosition within organic results
rank_absoluteintegerAbsolute position among all SERP elements
positionstring"left" or "right"
domainstringDomain of the ranking result
titlestringPage title
urlstringRanking URL
breadcrumbstringBreadcrumb shown in SERP
descriptionstringMeta description or snippet
is_featured_snippetbooleanWhether the result also holds the featured snippet
is_imagebooleanIncludes an image
is_videobooleanIncludes a video
is_maliciousbooleanFlagged as malicious by Google
amp_versionbooleanHas AMP version
highlightedarrayWords bolded in the snippet
ratingobjectStar rating if shown (type, value, votes count, max)
linksarraySitelinks below the result
about_this_resultobject"About this result" panel data
extended_snippetstringAdditional snippet text after the description
pre_snippetstringAdditional text before the description

cURL Example

bash
curl --request POST \
  --url https://api.dataforseo.com/v3/dataforseo_labs/google/historical_serps/live \
  --header 'Authorization: Basic BASE64(login:password)' \
  --header 'Content-Type: application/json' \
  --data '[
    {
      "keyword": "best roofing contractor miami",
      "location_code": 2840,
      "language_code": "en",
      "date_from": "2024-06-01",
      "date_to": "2025-05-01"
    }
  ]'

Python Example

python
import requests
from requests.auth import HTTPBasicAuth
import json
from datetime import datetime, timedelta

def historical_serps(keyword, location_code=2840, language_code="en", months_back=12):
    date_to = datetime.now().strftime("%Y-%m-%d")
    date_from = (datetime.now() - timedelta(days=months_back * 30)).strftime("%Y-%m-%d")

    payload = [{
        "keyword": keyword,
        "location_code": location_code,
        "language_code": language_code,
        "date_from": date_from,
        "date_to": date_to
    }]

    response = requests.post(
        "https://api.dataforseo.com/v3/dataforseo_labs/google/historical_serps/live",
        auth=HTTPBasicAuth("your_login", "your_password"),
        headers={"Content-Type": "application/json"},
        data=json.dumps(payload)
    )

    data = response.json()
    snapshots = data["tasks"][0]["result"][0]["items"]
    return snapshots


def track_domain_rank_over_time(keyword, target_domain, location_code=2840):
    snapshots = historical_serps(keyword, location_code)

    rankings = []
    for snapshot in snapshots:
        date = snapshot["datetime"][:10]  # yyyy-mm-dd
        serp_items = snapshot.get("items", [])

        rank = None
        for item in serp_items:
            if item.get("type") == "organic" and target_domain in item.get("domain", ""):
                rank = item["rank_absolute"]
                break

        rankings.append({"date": date, "rank": rank})

    return rankings


# Usage
history = track_domain_rank_over_time(
    "roof repair miami fl",
    "bestroofingmiami.com"
)

for entry in history:
    rank_display = entry["rank"] if entry["rank"] else "not ranking"
    print(f"{entry['date']}: position {rank_display}")

Use Cases

Rank Tracking History — Plot a domain's organic position for a keyword over 12 months without requiring a separate rank tracking subscription.

SERP Volatility Analysis — Compare item_types across months to detect when features like local_pack or ai_overview appeared or disappeared.

Featured Snippet Ownership — Track which domain held the featured snippet and when ownership changed.

Competitor Monitoring — Identify when a competitor entered or dropped out of the top 10 for a target keyword.

Algorithm Impact Assessment — Correlate ranking changes with known Google algorithm update dates.

Notes

  • Each POST request for this endpoint can contain only one task (unlike most other endpoints that allow batching).
  • The check_url field in each snapshot can be opened in Incognito mode to verify results.
  • The spell object indicates when Google's autocorrection redirected the query — important for understanding which keyword the SERP actually represents.
  • Use %25 for literal % characters in keywords and %2B for literal + characters.

Internal SOP reference — not affiliated with DataForSEO.