Services & Food Menus
Read and replace the service list of a Google Business Profile location, and the food menus of a restaurant or cafe.
When you finish this page the services a Google Business Profile (googlebusiness) location offers, and the menus of a food business, come from the API. You need a connected Google Business Profile account (accountId) whose location is verified (verification).
Services
GET /v1/accounts/{accountId}/gmb-services returns the services the location offers and PUT replaces the whole list (Services). Google's API has no per-item update, so send every service on each PUT. A service is either structured (a serviceTypeId from Google's catalog) or free-form (a category and a label), with an optional price.
import Zernio from '@zernio/node';
const zernio = new Zernio();
const { data: services } = await zernio.gmbservices.getGoogleBusinessServices({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d' }
});
await zernio.gmbservices.updateGoogleBusinessServices({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d' },
body: {
serviceItems: [
...services.services,
{
freeFormServiceItem: {
category: 'categories/gcid:plumber',
label: { displayName: 'Pipe Repair', description: 'Emergency and scheduled pipe repair' }
},
price: { currencyCode: 'USD', units: '150' }
}
]
}
});Response (200) of the read:
{
"success": true,
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"locationId": "12345678901234567890",
"services": [
{
"freeFormServiceItem": {
"category": "categories/gcid:plumber",
"label": { "displayName": "Pipe Repair", "description": "Emergency and scheduled pipe repair" }
},
"price": { "currencyCode": "USD", "units": "150" }
}
]
}Response (200) of the update: success and the services array as Google stored it, which is the list to send back on the next PUT.
Food menus
For locations that support menus (restaurants, cafes), GET /v1/accounts/{accountId}/gmb-food-menus returns the menus and PUT updates them with the full menus array and an updateMask (Food menus). A menu item's attributes take a price with a currency code, dietaryRestriction (VEGETARIAN, VEGAN, GLUTEN_FREE), allergen (DAIRY, GLUTEN, SHELLFISH, ...), spiciness, servesNumPeople, preparationMethods and mediaKeys for item photos. Give an item options when it comes in variants: each entry carries its own labels and attributes, so a size can set its own price.
const { data: menus } = await zernio.gmbfoodmenus.getGoogleBusinessFoodMenus({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d' }
});
await zernio.gmbfoodmenus.updateGoogleBusinessFoodMenus({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d' },
body: {
menus: [{
labels: [{ displayName: 'Lunch Menu', languageCode: 'en' }],
sections: [{
labels: [{ displayName: 'Appetizers' }],
items: [{
labels: [{ displayName: 'Caesar Salad', description: 'Romaine, parmesan, croutons' }],
attributes: {
price: { currencyCode: 'USD', units: '12' },
dietaryRestriction: ['VEGETARIAN']
}
}]
}]
}],
updateMask: 'menus'
}
});
console.log(menus.menus);Response (200) of the read:
{
"success": true,
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"locationId": "12345678901234567890",
"name": "accounts/123456789/locations/12345678901234567890/foodMenus",
"menus": [
{
"labels": [{ "displayName": "Lunch Menu", "languageCode": "en" }],
"sections": [
{
"labels": [{ "displayName": "Appetizers" }],
"items": [
{
"labels": [{ "displayName": "Caesar Salad", "description": "Romaine, parmesan, croutons" }],
"attributes": {
"price": { "currencyCode": "USD", "units": "12" },
"dietaryRestriction": ["VEGETARIAN"]
}
}
]
}
]
}
]
}Response (200) of the update: the same body, with menus as Google stored it.
If it fails
Both endpoints proxy Google, so a 400 on PUT /gmb-services means Google rejected the serviceItems list and its own message comes back in the envelope:
{
"error": "Request contains an invalid argument.",
"code": "gbp_bad_request"
}Read the location's categories with Location details, and send a freeFormServiceItem when Google's catalog has no serviceTypeId for what the business offers. On the food-menu calls a 400 means the account is not a Google Business Profile account or has no location selected; menus themselves exist only on locations Google gives menu support to. A 403 on either surface means the Google login has no permission on this location, and a 401 with code token_invalid means Google revoked the token, so reconnect the account. Error handling covers the envelope.
Related
- Services and Food menus: the full schemas.
- Business Profile Management: verification, hours, photos, attributes and action links.
- Multi-Location Posting: the
locationIdthese endpoints accept.