My Business
2.4K members online now
2.4K members online now
For developers who are using the Google My Business API to manage locations
Guide Me

HttpError 400 on Method accounts.locations.patch

[ Edited ]
Visitor ✭ ✭ ✭
# 1
Visitor ✭ ✭ ✭

I am receiving "INVALID_ARGUMENT" and am unable to find what I am missing. I have this working under v2. I have included some code and the output with some data replaced with X's.
I am using python with httplib2, uritemplate, google-api-python-client


Here is a summary of my code.
API_NAME = 'mybusiness'
SCOPE = ''
DISCOVERY_URI = '{api}_google_rest_{apiVersion}.json'
service =, API_VERSION, http=http, discoveryServiceUrl=DISCOVERY_URI)
locationId = "accounts/10291255XXX17069664/locations/181373XXXX49336769"
language = 'en'
service, flags = init(debug=True)
body = json.dumps({"primaryPhone": "(450) 687-6318",})
fieldMask = ["primaryPhone"]
response = service.accounts().locations().patch(name=locationId,


- I grab the request argument before they are sent to httplib2.request
*** start request args
"{\"primaryPhone\": \"(555) 555-6318\"}"
{'content-length': '40', 'accept-encoding': 'gzip, deflate', 'accept': 'application/json', 'user-agent': 'google-api-python-client/1.5.3 (gzip)', 'content-type': 'application/json', 'Authorization': 'Bearer xxx.XXXXX'}
*** start keyword args
*** end request args


- This is the response I receive from the server.

({'status': '400', 'alternate-protocol': '443:quic', 'content-length': '457', 'x-xss-protection': '1; mode=block', 'x-content-type-options': 'nosniff', 'transfer-encoding': 'chunked', 'vary': 'Origin, X-Origin, Referer', 'server': 'ESF', '-content-encoding': 'gzip', 'cache-control': 'private', 'date': 'Tue, 30 Aug 2016 20:17:32 GMT', 'x-frame-options': 'SAMEORIGIN', 'alt-svc': 'quic=":443"; ma=2592000; v="36,35,34,33,32,31,30"', 'content-type': 'application/json; charset=UTF-8'}, '{\n "error": {\n "code": 400,\n "message": "Invalid value at \'location\' (, \\"{\\"primaryPhone\\": \\"(450) 687-6318\\"}\\"",\n "errors": [\n {\n "message": "Invalid value at \'location\' (, \\"{\\"primaryPhone\\": \\"(555) 555-6318\\"}\\"",\n "domain": "global",\n "reason": "badRequest"\n }\n ],\n "status": "INVALID_ARGUMENT"\n }\n}\n')

Thank you for your assistance

1 Expert replyverified_user

Re: HttpError 400 on Method accounts.locations.patch

Visitor ✭ ✭ ✭
# 2
Visitor ✭ ✭ ✭
here is an better formated response.
"error": {
"code": 400,
"message": "Invalid value at 'location' (, \"{\"primaryPhone\": \"(555) 555-6318\"}\"",
"details": [
"@type": "",
"fieldViolations": [
"field": "location",
"description": "Invalid value at 'location' (, \"{\"primaryPhone\": \"(450) 687-6318\"}\""

Re: HttpError 400 on Method accounts.locations.patch

[ Edited ]
Google Employee
# 3
Google Employee

Hi @Greg E,


We don’t currently have an official client library for Python, and the Google My Business API is not listed as one of the Supported APIs for the service object you build in your script. Therefore, support for Google API Client Library for Python should be directed to its Support page, and support for Google API Discovery Service should be respectively directed to its Forums. Please notice the backward incompatible changes from v2 to v3 of the Google My Business API. Please also note that you can enable more detailed error messages in responses by adding an additional header to your requests when using the Google API Client Library for Python.


Nonetheless, here is a code snippet for assisting you in building a client library and making requests with Google API Client Library for Python and APIs Discovery Service:

import os

import httplib2

import json

import argparse


from oauth2client.client import flow_from_clientsecrets

from oauth2client.file import Storage

from oauth2client import tools

from apiclient.discovery import build

from apiclient import errors


API_NAME = 'mybusiness'


DISCOVERY_URI = '{api}_google_rest_{apiVersion}.json'


# Make authorized API calls by using OAuth 2.0 client ID credentials for authentication & authorization

parser = argparse.ArgumentParser(parents=[tools.argparser])

flags = parser.parse_args()


flow = flow_from_clientsecrets('client_secrets.json',




# For retrieving the refresh token

flow.params['access_type'] = 'offline'

flow.params['approval_prompt'] = 'force'


# Use a Storage in current directory to store the credentials in

storage = Storage('.' + os.path.basename(__file__))

credentials = storage.get()


# Refresh the access token if it expired

if credentials is not None and credentials.access_token_expired:






# Acquire credentials in a command-line application

if credentials is None or credentials.invalid:

 credentials = tools.run_flow(flow, storage, flags)


# Apply necessary credential headers to all requests made by an httplib2.Http instance

http = credentials.authorize(httplib2.Http())


# Build the service object

service = build(API_NAME, API_VERSION, http=http, discoveryServiceUrl=DISCOVERY_URI)


# List all accounts for the authenticated user

list_accounts_response = service.accounts().list().execute()

print json.dumps(list_accounts_response, indent=2)


# For testing purposes, selects the very first account in the accounts array to list all locations

list_locations_response = service.accounts().locations().list(name=list_accounts_response['accounts'][0]['name']).execute()

print json.dumps(list_locations_response, indent=2)


# For testing purposes, selects the very first location in the locations array to update the specified location.

name = list_locations_response['locations'][0]['name']

list_locations_response['locations'][0]['name'] = None

list_locations_response['locations'][0]['primaryPhone'] = "02 9374 4000"

update_location_request = service.accounts().locations().patch(name=name, body=list_locations_response['locations'][0])

# Add this additional header to your requests to enable more detailed error messages in responses

update_location_request.headers['X-GOOG-API-FORMAT-VERSION'] = 2

update_location_request.uri += "&languageCode=en&fieldMask=primaryPhone&validateOnly=false"


 update_location_response = update_location_request.execute();

 print json.dumps(update_location_response, indent=2)

except errors.HttpError, e:


   # Load Json body.

   error = json.loads(e.content)['error']

   print json.dumps(error, indent=2)

 except ValueError:

   # Could not load Json body.

   print 'HTTP Status code: %d' % e.resp.status

   print 'HTTP Reason: %s' % e.resp.reason


# For testing purposes, selects the very first location in the locations array to list all reviews

list_reviews_response = service.accounts().locations().reviews().list(name=list_locations_response['locations'][0]['name']).execute()

print json.dumps(list_reviews_response, indent=2)


I hope this helps.