---
title: "Search Console hourly API data: request and check recent hours"
description: "Request hourly Search Console data with hour and hourly_all. Preserve timestamp offsets and inspect incomplete-hour metadata before comparing recent traffic."
canonical_url: "https://gscdump.com/learn-google-search-console/api/hourly-search-analytics-api"
last_updated: "2026-09-11"
---

To request hourly Google Search Console data, group by **`hour`** and set **`dataState` to `hourly_all`**. Google provides up to **10 days** of hourly history through the Search Analytics API, compared with the recent 24-hour window in the interface. [Google introduced hourly API data in April 2025](https://developers.google.com/search/blog/2025/04/san-hourly-data).

Start with one day and no page or query filters. Check the returned timestamps and incomplete-data metadata before building a larger comparison.

## Make one request

You need an [OAuth access token](/learn-google-search-console/api/authentication) with access to the property and the `webmasters.readonly` scope, or the broader `webmasters` scope. A Google API key by itself doesn't authorize this request. The [query reference](https://developers.google.com/webmaster-tools/v1/searchanalytics/query) lists the accepted scopes and property formats.

This example uses a Domain property. Replace it with your property and choose a recent date within the hourly window. Both date endpoints are inclusive and use Pacific Time.

```js
const siteUrl = 'sc-domain:example.com'
const accessToken = process.env.GOOGLE_ACCESS_TOKEN

if (!accessToken)
  throw new Error('Set GOOGLE_ACCESS_TOKEN before requesting data.')

const response = await fetch(
  `https://www.googleapis.com/webmasters/v3/sites/${encodeURIComponent(siteUrl)}/searchAnalytics/query`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      startDate: '2026-09-10',
      endDate: '2026-09-10',
      dimensions: ['hour'],
      dataState: 'hourly_all',
      type: 'web',
    }),
  },
)

if (!response.ok)
  throw new Error(`Search Console returned HTTP ${response.status}.`)

const result = await response.json()
console.log(JSON.stringify(result, null, 2))
```

Run this as a `.mjs` file in a Node version with built-in `fetch`, with the token supplied through your environment. Update the example date before running it later. Keep the token out of source files and shared terminal logs.

The request shape was checked against Google's documentation. The code was exercised with local response fixtures, including an HTTP failure. It wasn't run against an authenticated Google API account for this article.

## Read the incomplete-hour boundary

The current [API discovery schema](https://searchconsole.googleapis.com/$discovery/rest?version=v1), revision `20260909`, names the JSON field **`metadata.firstIncompleteHour`**. Google's descriptive text also refers to it as `first_incomplete_hour`; use the camelCase field when reading JSON.

For example, this is an **illustrative metadata fragment**, not a captured response:

```json
{
  "metadata": {
    "firstIncompleteHour": "2026-09-10T15:00:00-07:00"
  }
}
```

Treat **15:00 and later** as incomplete in this example. The field marks the first affected hour, so excluding only hours after 15:00 would leave that incomplete hour in your comparison.

Preserve the offset in each timestamp. Compare parsed instants when ordering rows; don't strip the offset or assume the browser's local time matches the report. The discovery schema describes this metadata in the `America/Los_Angeles` time zone.

## Compare matching hours

For a daily check, compare the same completed portion of each day. If today's data is incomplete from 15:00, comparing it with all of yesterday would build a shortfall into the calculation.

Keep incomplete hours visible as provisional data when they help you monitor a new page. Separate them from any total you label finished. Re-request recent periods when you need to update a saved result.

A missing metadata field doesn't prove complete coverage. It also doesn't turn absent rows into zero-traffic hours. Check the date window, filters, and response before filling gaps in a chart. The API [returns top rows rather than guaranteeing every data row](https://developers.google.com/webmaster-tools/v1/searchanalytics/query).

If you only need an interactive check of the latest available hours, use the report's **24 hours** view. Use [daily, weekly, or monthly views](/learn-google-search-console/weekly-monthly-views) for longer trends; the hourly window doesn't replace daily history.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
