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 performs a partial update. All fields go under
input, input.id is the only required field, and fields you omit keep their
current values. Each section below changes only the JSON request body.
1. Update phone and website
Send id plus the fields to change. Publishers publish bizUrl as the
website URL. 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 marks the business as closed and stops publishing
its hours. Set it to false to reopen. For a
service-area business, set hideAddress: true: ListingsAPI keeps the address
on the location but does not submit it to publishers.
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.