Google Business refresh and jobs
Reading a business live (GET /gmb/locations/{id}?live=1) answers at once but waits on Google. When you
would rather not wait — a nightly job, a dashboard that refreshes many businesses — queue a refresh and
poll it. The work is done by MauKirim’s worker on the background lane, which uses only budget that
interactive traffic leaves free (see rate limits).
POST /gmb/locations/{id}/refresh
Section titled “POST /gmb/locations/{id}/refresh”Queues a re-read of one business from Google. It answers 202 immediately with a job.
| Scope | gmb (it spends Google budget, so a read key is refused) |
| Path | id — the business id (gml_…) |
| Body | none |
| Header | Idempotency-Key (optional): 8–128 characters of letters, digits and _ . : - |
curl -X POST https://app.maukirim.com/api/v1/gmb/locations/gml_8f3kq2x1ab/refresh \ -H "Authorization: Bearer mk_live_…" \ -H "Idempotency-Key: refresh-gml_8f3kq2x1ab-2026-10-14"const response = await fetch(`https://app.maukirim.com/api/v1/gmb/locations/${id}/refresh`, { method: "POST", headers: { Authorization: `Bearer ${process.env.MAUKIRIM_KEY}`, "Idempotency-Key": `refresh-${id}-2026-10-14`, },})const { job } = await response.json() // HTTP 202$curl = curl_init("https://app.maukirim.com/api/v1/gmb/locations/$id/refresh");curl_setopt_array($curl, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('MAUKIRIM_KEY'), "Idempotency-Key: refresh-$id-2026-10-14", ], CURLOPT_RETURNTRANSFER => true,]);$job = json_decode(curl_exec($curl), true)['job'];{ "ok": true, "job": { "id": "gmj_5n2c8wq0ra", "state": "queued", "kind": "sync_location" }, "replayed": false}| Field | Meaning |
|---|---|
job.id |
The id to poll at GET /gmb/jobs/{id} |
job.state |
queued, running, done or failed |
job.kind |
sync_location for this endpoint |
replayed |
true when the same Idempotency-Key had already queued this job: you get the same job back, not a second one |
Queuing itself makes no Google call. Because it only queues, it does not report a business that is
disabled or removed_upstream at once: such a job finishes failed, with the reason in error.
Errors
Section titled “Errors”| HTTP | Code | Condition |
|---|---|---|
| 400 | invalid_input |
A malformed Idempotency-Key |
| 402 | gmb_plan_required |
The package does not include the connector |
| 403 | api_key_scope_denied |
The key lacks gmb |
| 404 | gmb_location_not_found |
Not your business, or no such business |
| 500 | server_error |
Unexpected |
GET /gmb/jobs/{id}
Section titled “GET /gmb/jobs/{id}”The state of a queued job.
| Scope | read or gmb |
| Path | id — the job id returned by the refresh call |
curl https://app.maukirim.com/api/v1/gmb/jobs/gmj_5n2c8wq0ra \ -H "Authorization: Bearer mk_live_…"const response = await fetch(`https://app.maukirim.com/api/v1/gmb/jobs/${jobId}`, { headers: { Authorization: `Bearer ${process.env.MAUKIRIM_KEY}` },})const { job } = await response.json()$curl = curl_init("https://app.maukirim.com/api/v1/gmb/jobs/$jobId");curl_setopt_array($curl, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('MAUKIRIM_KEY')], CURLOPT_RETURNTRANSFER => true,]);$job = json_decode(curl_exec($curl), true)['job'];{ "ok": true, "job": { "id": "gmj_5n2c8wq0ra", "kind": "sync_location", "state": "done", "attempts": 1, "error": null, "createdAt": "2026-10-14T03:00:00.000Z", "finishedAt": "2026-10-14T03:00:02.000Z" }}| Field | Meaning |
|---|---|
state |
queued (waiting for budget or the worker), running, done, failed |
attempts |
How many times the worker has tried |
error |
null, or a short code for the last failure |
createdAt, finishedAt |
ISO timestamps; finishedAt is null until the job ends |
A job is retried automatically with backoff while the reason may pass (a busy budget, a Google hiccup),
up to five attempts; a reconnect-needed connection, a disabled connection or a missing business fails at once
because retrying cannot fix it. A refresh only reads from Google, so a retry can never repeat a public change.
Poll no faster than every few seconds; when state is done, read the business with
GET /gmb/locations/{id}.
A job that belongs to another account answers 404 not_found, the same as a job that does not exist.
Errors
Section titled “Errors”| HTTP | Code | Condition |
|---|---|---|
| 402 | gmb_plan_required |
The package does not include the connector |
| 403 | api_key_scope_denied |
Neither read nor gmb |
| 404 | not_found |
No such job for this account |
| 500 | server_error |
Unexpected |