npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@power-seo/search-console

v1.0.12

Published

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

Downloads

804

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