Update a location's details and hours
Change contact details, publish a full weekly schedule with one-off overrides, mark a temporary closure, set Google categories, and read the changes back.
POST /locations/update is a partial update. Everything goes under input,
input.id is the only required field, and only the fields you send change.
The same call handles a one-line phone fix and a full schedule rewrite, so the
steps below differ only in what they put in the body.
1. Update phone and website
Send id plus the fields to change. bizUrl is what publishers show as the
website. The Python SDK's locations.update() takes a dict with camelCase
keys, and the Node SDK's updateLocation() takes the same object.
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "phone": "5125550199", "bizUrl": "https://acmekitchen.example.com" }}'{ "data": { "updateLocation": { "success": true, "errors": null, "location": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "name": "Jenny Home", "phone": "5125550199", "status": "APPROVED" } } }}A validation failure still returns HTTP 200, with success: false and the
reason in data.updateLocation.errors, so check success rather than the
status code. Both SDKs raise ValidationError for that case.
2. Set weekly hours
businessHours is an array with one entry per weekday. Always send all
seven, and mark a closed day with type: "CLOSED" and an empty slots
array rather than leaving it out. Intervals inside a day must not overlap.
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "businessHours": [ { "day": "MONDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "TUESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "WEDNESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "THURSDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "FRIDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "SATURDAY", "type": "OPEN", "slots": [{ "start": "10:00am", "end": "02:00pm" }] }, { "day": "SUNDAY", "type": "CLOSED", "slots": [] } ] }}'For a holiday, append a SPECIAL entry to the same array. It overrides that
one date and leaves the weekly pattern alone:
{ "day": "SPECIAL", "type": "CLOSED", "specialDate": "2026-12-25", "slots": [] }3. Mark a temporary closure or hide the address
temporarilyClosed: true tells publishers the business is closed for now and
stops publishing its hours; set it back to false when you reopen. For a
service-area business, hideAddress: true keeps the street address off
listings and makes city optional.
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "temporarilyClosed": true } }'4. Set Google categories
Google Business Profile has its own category taxonomy, separate from the
numeric subCategoryId. primaryGbpSiteCategoryId takes a GCID such as
gcid:restaurant, and additionalGbpSiteCategoryIds takes more of them.
Both are resolved against countryIso, so send the country in the same call.
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "id": "TG9jYXRpb246MTgwMDI4OQ==", "countryIso": "US", "primaryGbpSiteCategoryId": "gcid:restaurant", "additionalGbpSiteCategoryIds": ["gcid:pizza_restaurant", "gcid:italian_restaurant"] }}'Do not confuse these with additionalCategoryIds, which takes integer
databaseId values from the subcategories endpoint. See
Look up countries, states and categories.
5. Read the location back
GET /locations-by-ids returns the full record for one or more base64 ids,
passed as a JSON array in the ids query parameter. Compare phone,
businessHours, and temporarilyClosed with what you sent.
curl -G https://listingsapi.com/api/v4/locations-by-ids \--data-urlencode 'ids=["TG9jYXRpb246MTgwMDI4OQ=="]' \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "getLocationsByIds": [ { "id": "TG9jYXRpb246MTgwMDI4OQ==", "databaseId": 1800289, "name": "Jenny Home", "phone": "5125550199", "hideAddress": false, "temporarilyClosed": true } ] }}Ids that do not exist in your account are dropped from the array without an error, so compare the returned count with what you asked for.
If webhooks are configured, a
profile.updated event fires. It is
debounced to one delivery per location per 60 seconds, on the leading edge:
later edits in that window are collapsed, and changed_fields describes only
the edit that opened it. Read the location back when the event arrives, and
again after the window has closed.
Next steps
- Upload a logo, cover and photos: add imagery to the record you just updated.
- Find locations and archive the ones you no longer manage: search by store code and retire closed branches.
- Update a location and Get locations by IDs: the reference pages, including place action links and every writable field.