@vitabletech/gbp-sdk
@vitabletech/gbp-sdk
Enterprise-grade Google Business Profile (GBP) SDK for Node.js, Next.js, and TypeScript.
⚡ Try the Live Playground & API Explorer
Want to test the Google Business Profile APIs without writing code or setting up a local server?
👉 https://gbp-playground.vitabletech.in
Test OAuth 2.0 (BYOC), Locations, Performance Metrics v1, Reviews, Verifications, and Quotas with real-time interactive Swagger documentation.
🔗 Quick Links
- ⚡ Live Interactive Playground: https://gbp-playground.vitabletech.in
- 📖 Full Documentation: https://gbp.vitabletech.in
- 📦 NPM Package: https://www.npmjs.com/package/@vitabletech/gbp-sdk
- 🐙 GitHub Repository: https://github.com/vitabletech/gbp-sdk
- 🏢 Developed by VitableTech: https://vitabletech.in
Features
- Automatic Token Management: Automatically handles refreshing access tokens when they expire. Thread-safe to prevent duplicate refresh requests.
- Pluggable Token Storage: Supports memory, file, and custom token storage implementations (e.g. Redis).
- Robust HTTP Client: Built-in exponential backoff, retry logic for 429 and 5xx errors, and rate limit handling.
- Auto-Pagination: Provides
listAllmethods and cursor paginators to automatically traversenextPageTokenand fetch all records. - Performance & Metrics API (v1): First-class native support for daily metric time series, multi-metric queries, and monthly search keyword impression counts.
- Strong Typing: Full TypeScript support with generics.
- Generic Requests: Exposes a
request()method for unsupported or newly released Google APIs.
Installation
npm install @vitabletech/gbp-sdkNetwork Whitelist
If you are running this SDK behind a strict corporate firewall, please ensure you whitelist the necessary Google API domains. See the Network Whitelist Documentation for the complete list of domains and URLs.
What's New in v1.3.0 🎉
- Business Profile Performance API (v1): Full native integration with
businessprofileperformance.googleapis.comviaMetricsServiceand directclient.locationsshortcuts. - Daily Metrics Time Series: New
locations.getDailyMetricsTimeSeriesmethod to fetch daily counts for calls, website clicks, directions, bookings, food orders, and impressions. - Multi Daily Metrics Time Series: Enhanced
locations.fetchMultiDailyMetricsTimeSerieswith support for sub-entity breakdowns (dailySubEntityType) and both camelCase (startDate/endDate) & snake_case dates. - Monthly Search Keyword Impressions: Track customer search terms with
locations.searchkeywords.impressions.monthly.list/listSearchKeywordsImpressionsMonthly. - Auto-Pagination for Keywords: Built-in
listAllSearchKeywordsImpressionsMonthlyandlistSearchKeywordsImpressionsMonthlyPaginator. - Performance Quotas: Direct
client.quotas.getPerformance(projectId)to monitor Performance API rate limits and quotas.
What's New in v1.0.0 🎉
- Native Location Attributes: Added native
getAttributesandpatchAttributessupport toLocationsService. - Enhanced Media Uploads: Upgraded
MediaServiceto fully support Google's v4 endpoints by allowing directaccountIdbinding. - Verifications API: Added full native support for the
mybusinessverifications.googleapis.comAPI via the newVerificationsService. - Quotas API: Programmatically check Google Cloud Service Usage Quotas for Business Profile APIs (
serviceusage.googleapis.com) to avoid hitting rate limits. - Chains API: Find global brands and associate your locations with them easily via
ChainsService. - Network Whitelisting: Added comprehensive network whitelist documentation for enterprise users.
- Food Menus & Metrics Types: Added complete, strict TypeScript interfaces for the Google Business Profile
FoodMenusandMetricsAPIs. - Quota Management: Check API quotas and limits using
QuotasServicewithout risking hitting limits unexpectedly.
Quick Start
import { GBPClient, ConsoleLogger } from '@vitabletech/gbp-sdk';
const client = new GBPClient({
clientId: 'YOUR_GOOGLE_CLIENT_ID',
clientSecret: 'YOUR_GOOGLE_CLIENT_SECRET',
refreshToken: 'YOUR_REFRESH_TOKEN',
tokenStorage: 'file', // stores tokens in gbp-tokens.json
logger: new ConsoleLogger(), // optional pluggable logger
});
async function main() {
// Automatically handles token generation and pagination!
const accounts = await client.accounts.listAll();
if (accounts.length > 0) {
const accountName = accounts[0].name;
const locations = await client.locations.listAll(accountName);
console.log(`Found ${locations.length} locations for ${accountName}`);
}
}
main();Fetching Performance Metrics & Search Keywords
import { DailyMetric } from '@vitabletech/gbp-sdk';
// 1. Fetch daily metrics time series (e.g. Website Clicks)
const dailyClicks = await client.locations.getDailyMetricsTimeSeries(
'locations/12345',
{
dailyMetric: DailyMetric.WEBSITE_CLICKS,
dailyRange: {
startDate: { year: 2024, month: 1, day: 1 },
endDate: { year: 2024, month: 1, day: 31 },
},
}
);
// 2. Fetch monthly search keywords with auto-pagination
const keywords = await client.locations.listAllSearchKeywordsImpressionsMonthly(
'locations/12345',
{
monthlyRange: {
startMonth: { year: 2024, month: 1 },
endMonth: { year: 2024, month: 3 },
},
}
);Creating a Location Example Payload
When using client.locations.create(), you must pass a valid location object. Here is an example of a complete payload:
{
"languageCode": "en",
"title": "Your Shop Name",
"storeCode": "1234567",
"phoneNumbers": {
"primaryPhone": "+9112345678902"
},
"categories": {
"primaryCategory": {
"name": "categories/gcid:airport"
}
},
"storefrontAddress": {
"regionCode": "IN",
"postalCode": "123456",
"administrativeArea": "State Name",
"locality": "City Name",
"addressLines": ["Address Line 1", "Address Line 2"]
},
"latlng": {
"latitude": 34.521721,
"longitude": 92.519443
},
"websiteUri": "https://www.yourwebsite.in",
"regularHours": {
"periods": [
{
"openDay": "MONDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "MONDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "TUESDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "TUESDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "WEDNESDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "WEDNESDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "THURSDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "THURSDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "FRIDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "FRIDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "SATURDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "SATURDAY",
"closeTime": { "hours": 22, "minutes": 0 }
},
{
"openDay": "SUNDAY",
"openTime": { "hours": 6, "minutes": 0 },
"closeDay": "SUNDAY",
"closeTime": { "hours": 22, "minutes": 0 }
}
]
},
"profile": {
"description": "Your RO - Retail Outlet."
}
}Reading API Quotas
You can programmatically retrieve Google Service Usage quotas using the SDK. This is useful for monitoring limits, such as Location creation limits. Note: this retrieves quota configuration/limits, not necessarily your current usage.
Quota OAuth Scopes
Reading quotas requires the https://www.googleapis.com/auth/cloud-platform.read-only scope in addition to the standard business.manage scope. Also, the user must have appropriate IAM permissions on the target Google Cloud project to read quotas.
Important: If you add
enableQuotaAccess, existing authorized users may need to re-consent to grant the new scope.
const client = new GBPClient({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
refreshToken: process.env.GOOGLE_REFRESH_TOKEN,
enableQuotaAccess: true, // Opt-in to request the quota scope during OAuth flow
});
async function checkQuotas() {
const quotas = await client.quotas.get({
projectId: 'YOUR_PROJECT_ID_OR_NUMBER',
service: 'mybusinessbusinessinformation.googleapis.com',
});
console.log(quotas.quotas);
// [ { metric: '...', displayName: 'Create Location requests per day', limit: 100, unit: '1/d' } ]
}Generic Request Mechanism
You can use the generic request() method to interact with endpoints not yet natively wrapped by the SDK:
const response = await client.request({
method: 'GET',
url: 'https://oauth2.googleapis.com/tokeninfo',
query: {
access_token: 'YOUR_ACCESS_TOKEN',
},
});