Many developers want to automatically retrieve Google Business Profile data using Google Apps Script (GAS). However, API application is mandatory, and simply enabling the API won't work. This article explains the actual errors you'll encounter and how to resolve them, written for beginners.
What is Google Business Profile API?
The Google Business Profile API (formerly Google My Business API) allows programmatic access to store information and performance data displayed on Google Maps.
Conclusion: While technically possible with GAS, API application approval is mandatory and not straightforward.
Retrievable Data
- Store Information: Name, address, business hours, phone number
- Performance Metrics: Search views, map views, direction requests, phone calls
- Review Data: Review text, star ratings, posting dates
- Photos: Store photo management
Can You Use GAS? Answer and Caveats
Possible, But With Hurdles
Key Point: Technically feasible, but you must clear three gates:
- API Enablement in GCP
- Explicit OAuth Scope Configuration
- Google Application and Approval Wait (Biggest Hurdle)
Especially #3, the "application approval," is mandatory, and the API is essentially unusable until approved.
Errors You'll Encounter Immediately
Error 1: 403 PERMISSION_DENIED (Insufficient Scopes)
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
}
Cause: OAuth scopes don't include Business Profile permissions.
Solution
Add scopes to appsscript.json:
{
"timeZone": "Asia/Tokyo",
"oauthScopes": [
"https://www.googleapis.com/auth/business.manage",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.external_request"
]
}
Action: Edit via "Project Settings" → "Show manifest file" in GAS editor.
Error 2: 403 SERVICE_DISABLED (API Not Enabled)
{
"error": {
"code": 403,
"message": "My Business Account Management API has not been used in project XXXXX before or it is disabled.",
"status": "PERMISSION_DENIED"
}
}
Cause: API not enabled in GCP Console.
Solution
- Check GCP project number in GAS "Project Settings"
- Open Google Cloud Console
- Select the project
- "APIs & Services" → "Library"
- Search and enable:
- My Business Account Management API
- Business Profile Performance API

Error 3: 429 RESOURCE_EXHAUSTED (Biggest Hurdle)
{
"error": {
"code": 429,
"message": "Quota exceeded for quota metric 'Requests' and limit 'Requests per minute' of service 'mybusinessaccountmanagement.googleapis.com' for consumer 'project_number:XXXXX'.",
"status": "RESOURCE_EXHAUSTED",
"details": [
{
"quota_limit_value": "0"
}
]
}
}

Caution: This is the most critical error. Note quota_limit_value: 0.
What This Error Means
- API is enabled
- Authentication passed
- But quota is 0, so not even 1 request is allowed
Conclusion: This API requires "application approval" and cannot be used without Google's authorization.
API Application Process
Why Application is Required
Google Business Profile API handles business data and uses review-based approval to prevent:
- Scraping prevention
- Unauthorized competitor data collection
- SaaS resale restrictions
Key Point: If your purpose is managing and analyzing your own stores, approval is almost certain.
Application Form Location
Official application form: https://support.google.com/business/contact/api_default
Application Form Examples
Important Selections
Caution: Avoid selecting "promotional purposes." Emphasize analysis and internal use.
Supplemental Explanation (Ready to Use)
We operate approximately 20 physical business locations under a single Google Business Profile account, and we fully own and manage these locations.
We plan to use the Business Profile API exclusively to retrieve performance insights such as search views, map views, customer actions, reviews, and ratings for internal analytics and reporting purposes.
The data will be used only within our company for business analysis and decision-making. We will not provide this data to third parties, resell it, or expose it in any public-facing product or service.
The implementation is based on Google Apps Script using OAuth 2.0, and the data will be stored internally in Google Sheets and visualized via Looker Studio.
Approval Timeframe
- Fastest: Same day ~ 2 business days
- Typical: 3-5 business days
- With additional questions: 1 week~
Action: Be patient. Plan your implementation while waiting for approval email.
Implementation Examples After Approval
Minimal Connection Test Code
function testGBPConnection() {
const url = "https://mybusinessaccountmanagement.googleapis.com/v1/accounts";
const res = UrlFetchApp.fetch(url, {
headers: {
Authorization: "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
});
Logger.log(res.getResponseCode()); // 200 = success
Logger.log(res.getContentText());
}
Retrieve Location List
function listLocations() {
// Get accounts
const accountsUrl = "https://mybusinessaccountmanagement.googleapis.com/v1/accounts";
const accountsRes = UrlFetchApp.fetch(accountsUrl, {
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() }
});
const accounts = JSON.parse(accountsRes.getContentText()).accounts;
const accountName = accounts[0].name;
// Get locations
const locationsUrl = `https://mybusinessbusinessinformation.googleapis.com/v1/${accountName}/locations?readMask=name,title,storeCode`;
const locationsRes = UrlFetchApp.fetch(locationsUrl, {
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() }
});
const locations = JSON.parse(locationsRes.getContentText()).locations || [];
// Output to spreadsheet
const sheet = SpreadsheetApp.getActive().getSheetByName("locations") ||
SpreadsheetApp.getActive().insertSheet("locations");
sheet.clear();
sheet.appendRow(["Location Name", "Title", "Store Code"]);
locations.forEach(loc => {
sheet.appendRow([loc.name, loc.title, loc.storeCode || ""]);
});
}
Retrieve Performance Data
function fetchPerformanceData() {
const sheet = SpreadsheetApp.getActive().getSheetByName("locations");
const data = sheet.getDataRange().getValues();
data.shift(); // Remove header
const endDate = new Date();
const startDate = new Date();
startDate.setDate(endDate.getDate() - 30); // Last 30 days
const resultSheet = SpreadsheetApp.getActive().getSheetByName("performance") ||
SpreadsheetApp.getActive().insertSheet("performance");
resultSheet.clear();
resultSheet.appendRow(["Date", "Location", "Metric", "Value"]);
data.forEach(row => {
const locationName = row[0];
const request = {
locationNames: [locationName],
basicRequest: {
timeRange: {
startTime: startDate.toISOString(),
endTime: endDate.toISOString()
},
metricRequests: [
{ metric: "SEARCH_VIEWS" },
{ metric: "MAP_VIEWS" },
{ metric: "WEBSITE_CLICKS" }
]
}
};
const url = "https://businessprofileperformance.googleapis.com/v1/locations:reportInsights";
const res = UrlFetchApp.fetch(url, {
method: "post",
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
contentType: "application/json",
payload: JSON.stringify(request)
});
const response = JSON.parse(res.getContentText());
// Write data to sheet (implementation omitted)
});
}
Frequently Asked Questions
Q1: Can applications be rejected?
Action: The following cases may result in rejection or hold:
- Purpose is competitor store data collection
- SaaS product resale purpose
- Company website doesn't exist
- Attempting to access stores without actual management rights
For own-store analysis purposes, approval is almost certain.
Q2: Can I develop before approval?
Conclusion: You can proceed with spreadsheet design and Looker Studio dashboard design.
It's practical to develop API call portions with dummy data and connect to production after approval.
Q3: Is it free to use?
For typical usage (dozens of stores, daily updates), the free tier is sufficient.
Caution: Be mindful of quota limits with high-volume requests or high-frequency updates.
Q4: Why doesn't it appear in Advanced Google Services?
Business Profile API doesn't show in GAS "Advanced Google Services" list.
Action: Implement by calling REST API directly with UrlFetchApp.
Multi-Store Management Use Cases
Looker Studio Integration
- Periodic data retrieval to spreadsheet via GAS
- Set spreadsheet as Looker Studio data source
- Visualize with dashboard
Trigger Setup
function setupDailyTrigger() {
ScriptApp.newTrigger("fetchPerformanceData")
.timeBased()
.everyDays(1)
.atHour(6) // Run at 6 AM daily
.create();
}
Summary
Key points for using Google Business Profile API with GAS:
Conclusion: Technically possible, but API application approval is mandatory. Once approved, it becomes a powerful automation tool.
Implementation Flow
- Enable API in GCP (5 minutes)
- Add scopes to appsscript.json (5 minutes)
- Submit application to Google (30 minutes)
- Wait for approval (Several days ~ 1 week)
- Start implementation and operation (1-2 days)
What Becomes Possible After Approval
- Centralized multi-store data management
- Automatic daily performance retrieval
- Looker Studio visualization
- Automatic review monitoring
Recommended For
- Companies operating multiple stores
- Those wanting to measure Google Maps effectiveness
- Those needing per-store KPI comparisons
- Those wanting freedom from manual data checking
Caution: Application is once per company. Fill out carefully.
References
- Google Business Profile API Documentation https://developers.google.com/my-business
- API Access Request Form https://support.google.com/business/contact/api_default
- Google Cloud Console https://console.cloud.google.com/
- GAS OAuth Scopes Reference https://developers.google.com/apps-script/guides/services/authorization