Zernio
APIFor you
Zernio
APIFor you
Platforms

Google Business Profile

Overview

Publish

Posts & content typesMedia requirementsEvent & offer postsMulti-location posting

Engage

AnalyticsInbox

Manage

Business Profile managementServices & food menus

Reference

Fields, media & limits
Dashboard
OverviewPlatformsAPI ReferenceResources
Google Business Profile

Services & food menus

Read and replace the service list of a Google Business Profile location, and the food menus of a restaurant or cafe.


By the end of 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. 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 or free-form, with an optional price:

  • Structured: a serviceTypeId from Google's catalog.
  • Free-form: a category and a label.
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. That 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.

PUT updates them with the full menus array and an updateMask (Food menus).

A menu item's attributes take:

  • price, with a currency code
  • dietaryRestriction (VEGETARIAN, VEGAN, GLUTEN_FREE)
  • allergen (DAIRY, GLUTEN, SHELLFISH, ...)
  • spiciness, servesNumPeople and preparationMethods
  • 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. 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. Send a freeFormServiceItem when Google's catalog has no serviceTypeId for what the business offers.

Food menus. 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.

Either surface:

  • 403: the Google login has no permission on this location.
  • 401 with code token_invalid: 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 locationId these endpoints accept.
Was this page helpful?

Business Profile management

Read and update a Google Business Profile listing through the API, with verification, hours, photos, attributes and action links.

Fields, media & limits

Every platformSpecificData field for a Google Business Profile post, the image requirements, what Google's API does not expose, and common errors with their fixes.

On this page

ServicesFood menusIf it failsRelated