JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 9
  • Score
    100M100P100Q68746F
  • License MIT

Google Search Console API client with OAuth2/service account auth, rate limiting, and retry

Package Exports

  • @power-seo/search-console

Readme

@power-seo/search-console

search-console banner

Typed Google Search Console API client for TypeScript — OAuth2 and service account auth, auto-paginated search analytics, URL inspection, and sitemap management with zero boilerplate.

npm version npm downloads Socket License: MIT TypeScript tree-shakeable

@power-seo/search-console is a production-ready Google Search Console API client for TypeScript. Provide OAuth2 credentials or a service account key — get back fully typed search analytics rows, URL inspection verdicts, and sitemap management operations. The token manager handles refresh cycles and JWT signing automatically. querySearchAnalyticsAll() transparently pages through the 25,000-row GSC API limit, merging all results into a single array. Use it in Next.js API routes, Remix loaders, Node.js scripts, and CI/CD pipelines. All operations are server-side only — service account credentials must never be exposed to the browser.

Zero runtime dependencies — pure TypeScript with native fetch and crypto; no googleapis package required.


Why @power-seo/search-console?

Without With
OAuth2 token refresh ❌ 50+ lines of boilerplate per project ✅ Auto-refresh via createTokenManager()
GSC data pagination ❌ Manual rowOffset loops and array merging querySearchAnalyticsAll() — one call, all rows
URL inspection ❌ Manual GSC UI check only ✅ Programmatic inspectUrl() in CI pipelines
Service accounts ❌ Complex JWT signing setup createTokenManager({ type: 'service-account' })
Type safety ❌ Raw API responses typed as any ✅ Fully typed request and response shapes
Sitemap management ❌ Manual GSC UI operations submitSitemap(), listSitemaps(), deleteSitemap()
Framework support ❌ Tied to googleapis setup ✅ Works in Next.js, Remix, Node.js, CI/CD

Search Console Comparison


Features

  • OAuth2 authenticationcreateTokenManager({ type: 'oauth' }) handles token refresh automatically
  • Service account JWT authenticationcreateTokenManager({ type: 'service-account' }) signs JWTs for server-to-server access without user interaction
  • Low-level auth primitivesexchangeRefreshToken() and getServiceAccountToken() for custom auth flows
  • Typed GSC clientcreateGSCClient(config) returns a GSCClient scoped to a specific verified site URL
  • Search analyticsquerySearchAnalytics() supports all 6 dimensions: query, page, country, device, date, searchAppearance
  • All search typesweb, image, video, and news search types
  • Auto-paginated full fetchquerySearchAnalyticsAll() merges all pages into one SearchAnalyticsRow[] array
  • URL inspectioninspectUrl() returns verdict, indexing state, last crawl time, mobile usability, and rich result status
  • Direct URL inspectioninspectUrlDirect() for the direct URL inspection API endpoint
  • Sitemap listinglistSitemaps() with status, last download time, and error counts
  • Sitemap submission and deletionsubmitSitemap() and deleteSitemap()
  • Typed error handlingGSCApiError class with status, code, and message
  • Full TypeScript support — complete type definitions for all request and response shapes

Search Console Dashboard UI


Comparison

Feature google-auth-library googleapis custom fetch @power-seo/search-console
OAuth2 token auto-refresh
Service account JWT signing
Auto-paginated analytics fetch
Typed GSC-specific response shapes ⚠️
URL inspection support ⚠️
Sitemap management ⚠️
Zero runtime dependencies
TypeScript-first ⚠️

Pagination Accuracy


Installation

npm install @power-seo/search-console
yarn add @power-seo/search-console
pnpm add @power-seo/search-console

Quick Start

import {
  createTokenManager,
  createGSCClient,
  querySearchAnalyticsAll,
} from '@power-seo/search-console';

// 1. Create a token manager (OAuth2)
import { exchangeRefreshToken } from '@power-seo/search-console';

const tokenManager = createTokenManager(() =>
  exchangeRefreshToken({
    clientId: process.env.GSC_CLIENT_ID!,
    clientSecret: process.env.GSC_CLIENT_SECRET!,
    refreshToken: process.env.GSC_REFRESH_TOKEN!,
  }),
);

// 2. Create a client scoped to your site
const client = createGSCClient({
  siteUrl: 'https://example.com',
  auth: tokenManager,
});

// 3. Fetch all search analytics data (auto-paginated)
const rows = await querySearchAnalyticsAll(client, {
  startDate: '2026-01-01',
  endDate: '2026-01-31',
  dimensions: ['query', 'page'],
});

rows.forEach(({ keys, clicks, impressions, ctr, position }) => {
  console.log(`Query: "${keys[0]}", Page: ${keys[1]}`);
  console.log(`  ${clicks} clicks, ${impressions} impressions, pos ${position.toFixed(1)}`);
});

Auth Benefit


Usage

OAuth2 Authentication

import { createTokenManager, exchangeRefreshToken } from '@power-seo/search-console';

const tokenManager = createTokenManager(() =>
  exchangeRefreshToken({
    clientId: process.env.GSC_CLIENT_ID!,
    clientSecret: process.env.GSC_CLIENT_SECRET!,
    refreshToken: process.env.GSC_REFRESH_TOKEN!,
  }),
);

const accessToken = await tokenManager.getToken();

Service Account Authentication

import { createTokenManager, getServiceAccountToken } from '@power-seo/search-console';
import { subtle } from 'node:crypto';

// Parse service account JSON and create signing function
const serviceAccount = JSON.parse(process.env.GSC_SERVICE_ACCOUNT_JSON!);

async function signJwt(payload: Record<string, unknown>): Promise<string> {
  // Implement JWT signing using node:crypto or your preferred library
  // Returns signed JWT assertion string
}

const tokenManager = createTokenManager(() =>
  getServiceAccountToken({
    clientEmail: serviceAccount.client_email,
    privateKeyId: serviceAccount.private_key_id,
    signJwt,
  }),
);

Search Analytics Query

import { createGSCClient, querySearchAnalytics } from '@power-seo/search-console';

const client = createGSCClient({ siteUrl: 'https://example.com', tokenManager });

const response = await querySearchAnalytics(client, {
  startDate: '2026-01-01',
  endDate: '2026-01-31',
  dimensions: ['query', 'country'],
  searchType: 'web',
  rowLimit: 5000,
});

// response.rows → SearchAnalyticsRow[]

Auto-Paginated Full Fetch

import { querySearchAnalyticsAll } from '@power-seo/search-console';

// Fetches all rows automatically — handles the 25,000-row API limit
const allRows = await querySearchAnalyticsAll(client, {
  startDate: '2026-01-01',
  endDate: '2026-01-31',
  dimensions: ['query'],
});

console.log(`Total rows: ${allRows.length}`);

URL Inspection

import { inspectUrl } from '@power-seo/search-console';

const result = await inspectUrl(client, 'https://example.com/blog/my-post');

console.log(result.verdict); // 'PASS' | 'FAIL' | 'NEUTRAL'
console.log(result.indexingState); // 'INDEXING_ALLOWED' | ...
console.log(result.lastCrawlTime); // ISO timestamp
console.log(result.mobileUsabilityResult.verdict); // 'PASS' | 'FAIL'

Sitemap Management

import { listSitemaps, submitSitemap, deleteSitemap } from '@power-seo/search-console';

// List all submitted sitemaps
const sitemaps = await listSitemaps(client);
// sitemaps.sitemap → SitemapEntry[]

// Submit a new sitemap
await submitSitemap(client, 'https://example.com/sitemap.xml');

// Delete an old sitemap
await deleteSitemap(client, 'https://example.com/old-sitemap.xml');

CI/CD Keyword Position Check

import {
  createTokenManager,
  createGSCClient,
  querySearchAnalyticsAll,
  getServiceAccountToken,
} from '@power-seo/search-console';
import { subtle } from 'node:crypto';

// Parse service account JSON from environment
const serviceAccount = JSON.parse(process.env.GSC_SERVICE_ACCOUNT_JSON!);

async function signJwt(payload: Record<string, unknown>): Promise<string> {
  // Sign JWT assertion using node:crypto
  // Implementation depends on your preferred JWT signing library
  throw new Error('Implement JWT signing');
}

const tokenManager = createTokenManager(() =>
  getServiceAccountToken({
    clientEmail: serviceAccount.client_email,
    privateKeyId: serviceAccount.private_key_id,
    signJwt,
  }),
);

const client = createGSCClient({ siteUrl: 'sc-domain:example.com', tokenManager });

const rows = await querySearchAnalyticsAll(client, {
  startDate: '2026-01-24',
  endDate: '2026-01-31',
  dimensions: ['query', 'page'],
});

const dropped = rows.filter((r) => r.position > 20 && r.impressions > 100);
if (dropped.length > 0) {
  console.error('Pages dropped below position 20:');
  dropped.forEach((r) => console.error(' -', r.keys[1], `pos ${r.position.toFixed(1)}`));
  process.exit(1);
}

API Reference

createTokenManager(fetchToken)

Parameter Type Description
fetchToken () => Promise<TokenResult> Function that returns token result

Returns TokenManager: { getToken(): Promise<string>; invalidate(): void }. Token caching and refresh is handled automatically.

createGSCClient(config)

Parameter Type Description
config.siteUrl string Verified GSC property URL (sc-domain: prefix for domain properties)
config.auth TokenManager Token manager from createTokenManager()
config.rateLimitPerMinute number Rate limit (default: 1200)
config.maxRetries number Max retries for failed requests (default: 3)
config.baseUrl string Base URL for GSC API (default: official Google endpoint)

Returns GSCClient.

querySearchAnalytics(client, request)

Parameter Type Default Description
request.startDate string required YYYY-MM-DD
request.endDate string required YYYY-MM-DD
request.dimensions Dimension[] [] 'query', 'page', 'country', 'device', 'date', 'searchAppearance'
request.searchType SearchType 'web' 'web', 'image', 'video', 'news', 'discover', 'googleNews'
request.rowLimit number 1000 Rows per request (max 25,000)
request.startRow number 0 Row offset for pagination
request.dimensionFilterGroups object[] [] Filter groups to narrow results
request.aggregationType string 'auto' Aggregation method: 'auto', 'byPage', 'byProperty'
request.dataState string 'all' Include all or final data: 'all', 'final'

querySearchAnalyticsAll(client, request)

Same parameters as querySearchAnalytics() but rowLimit and startRow are managed automatically. Returns Promise<SearchAnalyticsRow[]>.

inspectUrl(client, url) / inspectUrlDirect(client, url)

Returns Promise<InspectionResult>: { verdict, indexingState, lastCrawlTime, mobileUsabilityResult, richResultsResult, ... }.

listSitemaps(client) / submitSitemap(client, url) / deleteSitemap(client, url)

listSitemaps() returns Promise<SitemapListResponse>. submitSitemap() and deleteSitemap() return Promise<void>.

Types

Type Description
OAuthCredentials { clientId, clientSecret, refreshToken }
ServiceAccountCredentials { clientEmail, privateKey, scopes }
TokenResult { accessToken: string, expiresAt: number }
TokenManager { getToken(): Promise<string>, invalidate(): void }
GSCClientConfig { siteUrl: string, tokenManager: TokenManager }
GSCClient Scoped API client instance
SearchType 'web' | 'image' | 'video' | 'news'
Dimension 'query' | 'page' | 'country' | 'device' | 'date' | 'searchAppearance'
SearchAnalyticsRequest Request shape for querySearchAnalytics()
SearchAnalyticsRow { keys: string[], clicks, impressions, ctr, position }
SearchAnalyticsResponse API response wrapper with rows: SearchAnalyticsRow[]
InspectionResult URL inspection verdict, indexing state, and details
SitemapEntry Single sitemap with status, lastDownloaded, errors
SitemapListResponse { sitemap: SitemapEntry[] }
GSCApiError Error class with status, code, and message

Use Cases

  • Automated keyword ranking reports — fetch all queries weekly and diff against the previous week
  • Indexing health monitoringinspectUrl() after deployments to verify new pages are indexed
  • Content gap analysis — merge GSC data with @power-seo/analytics to find high-impression, low-click pages
  • Sitemap automation — submit new sitemaps programmatically after content migrations
  • CI/CD SEO checks — fail pipelines when key pages drop below a position threshold
  • Multi-site SaaS dashboards — aggregate GSC data across multiple client properties with one GSCClient per site
  • Image and news search analytics — query image and news search types separately
  • Country and device breakdowns — segment click data by country or device for regional SEO analysis

Architecture Overview

  • Pure TypeScript — no compiled binary, no native modules
  • Server-side only — requires crypto for JWT signing; not edge or browser compatible
  • Zero runtime dependencies — no googleapis package; uses native fetch and crypto
  • Auto-paginationquerySearchAnalyticsAll() manages rowOffset and array merging transparently
  • Token caching — access tokens are cached and reused until 5 minutes before expiry
  • Scoped clients — each GSCClient is scoped to one verified GSC property via siteUrl
  • Typed errorsGSCApiError carries HTTP status, error code, and message for reliable error handling
  • Dual ESM + CJS — ships both formats via tsup for any bundler or require() usage

Supply Chain Security

  • No install scripts (postinstall, preinstall)
  • No runtime network access outside of GSC API calls
  • No eval or dynamic code execution
  • CI-signed builds — all releases published via verified github.com/CyberCraftBD/power-seo workflow
  • Safe for Node.js 18+ server environments

The @power-seo Ecosystem

All 17 packages are independently installable — use only what you need.

Package Install Description
@power-seo/core npm i @power-seo/core Framework-agnostic utilities, types, validators, and constants
@power-seo/react npm i @power-seo/react React SEO components — meta, Open Graph, Twitter Card, breadcrumbs
@power-seo/meta npm i @power-seo/meta SSR meta helpers for Next.js App Router, Remix v2, and generic SSR
@power-seo/schema npm i @power-seo/schema Type-safe JSON-LD structured data — 23 builders + 21 React components
@power-seo/content-analysis npm i @power-seo/content-analysis Yoast-style SEO content scoring engine with React components
@power-seo/readability npm i @power-seo/readability Readability scoring — Flesch-Kincaid, Gunning Fog, Coleman-Liau, ARI
@power-seo/preview npm i @power-seo/preview SERP, Open Graph, and Twitter/X Card preview generators
@power-seo/sitemap npm i @power-seo/sitemap XML sitemap generation, streaming, index splitting, and validation
@power-seo/redirects npm i @power-seo/redirects Redirect engine with Next.js, Remix, and Express adapters
@power-seo/links npm i @power-seo/links Link graph analysis — orphan detection, suggestions, equity scoring
@power-seo/audit npm i @power-seo/audit Full SEO audit engine — meta, content, structure, performance rules
@power-seo/images npm i @power-seo/images Image SEO — alt text, lazy loading, format analysis, image sitemaps
@power-seo/ai npm i @power-seo/ai LLM-agnostic AI prompt templates and parsers for SEO tasks
@power-seo/analytics npm i @power-seo/analytics Merge GSC + audit data, trend analysis, ranking insights, dashboard
@power-seo/search-console npm i @power-seo/search-console Google Search Console API — OAuth2, service account, URL inspection
@power-seo/integrations npm i @power-seo/integrations Semrush and Ahrefs API clients with rate limiting and pagination
@power-seo/tracking npm i @power-seo/tracking GA4, Clarity, PostHog, Plausible, Fathom — scripts + consent management

About CyberCraft Bangladesh

CyberCraft Bangladesh is a Bangladesh-based enterprise-grade software development and Full Stack SEO service provider company specializing in ERP system development, AI-powered SaaS and business applications, full-stack SEO services, custom website development, and scalable eCommerce platforms. We design and develop intelligent, automation-driven SaaS and enterprise solutions that help startups, SMEs, NGOs, educational institutes, and large organizations streamline operations, enhance digital visibility, and accelerate growth through modern cloud-native technologies.

Website GitHub npm Email

© 2026 CyberCraft Bangladesh · Released under the MIT License