Skip to content

Google Business verification

A business must be verified before Google shows many of its changes publicly. These endpoints let you drive Google’s verification from the API. They are served by Google’s Verifications API, a separate Google API from the ones that list and edit businesses. Who manages the listing is on the managers page. Every call is one metered Google call and needs a package that includes the connector.

These APIs may need enabling and approval. If the Verifications API is not enabled or approved for the Google project MauKirim runs under, these calls answer 503 gmb_api_unavailable. That is an operator-side problem. Google also limits how often a business may be verified, and which methods it offers varies by business; we do not restate Google’s rules, so rely on the options endpoint.

A business you create through the API (or an assistant) is not verified: its verificationState reads unverified, and Google does not apply many public changes to it until it is. The flow from nothing to a live listing is:

  1. POST /gmb/connections/{id}/locations (use validateOnly first) — returns the new business’s id.
  2. POST …/verifications/options — which methods Google offers for this address (a postcard to the address is the usual one; others appear when Google can confirm the business another way).
  3. POST …/verifications/start with one of them.
  4. POST …/verifications/{verificationId}/complete with the code the business receives. A postcard takes days, so keep the verification id and come back.
  5. Add photos and posts.
  1. GET …/verifications — is it already verified or pending?
  2. POST …/verifications/options — which methods does Google offer now?
  3. POST …/verifications/start with one of those methods.
  4. When the person at the business receives the code, POST …/verifications/{verificationId}/complete.

The verification objects are passed through in Google’s own shape.

Scope read or gmb
Terminal window
curl https://app.maukirim.com/api/v1/gmb/locations/gml_8f3kq2x1ab/verifications -H "Authorization: Bearer mk_live_…"
{
"ok": true,
"verifications": [
{ "name": "locations/123/verifications/v1", "method": "EMAIL", "state": "PENDING", "createTime": "2026-10-14T03:00:00Z" }
]
}

state is Google’s (PENDING, COMPLETED, FAILED). The id to use in step 4 is the last segment of name.


POST /gmb/locations/{id}/verifications/options

Section titled “POST /gmb/locations/{id}/verifications/options”

Asks Google which verification methods are available for this business right now. It changes nothing at Google, but it is a POST, so it needs the gmb scope.

Scope gmb
Body Optional { "languageCode": "en" } (default en)
{
"ok": true,
"options": [
{ "verificationMethod": "EMAIL", "emailData": { "domain": "example.com", "user": "owner" } },
{ "verificationMethod": "SMS", "phoneNumber": "+62 21 5550 100" }
]
}

POST /gmb/locations/{id}/verifications/start

Section titled “POST /gmb/locations/{id}/verifications/start”

Starts a verification. Google sends a code or a postcard to the business, so call it only with a method the options endpoint offered, and tell whoever will receive it.

Scope gmb
Header Idempotency-Key (optional, recommended): 8–128 characters of letters, digits and _ . : -
Field Required Rule
method yes ADDRESS (postcard), EMAIL, PHONE_CALL, SMS, AUTO or VETTED_PARTNER
languageCode no Up to 16 characters; default en
emailAddress for EMAIL A valid email address, up to 254 characters
phoneNumber for SMS and PHONE_CALL Up to 32 characters
mailerContact no For ADDRESS: the contact name on the postcard, up to 100 characters
Terminal window
curl -X POST https://app.maukirim.com/api/v1/gmb/locations/gml_8f3kq2x1ab/verifications/start \
-H "Authorization: Bearer mk_live_…" -H "Content-Type: application/json" \
-H "Idempotency-Key: verify-gml_8f3kq2x1ab-email-1" \
-d '{ "method": "EMAIL", "emailAddress": "owner@example.com" }'
const response = await fetch(`https://app.maukirim.com/api/v1/gmb/locations/${id}/verifications/start`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MAUKIRIM_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": `verify-${id}-email-1`,
},
body: JSON.stringify({ method: "EMAIL", emailAddress: "owner@example.com" }),
})
const { verification } = await response.json()
$curl = curl_init("https://app.maukirim.com/api/v1/gmb/locations/$id/verifications/start");
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MAUKIRIM_KEY'),
'Content-Type: application/json',
"Idempotency-Key: verify-$id-email-1",
],
CURLOPT_POSTFIELDS => json_encode(['method' => 'EMAIL', 'emailAddress' => 'owner@example.com']),
CURLOPT_RETURNTRANSFER => true,
]);
$verification = json_decode(curl_exec($curl), true)['verification'];
{
"ok": true,
"replayed": false,
"verification": { "name": "locations/123/verifications/v2", "method": "EMAIL", "state": "PENDING" }
}

The same key with the same body is "replayed": true and starts no second verification (so no second email or postcard); a different body under the same key is 409 gmb_idempotency_conflict. The response is 200.


POST /gmb/locations/{id}/verifications/{verificationId}/complete

Section titled “POST /gmb/locations/{id}/verifications/{verificationId}/complete”

Enters the code the business received.

Scope gmb
Path verificationId — from the list or the start answer (letters, digits and _ . = -)
Body { "pin": "123456" } — 4–8 digits
Terminal window
curl -X POST https://app.maukirim.com/api/v1/gmb/locations/gml_8f3kq2x1ab/verifications/v2/complete \
-H "Authorization: Bearer mk_live_…" -H "Content-Type: application/json" \
-d '{ "pin": "123456" }'
{ "ok": true, "verification": { "name": "locations/123/verifications/v2", "method": "EMAIL", "state": "COMPLETED" } }

A malformed pin is 400 invalid_input before Google is called; a wrong code is refused by Google, which also answers 400 invalid_input. Google limits the attempts, so do not guess. MauKirim does not log the pin.


HTTP Code Condition
400 invalid_input An unknown method, a missing emailAddress or phoneNumber, an invalid email, a malformed pin or id or key, or Google refused the request (a wrong code, a method not offered)
401 api_key_invalid / api_key_revoked / api_key_expired
402 gmb_plan_required The package does not include the connector
403 api_key_scope_denied Writes (including options) need gmb; reads need read or gmb
403 gmb_forbidden Google says the connected account may not verify this business
404 gmb_location_not_found Not your business, no such business, it left Google, or no such verification
409 gmb_reconnect_required / gmb_location_disabled / gmb_idempotency_conflict See Errors
429 gmb_rate_limited No budget now (Retry-After)
502 gmb_upstream_error Google failed
503 gmb_api_unavailable The Verifications API is not enabled or approved for the deployment’s Google project