OpenGMB MCP tools reference
This reference lists all 238 tools the OpenGMB MCP server offers, grouped by area. It is generated from the same list the server serves, so it cannot drift. Each tool shows whether it reads or writes, the permission it needs, who has that permission, and its inputs.
Last updated 2026-10-24
Which tools need which access?
Read
Works with any token, including a read only one. A read only token is refused on every write tool, even with a dry run.
Write, proposal (needs Read & write)
The call stores a proposal that expires after 15 minutes and changes nothing until it is applied with mcp_proposals_apply.
Write, own approval steps (needs Read & write)
The tool runs when called and has its own draft, approval and publish steps. Pass dryRun set to true for a preview that creates nothing.
Client approver tokens
A client approver's write token can only approve or reject replies. A client viewer can only have read only tokens.
Which resources can an agent open?
review-queue(opengmb://reviews/queue): Replies pending approval, blocked or conflicted, and posts pending approval or blocked. Needs thereview:approvepermission.google-pending-updates(opengmb://google/pending-updates): Open profile changes: edits made outside OpenGMB and updates Google suggested. Needs thelocation:readpermission.audit-recent(opengmb://audit/recent): The last 100 audit rows. Needs theaudit:readpermission.
workspaces tools
workspaces_list
Read: works with any token
Needs the workspace:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List the workspaces the caller can see in their organization, ordered by name, each with defaultPostLanguage (the language new posts start in), timeZone (IANA, the zone the client's times are shown and scheduled in), timeZoneSource and dateFormat.
workspaces_create
Write, proposal: needs a Read & write token
Needs the workspace:create permission. Roles with it: owner, admin, manager.
Create a workspace (shown as a client in the app) in the caller's organization. Names are unique per organization, ignoring upper and lower case.
namerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
workspaces_rename
Write, proposal: needs a Read & write token
Needs the workspace:manage permission. Roles with it: owner, admin.
Rename a workspace (shown as a client in the app). Names are unique per organization, ignoring upper and lower case; changing only the casing of its own name is allowed. Needs workspace:manage (owner, admin).
workspaceIdrequirednamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
workspaces_delete
Write, proposal: needs a Read & write token
Needs the workspace:manage permission. Roles with it: owner, admin.
Delete a workspace (a client in the app). Refused with CONFLICT while the client has any location, and while anything else still belongs to it (people, posts, reports, templates); remove those first. Its reply settings are deleted with it. Needs workspace:manage (owner, admin).
workspaceIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
workspaces_erase_data
Write, proposal: needs a Read & write token
Needs the workspace:erase permission. Roles with it: owner.
Permanently delete one client (workspace) and everything OpenGMB stores for it: locations, reviews, replies, posts, profile history, media records, reports, templates, people's access and invitations, in one transaction. confirmName must equal the client's name exactly. Does NOT delete anything on Google (posts, replies, profile edits already published stay there), does not delete people's accounts or the agency's Google connection, and keeps the audit log (append-only; it is the proof of this erasure). Leaves one tombstone audit row with the client id and row counts, no personal data. Export first: this cannot be undone. Needs workspace:erase (owner only).
workspaceIdrequiredconfirmNamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
workspaces_export_data
Read: works with any token
Needs the workspace:manage permission. Roles with it: owner, admin.
Export everything OpenGMB stores for one client (workspace) as one JSON document: locations, reviews, replies, assignments and notes, posts and edits, profile snapshots and changes, media records, reports, templates, people and invitations, and the audit rows about the client. Never includes secrets (Google tokens, API token hashes, passwords, two-factor secrets, invitation and share-link token hashes) or anything held only on Google. Refused above 1,000,000 rows. Each export is recorded in the audit log (counts only). Needs workspace:manage (owner, admin).
workspaceIdrequired
workspaces_setPostLanguage
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Set the language new posts in a workspace start in: posts.createDraft uses it when no language is given, and each post can still pick its own. language: one of en, es, fr, de, it, pt, nl, vi, zh, ko, ja, ar, hi, gu (BCP 47). Existing posts keep their language. Needs review:configure (owner, admin).
workspaceIdrequiredlanguagerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
workspaces_setTimeSettings
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Set a workspace's time zone and date format. timeZone: an IANA zone such as Asia/Kolkata, America/Chicago or Australia/Sydney. dateFormat: one of YYYY-MM-DD, DD/MM/YYYY, MM/DD/YYYY. Times in the app, scheduled posts, recurring posts, report schedules and digests use the zone; stored times do not change. Pass only the fields to change. Needs review:configure (owner, admin).
workspaceIdrequiredtimeZoneoptionaldateFormatoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
audit tools
audit_list
Read: works with any token
Needs the audit:read permission. Roles with it: owner, admin.
List audit log entries for the caller's organization, newest first, with the acting user's name (null for system rows) and each row's before/after. Optional filters, applied before limit: surface (ui, mcp, worker, cli) and actorUserId. Pass beforeId (the smallest id seen) with the same filters to page.
limitoptionalbeforeIdoptionalsurfaceoptionalactorUserIdoptional
audit_verify
Read: works with any token
Needs the audit:read permission. Roles with it: owner, admin.
Verify the caller's organization audit chain: recompute every row hash and link, and compare the chain head (last id, hash, row count) with the signed checkpoint. checkpoint is ok, missing (rows exist but no checkpoint yet), invalid_signature, or mismatch (rows were deleted or truncated).
audit_export
Read: works with any token
Needs the audit:read permission. Roles with it: owner, admin.
Export the caller's organization audit log as CSV or JSON, ordered by id ascending. from is inclusive and to is exclusive, both ISO datetimes compared in UTC at millisecond precision. limit defaults to 5000 (max 5000); when truncated is true, pass nextAfterId as afterId to continue. before/after are canonical JSON. The result includes the current signed checkpoint, so a copy of the signed chain head leaves the system with each export. Each export is itself recorded as an audit.export audit row.
formatrequiredfromoptionaltooptionallimitoptionalafterIdoptional
apiTokens tools
apiTokens_list
Read: works with any token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List API tokens in the caller's organization, newest first, including revoked ones. Members see their own tokens; owners and admins see everyone's. Never returns token secrets.
apiTokens_create
Write, proposal: needs a Read & write token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Create an API token for the caller. The plaintext token is returned once and cannot be recovered. scopes: ["read"] makes a read-only token (cannot run any write tool; resources stay readable), ["read","write"] (the default) a read and write token; client_viewer tokens are always read-only. Not available to callers authenticated by an API token.
namerequiredscopesoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
apiTokens_revoke
Write, own approval steps: needs a Read & write token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Revoke an API token by id. Members may revoke their own tokens; owners and admins may revoke any token in the organization.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
apiTokens_current
Read: works with any token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Who is calling: the caller's organization, user email and role, plus the API token's id, name and scopes (token is null for a web session). Use it to test a connection.
webhooks tools
webhooks_list
Read: works with any token
Needs the webhook:manage permission. Roles with it: owner, admin.
List the organization's outgoing webhooks (owners and admins only), newest first, each with its status, why it was turned off if it was, and its most recent delivery. Never returns signing secrets.
webhooks_subscribe
Write, own approval steps: needs a Read & write token
Needs the webhook:manage permission. Roles with it: owner, admin.
Create an outgoing webhook that POSTs a signed JSON event to an https URL (port 443, public hosts only) when a new review arrives (event "review.created"). Owners and admins only; an API token needs the write scope. Executes directly (no proposal step); dryRun previews and checks the URL. The signing secret (starts "whsec_") is returned once and cannot be recovered: store it now. Optional workspaceId limits it to one client. At most 10 active webhooks per organization.
urlrequiredeventsoptionalworkspaceIdoptionaldescriptionoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
webhooks_unsubscribe
Write, own approval steps: needs a Read & write token
Needs the webhook:manage permission. Roles with it: owner, admin.
Delete an outgoing webhook by id, with its delivery history. Owners and admins only. Executes directly; dryRun previews.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
webhooks_setStatus
Write, proposal: needs a Read & write token
Needs the webhook:manage permission. Roles with it: owner, admin.
Turn an outgoing webhook "active" or "disabled" by id. Turning it on again clears its failure count. Owners and admins only. At most 10 webhooks can be active.
idrequiredstatusrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
webhooks_deliveries
Read: works with any token
Needs the webhook:manage permission. Roles with it: owner, admin.
List the last 50 deliveries of one outgoing webhook, newest first: status, HTTP status code, attempts and times. Never returns the payload or the signing secret. Deliveries are kept for 30 days.
idrequired
webhooks_sendTest
Write, own approval steps: needs a Read & write token
Needs the webhook:manage permission. Roles with it: owner, admin.
Queue one sample "review.created" event (marked test: true) to an active outgoing webhook, signed like a real one. Owners and admins only. Executes directly; check the result with webhooks.deliveries.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
billing tools
billing_get
Read: works with any token
Needs the billing:read permission. Roles with it: owner, admin.
Read this account's billing: state (trial, active, read-only), credit balance in USD, each credit grant with its expiry, recent usage and the top-up sizes. Hosted OpenGMB only; on a self-hosted server the state is 'off'. Never returns keys or payment details. Needs billing:read (owner, admin).
billing_topups_create
Write, proposal: needs a Read & write token
Needs the billing:manage permission. Roles with it: owner.
Start a prepaid top-up: creates a payment order for one of the configured top-up sizes (optionIndex into billing.get topUpOptionsUsd). The amount is decided by the server. Web only: not available to API tokens or MCP. Needs billing:manage (owner).
optionIndexrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
billing_topups_confirm
Write, proposal: needs a Read & write token
Needs the billing:manage permission. Roles with it: owner.
Confirm a top-up after checkout: verifies the payment signature against the order stored for this account, checks with the provider that it is paid for the right amount, then adds the credit once. If the provider has not marked it paid yet, nothing is added and the webhook finishes the job. Web only: not available to API tokens or MCP. Needs billing:manage (owner).
razorpayOrderIdrequiredrazorpayPaymentIdrequiredrazorpaySignaturerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
billing_subscription_start
Write, proposal: needs a Read & write token
Needs the billing:manage permission. Roles with it: owner.
Start the monthly plan: creates a subscription for this account with the configured plan (the price and the included credit come from config, never from the caller) and returns what checkout needs. Nothing is charged until the owner pays in checkout. Refused when the plan is already active, a renewal is overdue, or the account is not billed. Web only: not available to API tokens or MCP. Needs billing:manage (owner).
dryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
billing_subscription_confirm
Write, proposal: needs a Read & write token
Needs the billing:manage permission. Roles with it: owner.
Confirm the monthly plan after checkout: verifies the payment signature against the subscription stored for this account, asks the provider whether it is active, then activates it and adds the month's included credit once. If the provider has not activated it yet, nothing is added and the webhook finishes the job. Web only: not available to API tokens or MCP. Needs billing:manage (owner).
razorpaySubscriptionIdrequiredrazorpayPaymentIdrequiredrazorpaySignaturerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
billing_subscription_cancel
Write, proposal: needs a Read & write token
Needs the billing:manage permission. Roles with it: owner.
Cancel the monthly plan at the end of the month already paid for. Access and the included credit last until then; nothing is refunded and nothing is charged again. Web only: not available to API tokens or MCP. Needs billing:manage (owner).
dryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
googleConnections tools
googleConnections_list
Read: works with any token
Needs the google:read permission. Roles with it: owner, admin, manager.
List the Google accounts connected to the caller's organization for Business Profile access, newest first. Never returns token material. configured is false when the server has no Google OAuth credentials, in which case connecting is unavailable.
googleConnections_connect
Write, proposal: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Start connecting a Google account. Returns an authUrl that must be opened in a browser where the SAME user is signed in to OpenGMB; it expires at expiresAt (10 minutes) and works once. The connection is created when Google redirects back to OpenGMB.
dryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
googleConnections_disconnect
Write, proposal: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Disconnect a Google account: revoke its refresh token at Google (best effort), then delete the connection. If Google could not be reached, the connection is still removed locally, revokedAtGoogle is false and warning says to remove access at https://myaccount.google.com/permissions.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
notifications tools
notifications_list
Read: works with any token
Needs the notification:own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List the caller's own in-app notifications, newest first, with the total unreadCount. Only the caller's notifications in their organization are ever returned. Titles name the location, never review text.
unreadOnlyoptionallimitoptional
notifications_markRead
Write, proposal: needs a Read & write token
Needs the notification:own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Mark the caller's own notifications as read: pass ids (1-100 notification ids) or all: true. Ids that belong to someone else or do not exist are silently ignored; updated counts only notifications that were unread and the caller's.
idsoptionalalloptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locations tools
locations_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List locations the caller can see, newest first, with their groups. needsRelink is true when Google was disconnected and the location must be re-imported to re-link it. Optional filters: workspaceId, groupId, status (active|inactive). Optional locationIds (up to 500) for specific locations. Client roles only see their own workspaces.
workspaceIdoptionalgroupIdoptionalstatusoptionallocationIdsoptional
locations_listAvailable
Read: works with any token
Needs the location:manage permission. Roles with it: owner, admin, manager.
List the Google accounts and locations reachable through one of the organization's Google connections, each marked alreadyImported (with the workspace when it is in this organization; activeInAnotherOrg when another organization holds it active). Calls Google, so it runs outside any database transaction. Follows up to 20 pages of 100 per account; truncated is true if there were more.
connectionIdrequired
locations_import
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Import Google locations into a workspace. Asynchronous: records the request and queues a worker job that fetches the details from Google itself (client-supplied details are never trusted) and creates the locations. Returns importId; poll locations.importStatus for per-location results (imported, already_imported, relinked, exists_inactive, conflict, not_found). A location already active in this workspace whose Google connection was removed is re-linked to the importing connection (relinked). A location already active in another organization or workspace is reported as conflict.
connectionIdrequiredworkspaceIdrequiredlocationsrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locations_importStatus
Read: works with any token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Status of a locations.import request: pending, done (with per-location results) or failed (with a reason).
importIdrequired
locations_setStatus
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Activate or deactivate up to 100 locations. Returns a result per location: updated, unchanged, conflict (activating a location whose Google location is active elsewhere, in any organization) or not_found. Inactive locations are excluded from sync, webhook processing, the inbox and the bulk tool.
locationIdsrequiredstatusrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locations_stats
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Per-location counts from OpenGMB's own tables, no Google call: synced reviews (total, average star rating, unreplied = reviews that need you: no visible reply and none waiting for approval or publish, or a reply that is blocked or failed, with the workspace reply policy applied, any age; waitingToPublish = approved reply not yet on Google), open profile changes (the alerts the change watch raised: snapshot diffs and Google-suggested edits) and whether a suspension case is open or appealed. Same order as locations.list (by name). Filters: workspaceId, locationIds (up to 500). Inactive locations are included. Client roles only see their own workspaces; ids outside the caller's scope are left out.
workspaceIdoptionallocationIdsoptional
locations_healthcheck
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Healthcheck of one location: a checklist of listing quality (description, categories, hours, phone, website, photos, posts, reviews, verification, place action links, attributes, services) with a score and a fix link for each failing check. Reads the profile, photos, posts, verification, place action links and attributes live from Google (outside any transaction) and reviews from our synced copy. Each check has an importance (necessary, important, nice), a status (pass, fail, unknown = the Google read failed, left out of the score) and a plain-language detail. score = passed / (passed + failed). Thresholds are our own choices (photo count, post age, rating ...), see config/healthcheck.ts. A check someone skipped (locations.healthcheckSkip) has status skipped and is left out of the score. Read only.
locationIdrequired
locations_healthcheckSummary
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Runs the healthcheck (see locations.healthcheck) for each active, Google-linked location in the caller's scope, one after another, and returns per location its score and how many necessary checks fail, worst score first. Each location also lists its failing checks (id, title, importance; necessary first) and checkedAt. Optional workspaceId. Runs one page of 25 locations (our choice: each costs about 7 Google reads), by name; `offset` (default 0) is where the page starts and `total` is how many locations are in scope, so offset + locations.length < total means more pages follow. Optional locationIds (up to 500) or groupId narrows what is paged (a location or group scope). Client roles only see their own workspaces. Read only.
workspaceIdoptionallocationIdsoptionalgroupIdoptionaloffsetoptional
locations_healthcheckSkip
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Skip one health check for one location (skipped true) or undo it (false). A skipped check shows as skipped and is left out of the location's score everywhere (healthcheck, healthcheckSummary, overview) until undone. checkId is one of: description, primary_category, additional_categories, regular_hours, special_hours, phone, website, website_utm, service_items, photo_count, recent_photo, logo_photo, cover_photo, recent_post, unreplied_reviews, average_rating, new_reviews, verification, place_action_link, attributes. Idempotent. Writes nothing to Google.
locationIdrequiredcheckIdrequiredskippedrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locations_overview
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One location's front page: its header facts (workspace, address, status, needsRelink), review/alert/suspension counts (as locations.stats), the last post OpenGMB published, change sets waiting for approval or apply that target it, the open suspension case with evidence progress, sync state, the 5 most recent events (changes found, change sets proposed, posts and replies published) and, for an active Google-linked location, one pass of the healthcheck's Google reads (about 7 calls, outside any transaction) giving the live health score, verification standing, primary category, today's hours and whether it is open now (both read in the workspace's time zone), phone, website, photos and booking links. Each Google part is null when its read failed; google is null for inactive or unlinked locations. Read only.
locationIdrequired
locationGroups tools
locationGroups_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List location groups the caller can see (optionally one workspace), with member location ids. Groups are per workspace.
workspaceIdoptional
locationGroups_create
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Create a location group in a workspace. Names are unique per workspace.
workspaceIdrequirednamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locationGroups_rename
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Rename a location group. Names are unique per workspace.
groupIdrequirednamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locationGroups_delete
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Delete a location group. Its locations are not deleted.
groupIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locationGroups_setMembers
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Replace a group's members with exactly these locations (empty clears it). Every location must be in the group's workspace, otherwise INVALID_INPUT and nothing changes.
groupIdrequiredlocationIdsrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviews tools
reviews_sync
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Request a review sync from Google for the active locations of a workspace (or just locationIds in it). Asynchronous: records one review_syncs row per location, audits it and queues a worker job per location in the same transaction; poll reviews.syncStatus with the returned syncIds. Inactive or unknown locations are listed in skipped. Replies made directly in Google are picked up too.
workspaceIdrequiredlocationIdsoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviews_syncStatus
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Status of review syncs started with reviews.sync: pending, done (with counts fetched/inserted/updated) or failed (with an error). Only syncs for locations in the caller's workspaces are returned; unknown ids are omitted.
syncIdsrequired
reviews_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List Google reviews for active locations the caller can see. Order: sort newest (default; create time, then id), oldest, rating_high (5 stars first) or rating_low (1 star first); unrated reviews come last in both rating sorts and ties go newest first. Search: q finds reviews whose text or reviewer name contains the phrase (case-insensitive, matched literally, so % and _ are ordinary characters; an anonymous reviewer's name is not searched). Filters: workspaceId, locationIds, groupId, ratings (1-5), replied (true = Google shows a reply; false = the review needs you: no visible reply and no reply waiting for approval or publish, or a reply that is blocked or failed, with the workspace reply policy applied), from (inclusive) and to (exclusive) as ISO datetimes on the review's create time (UTC), topic (one of the ids reviews.classifyTopics uses: staff, wait_time, price_value, cleanliness, results_quality, communication, booking, location_parking, other) and sentiment (positive, negative or mixed: that topic's sentiment when topic is set, otherwise the review's overall sentiment); these two only match reviews already classified and not edited since. limit 1-100 (default 25); pass nextCursor as cursor for the next page. Client roles only see their own workspaces.
workspaceIdoptionallocationIdsoptionalgroupIdoptionalratingsoptionalrepliedoptionalfromoptionaltooptionalqoptionaltopicoptionalsentimentoptionalsortoptionalcursoroptionallimitoptionalassignedToMeoptionaloverdueoptional
reviews_export
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Export reviews as a CSV spreadsheet (UTF-8 with BOM, CRLF lines), newest first unless sort says otherwise, with the same filters, search (q), sort and visibility as reviews.list (workspaceId, locationIds, groupId, ratings, replied, from, to, q, sort; no paging). Columns: review date (UTC), location, stars, reviewer (Anonymous when hidden), review text, reply text, reply date, Google reply state, needs reply (yes/no, the same rule as the replied=false filter). Optional columns picks which columns to write (date, location, stars, reviewer, review, reply, replyDate, replyState, needsReply); they are written in that order; omitted means all nine. Leave out reviewer and review to export counts and ratings only. Capped at a fixed row maximum: truncated is true when more matched, so narrow the filters. Review text can contain patient details: the export is audited (reviews.exported) with filters and row count only, never the text.
workspaceIdoptionallocationIdsoptionalgroupIdoptionalratingsoptionalrepliedoptionalfromoptionaltooptionalqoptionaltopicoptionalsentimentoptionalsortoptionalcolumnsoptional
reviews_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Get one review by id, with its current Google reply. Only reviews at active locations in the caller's workspaces are visible; anything else is NOT_FOUND.
idrequired
reviews_list_unreplied
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Bulk list of reviews with no visible Google reply (none, or one Google rejected), across every active location the caller can see, newest first (create time, then id). Optional filters: workspaceId, locationIds, ratings (1-5). Each item carries replyAllowed and skipReason (from the reply policy, e.g. reviews that must not be answered, or a reply already in progress) and openReply (the open draft or pending reply, if any) so you do not draft replies that will be blocked or refused; skipped items are left out unless includeSkipped is true. limit 1-200 (default 100); pass nextCursor as cursor for the next page. totalReturned is the number of items in this response, not a total.
workspaceIdoptionallocationIdsoptionalratingsoptionalincludeSkippedoptionalcursoroptionallimitoptional
reviews_assign
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Assign a review to a team member (an organization-wide owner, admin or manager; client roles cannot be assigned), with an optional due date (ISO datetime; omitted clears it) and an optional internal note added in the same step. Assigning again replaces the assignee and due date. assigneeUserId null removes the assignment. The assignee gets an in-app notification (and the daily email digest when email is configured) unless they assigned it to themselves. The notification names the location only, never the review or the note. Internal only: nothing here reaches Google or a reply. Needs review:draft.
reviewIdrequiredassigneeUserIdrequireddueAtoptionalnoteoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviews_assignees
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Team members a review in this workspace can be assigned to: the organization-wide members (owner, admin, manager). Client roles are never listed. Needs review:draft.
workspaceIdrequired
reviews_assignments
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Who each of up to 100 reviews is assigned to, with the due date, whether it is overdue (due date passed and the review still needs a reply) and how many internal notes it has. Reviews with neither an assignment nor a note are left out. Only reviews the caller can see are considered. Needs review:draft: client roles never see assignments.
reviewIdsrequired
reviews_analytics
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Review analytics by plain arithmetic over synced reviews, no AI: for the window from (inclusive) to (exclusive), ISO datetimes, at most 800 days, and the equally long window right before it. Returns totals (count, average rating to one decimal, reply rate 0 to 1, median hours from review to reply using Google's reply update time, number needing a reply: no reply or a reply Google rejected), new reviews and average rating per UTC month, the star distribution, and per location totals with a rating trend. Filters: workspaceId, locationIds, groupId. Active locations in the caller's workspaces only. Returns no review text, reviewer names or reply text. truncated is true when a window held more than 50,000 reviews.
workspaceIdoptionallocationIdsoptionalgroupIdoptionalfromrequiredtorequired
reviews_classifyTopics
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Classify a client's reviews by topic and sentiment with AI (topics: staff, wait_time, price_value, cleanliness, results_quality, communication, booking, location_parking, other; sentiment positive, negative or mixed, per topic and overall). Takes reviews that have text and no current classification, newest first, up to 200 per run (remaining says how many still wait; run again). Several reviews go in one AI call. A review that was already classified and has not been edited is never classified or paid for again; an edited review is classified again. A review the AI answered badly twice is marked unclassified and is retried by the next run. Metered and capped like drafts: stopped 'cap' means a monthly AI limit was reached (what was done is kept), 'error' means the AI service failed. Only topics and sentiment are stored, never the review text, and review text is never logged. Optional locationIds narrows to those locations of the client. NOT_CONFIGURED when this server has no AI key. Needs review:draft (owner, admin, manager).
workspaceIdrequiredlocationIdsoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviews_topicTrends
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Review topics over the last 12 weeks (UTC weeks starting Monday, by the review's create time), from reviews already classified by reviews.classifyTopics (nothing here calls AI). For the whole scope: per topic the number of mentions (total) and how many were positive, negative or mixed, with positiveShare and negativeShare (0 to 1, null when no mentions), and the same counts for each week. Per location: the same per-topic counts over the window. Also classifiedReviews and the overall sentiment counts. Reviews edited since they were classified are left out until classified again. Filters: workspaceId, locationIds, groupId. Active locations in the caller's clients only. Counts only: no review text or reviewer names. truncated is true when more than 50000 reviews matched.
workspaceIdoptionallocationIdsoptionalgroupIdoptional
reviewNotes tools
reviewNotes_add
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Add an internal note to a review (up to 2000 characters). Notes are for the team only: they are never sent to Google, never part of a reply, and client roles cannot see them. The audit entry records that a note was added, not its text. Needs review:draft.
reviewIdrequiredbodyrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewNotes_list
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
The internal notes on a review, oldest first, with who wrote each. Team only (needs review:draft): client roles never see notes.
reviewIdrequired
reviewLinks tools
reviewLinks_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Review request tools for one location: its tracked review link (slug, the /go/<slug> path, Google's review form URL, widget settings and the sentence the widget shows about which reviews it displays), link opens in the last 30 UTC days by source (link, qr, sms, email; never matched to reviews), new reviews in the last 30 days, the average rating and count of all synced reviews, and the workspace reply profile. When no link exists yet, suggestedPlaceId is Google's place id for the location if Google could be read, else null. Read only. Needs review:read.
locationIdrequired
reviewLinks_save
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create or update the tracked review link of an active location. Creating needs placeId (Google place id, letters, digits, - and _, 10 to 300 characters) and generates the public slug. Later calls change only the fields passed: placeId, widgetEnabled (the website widget is off until turned on), widgetMinRating (1 shows every rating, 4 shows 4 and 5 stars; the widget always states it), widgetLayout (grid, list, carousel, badge). A healthcare workspace starts with the badge layout (rating and count, no review text). Does not write to Google. Needs review:draft (owner, admin, manager).
locationIdrequiredplaceIdoptionalwidgetEnabledoptionalwidgetMinRatingoptionalwidgetLayoutoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests tools
reviewRequests_create
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create a draft email campaign that asks customers of one location to leave a Google review. Every recipient gets the same message and the same link to Google's review form; there is no rating question and no routing of unhappy customers. Refuses a location that has no review link yet (create it with reviewLinks.save first, it holds the Google place id). subject and body may use {name} and {business}; omitted, a plain default is used. At most one reminder, reminderDays (1 to 14, default 3) after the first email, only to people who have not clicked. Nothing is sent until reviewRequests.start. Needs review:draft (owner, admin, manager).
locationIdrequirednamerequiredsubjectoptionalbodyoptionalreminderEnabledoptionalreminderDaysoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_update
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Change a DRAFT review request campaign: name, subject, body, reminder on or off, reminder days (1 to 14). A started campaign cannot be edited (cancel it and make a new one). Needs review:draft.
campaignIdrequirednameoptionalsubjectoptionalbodyoptionalreminderEnabledoptionalreminderDaysoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_addRecipients
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Add customers (email and optional name) to a draft or running campaign, one or a few at a time. confirmPermission must be true: the caller confirms they have permission to email these customers (recorded in the audit log, counts only, never the addresses). Addresses are lower-cased; duplicates, invalid addresses and addresses that opted out of this client earlier are not emailed and are counted in the answer. Needs review:draft.
campaignIdrequiredrecipientsrequiredconfirmPermissionrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_importCsv
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Add customers from CSV text to a draft or running campaign. The first row may be a header with an "email" column and a "name" or "first name" column; without a header column 1 is the email and column 2 the name. At most 500 rows per import. confirmPermission must be true (recorded in the audit log, counts only). Same rules as addRecipients. Needs review:draft.
campaignIdrequiredcsvrequiredconfirmPermissionrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_start
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Start a draft campaign. Refused unless email sending is set up, the public app URL is configured, the location still has its review link, there is at least one recipient waiting, and the subject and message pass the wording check (no ratings, stars, surveys or 'how was your visit') and the universal and post guardrail packs. Sending then happens in the background: the worker paces it (a daily limit for the whole server, only 08:00 to 21:00 in the client's time zone). Needs review:draft.
campaignIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_cancel
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Cancel a campaign: no further first emails or reminders go out. Emails already sent stay sent. Needs review:draft.
campaignIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewRequests_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Review request email campaigns, newest first, each with its results: recipients, sent, clicked, opted out, reminder sent, skipped, failed, waiting. Optionally for one location. Counts only, no customer addresses. Delivery confirmation is not tracked. Needs review:read (client roles can view results).
locationIdoptionallimitoptional
reviewRequests_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One review request campaign with its results (counts only). Needs review:read.
campaignIdrequired
reviewRequests_recipients
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
The customers of a campaign with their status (email addresses and names: personal data). Needs review:draft, so client roles do not see it.
campaignIdrequiredlimitoptionaloffsetoptional
locationPages tools
locationPages_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The public landing page of one location: whether it is published, its slug and its path (/l/<slug> on the app's address). The page is off until someone publishes it and shows only data OpenGMB already holds. page is null when it was never published. Read only. Needs location:read.
locationIdrequired
locationPages_set
Write, proposal: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Publish or unpublish the public landing page of an active location (published true or false). The first publish creates the page and its public slug; unpublishing keeps the slug and makes the address return 404 and stay out of search. The page shows the profile (name, categories, description, hours, address, phone, website, services), recent reviews with a comment (the review widget's rules apply), recent Google posts and the agency branding. Does not write to Google. Needs location:manage (owner, admin, manager).
locationIdrequiredpublishedrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewReplies tools
reviewReplies_check
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Dry-run the reply guardrails for a candidate reply to a review. Writes nothing and stores nothing. Returns { ok, violations, packs }: ok is false when any violation has severity block (blocks cannot be overridden); warn violations need acknowledgeWarnings on submit/publish. Each violation has ruleId, packId, severity, status (active or pending_counsel_review), message and match offsets into the reply. Use it to check an AI-drafted reply before reviewReplies.createDraft.
reviewIdrequiredbodyrequired
reviewReplies_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
All reply revisions of one review, newest revision first, with each revision's status, guardrail result and what the caller may do next (can.edit/submit/approve/reject/publish). The review block says whether the caller can start a draft (canDraft: no open revision), delete the Google reply, and whether a Google reply exists. Poll this after reviewReplies.publish.
reviewIdrequired
reviewReplies_listQueue
Read: works with any token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Approval and attention queue: replies in one status (pending_approval, blocked, failed, approved or conflict) across the workspaces the caller can see (or one workspaceId), at active locations, oldest update first. Each item carries the reply (with guardrail result and can.* flags) and the review it answers. limit 1-100 (default 25); pass nextCursor as cursor for the next page.
workspaceIdoptionalstatusrequiredcursoroptionallimitoptional
reviewReplies_createDraft
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create a draft reply to a review. A review has at most one open revision (draft, pending_approval, approved, blocked or failed): if one exists this is CONFLICT and the message names its id (use reviewReplies.updateDraft). If the review already has a Google reply this opens a new revision that, once published, replaces it. The draft remembers Google's reply as it is now: if someone changes that reply on Google before publishing, the publish is refused with status conflict (nothing is written to Google) and you open a new revision from Google's current reply. The draft is not sent anywhere: call reviewReplies.submit, which runs the guardrails.
reviewIdrequiredbodyrequireddryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_updateDraft
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Replace the text of a reply that is a draft or blocked (a blocked reply goes back to draft, with its guardrail result cleared). Replies that are pending approval, approved, failed or published cannot be edited: reject it, or open a new revision for a published one.
idrequiredbodyrequireddryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_submit
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Submit a draft reply: runs the guardrails. Any block-severity violation sets status blocked and returns the violations (not an error). Warnings only: the reply stays a draft and the result has outcome needs_acknowledgement and code WARNINGS_REQUIRE_ACKNOWLEDGEMENT; call again with acknowledgeWarnings true to proceed. Otherwise the workspace approval rule decides: approved (auto-approve; never for 1-3 star reviews) or pending_approval; if the workspace also auto-publishes, a publish job is queued. Guardrails run again just before anything is sent to Google.
idrequiredacknowledgeWarningsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_approve
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Approve a reply that is pending approval (pending_approval -> approved). Approving does not publish: call reviewReplies.publish. Client approvers can approve replies in their own workspaces only.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_reject
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Reject a reply that is pending approval: it goes back to draft with the reason shown to the author (pending_approval -> draft). The author edits and resubmits.
idrequiredreasonrequireddryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_publish
Write, own approval steps: needs a Read & write token
Needs the review:publish permission. Roles with it: owner, admin, manager.
Queue publishing of an approved (or failed) reply to Google. Asynchronous and does not call Google: it records the request, audits it and queues a worker job in the same transaction, returning { queued: true }. The worker runs the guardrails again and then sends the reply; poll reviewReplies.list until the status is published, failed (failureReason), blocked or conflict (someone changed the reply on Google after the draft; nothing was written, open a new revision). acknowledgeWarnings true accepts warn-severity violations that appear at publish time. A failed reply is retried by calling this again.
idrequiredacknowledgeWarningsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
reviewReplies_deletePublished
Write, own approval steps: needs a Read & write token
Needs the review:publish permission. Roles with it: owner, admin, manager.
Queue removal of the review's Google reply (a reply published here or made in Google). Asynchronous: audits the request and queues a worker job in the same transaction, returning { queued: true }. When the job finishes the review has no reply and the published revision is deleted. CONFLICT if the review has no Google reply.
reviewIdrequireddryRunoptional- Preview only: returns a preview and changes nothing.
workspaceSettings tools
workspaceSettings_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Get a workspace's reply settings: profile (general, healthcare, legal), guardrail packs, whether positive (4-5 star) reviews are skipped, generic-templates-only, staff names (used by the H2.staff guardrail) and approval rules (autoApproveMinStars 4, 5 or null; autoPublish) and h2Severity (block or warn: whether the HIPAA H2.* rules block or only warn). A workspace that was never configured returns the defaults. 1-3 star replies are always manual and never auto-published.
workspaceIdrequired
workspaceSettings_update
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Update a workspace's reply settings; only the fields you pass change. Changing profile first applies that profile's defaults (healthcare: hipaa pack on, skipPositiveReviews on, generic templates only; legal: legal_ethics pack on; general: none), then the other fields in the same call override them. packs may contain hipaa and legal_ethics (universal always runs); the profile's required pack cannot be removed. staffNames: up to 200 names of 2-80 characters. autoApproveMinStars: 4, 5 or null (off); autoPublish: publish automatically once approved. h2Severity: block (default) or warn, for all HIPAA H2.* rules together (reviewer/provider/staff names, clinical terms, dates, echoed review text); only has an effect while the hipaa pack is on, and warnings still need acknowledgeWarnings. 1-3 star replies are always manual and never auto-published. Needs review:configure (owner, admin).
workspaceIdrequiredprofileoptionalpacksoptionalskipPositiveReviewsoptionalstaffNamesoptionalautoApproveMinStarsoptionalautoPublishoptionalh2SeverityoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
replyTemplates tools
replyTemplates_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List a workspace's reply templates, ordered by name. generic is true when the body uses no reviewer-specific variable ({reviewer_first_name}); healthcare workspaces can only render generic templates. Variables: {reviewer_first_name}, {location_name}, {phone}.
workspaceIdrequired
replyTemplates_create
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Create a reply template in a workspace. Names are unique per workspace. The body may use only {reviewer_first_name}, {location_name}, {phone}; any other {variable} is INVALID_INPUT. generic is computed from the body. Needs review:configure (owner, admin).
workspaceIdrequirednamerequiredbodyrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
replyTemplates_update
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Rename a reply template and/or change its body (same variable rules as replyTemplates.create: only {reviewer_first_name}, {location_name}, {phone}). generic is recomputed. Needs review:configure (owner, admin).
idrequirednameoptionalbodyoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
replyTemplates_delete
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Delete a reply template. Needs review:configure (owner, admin).
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
replyTemplates_render
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Render a reply template for a review and return the text only (nothing is saved or published; use it as a draft body, guardrails still apply). {reviewer_first_name} is the first word of the reviewer's name (error "reviewer name unavailable" for anonymous reviewers), {location_name} the location's title, {phone} its phone number (error naming the variable if missing). In a workspace with generic-templates-only (healthcare profile), non-generic templates are FORBIDDEN. The template and review must be in the same workspace.
templateIdrequiredreviewIdrequired
postImages tools
postImages_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List a workspace's post image library (JPG or PNG, up to 5 MB each, newest first, at most 500). Each image has a public `url`: pass it as a post's media sourceUrl (posts.createDraft / posts.updateDraft, one image per post) to attach it. `usedIn` lists the posts that use it with their status; canDelete is false while a pending, approved, scheduled or publishing post uses it. Images are uploaded in the web app; agents cannot upload or delete.
workspaceIdrequired
postImages_rename
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Rename an image in the post image library (a display name only; the public URL does not change). Needs review:draft (owner, admin, manager).
idrequirednamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
postImages_delete
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Delete an image from the post image library. Refused (CONFLICT) while a pending, approved, scheduled or publishing post uses it. Posts already on Google keep their copy; a draft that uses it will show a missing image. Not available to agents (FORBIDDEN over MCP). Needs review:draft.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
postImages_renderBranded
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Make a branded post image: take a photo from the client's post image library (photoImageId from postImages.list), draw the client's uploaded logo (if it has one) and a headline plus optional second line over it in a fixed white layout ('band' along the bottom, or 'frame'), and save the result to the same library as a 1200x900 JPEG. Returns the new image; put its url in a post's media sourceUrl. The same inputs always give the same image. Latin-script (English) text only. Needs review:draft.
workspaceIdrequiredphotoImageIdrequiredlayoutrequiredheadlinerequiredsublineoptionaluseLogooptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
postTemplates tools
postTemplates_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List a workspace's post templates (name order). A template holds a post type (STANDARD, EVENT or OFFER), language, text, call to action, event title, offer fields and one library image; it has no locations, send time or event dates. To post from one, read it and call posts.createDraft with its content (a post made from a template is an ordinary draft).
workspaceIdrequired
postTemplates_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Get one post template by id.
idrequired
postTemplates_create
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create a post template in a workspace. Names are unique per workspace (CONFLICT otherwise). imageId must be an image from postImages.list. Needs review:draft (owner, admin, manager).
workspaceIdrequirednamerequiredtopicTyperequiredlanguagerequiredsummaryoptionalctaoptionaleventTitleoptionalofferoptionalimageIdoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
postTemplates_update
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Replace a post template's content (send every field; imageId null removes the image). Posts already made from it are not changed. Needs review:draft.
idrequirednamerequiredtopicTyperequiredlanguagerequiredsummaryoptionalctaoptionaleventTitleoptionalofferoptionalimageIdoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
postTemplates_delete
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Delete a post template. Posts already made from it are not affected. Needs review:draft.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
posts tools
posts_check
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Dry-run the post guardrails for a candidate Google Business Profile post. Writes nothing. Returns { ok, violations, packs }: ok is false when any violation has severity block (blocks cannot be overridden); warn violations need acknowledgeWarnings on posts.submit. Rules (pack post): no phone numbers in text (use a CALL button, which uses the location's phone), summary at most 1,500 characters, at most 1 image, call to action rules (URL required except for CALL, none for CALL), ALERT restrictions, EVENT/OFFER need an event title and dates. Healthcare workspaces also apply H1 (care relationship wording), provider and staff names; legal workspaces apply LE3/LE4. Pass locationIds to check with those locations' names and phones.
workspaceIdrequiredlocationIdsoptionaltopicTyperequiredalertTypeoptionalsummaryoptionalctaoptionaleventoptionalofferoptionalmediaoptional
posts_list
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Posts the caller can see, newest first. Filters: workspaceId, status, topicType, q (case-insensitive text in the summary), locationId (posts that target it), from (inclusive) and to (exclusive) ISO datetimes applied to the scheduled time (or the creation time when unscheduled). sort oldest_submitted lists the earliest submission first (unsubmitted last) instead of newest first. limit 1-100 (default 50). Each post carries its per-location targets. Use status pending_approval for the approval queue. googleOnly lists posts that are live on Google but were made outside OpenGMB (same filters, except status: only with no status or published); an OpenGMB post that is also on Google appears in posts only.
workspaceIdoptionalstatusoptionaltopicTypeoptionalqoptionalsortoptionallocationIdoptionalfromoptionaltooptionallimitoptional
posts_googleList
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List the posts currently on a location's Google Business Profile, live from Google, including ones made outside this app (in the Google UI or another tool). Newest first as Google returns them. managedHere marks posts this app published. Read only; calls Google, so it runs outside any database transaction.
locationIdrequired
posts_syncGoogle
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Refresh OpenGMB's copy of one location's Google posts now, so All posts, the Calendar, Home, Performance and the Overview include posts made outside OpenGMB without waiting for the review sync (every 2 hours). Reads the posts from Google and stores them (a cache: Google is not changed, nothing is audited). Returns how many Google listed (fetched), how many stored copies of posts no longer on Google were dropped (removed), and truncated when Google had more pages than we read. Calls Google, so it runs outside any database transaction.
locationIdrequired
posts_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One post with its content, status, guardrail result, what the caller may do next (can.*) and the per-location results of every send (targets: status, googlePostName, publishedAt, error reason code).
idrequired
posts_calendar
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Calendar entries between from (inclusive) and to (exclusive), at most 366 days apart: scheduled sends, projected future occurrences of recurring posts (expanded only inside the window, respecting until/count), and past sends (published, failed or skipped, grouped per post and occurrence with per-status location counts), plus posts made outside OpenGMB that are live on Google (kind google, on their Google date). Optional workspaceId, and optional locationIds (up to 500) or groupId to keep only entries that touch those locations. Entry times are ISO instants. truncated is true if the entry cap (1000) was hit.
fromrequiredtorequiredworkspaceIdoptionallocationIdsoptionalgroupIdoptional
posts_createDraft
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create a draft Google Business Profile post for one or more locations of a workspace. topicType STANDARD (summary, optional CTA and one image), EVENT (event title + start/end dates, times optional), OFFER (event plus optional couponCode, redeemOnlineUrl, termsConditions; Google ignores a CTA on offers) or ALERT (alertType COVID_19; Google has disabled new COVID_19 alerts). callToAction actionType BOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP (all need an https url) or CALL (no url; uses the location's phone). media: one image by URL (uploads are not built yet). Do not put phone numbers in the summary. The draft is not sent anywhere: call posts.submit, which runs the guardrails. Content problems do not fail this call; posts.check shows them. language: the post's language, a BCP 47 code (en, es, fr, de, it, pt, nl, vi, zh, ko, ja, ar, hi, gu); omitted = the workspace's default post language (workspaces.list defaultPostLanguage). Sent to Google as languageCode. A bilingual post is two posts. scheduledFor (optional, ISO datetime with offset, not in the past) is the send time picked in Compose: it is only remembered on the draft and shown to the approver, nothing is sent until posts.schedule.
workspaceIdrequiredlocationIdsrequiredlanguageoptionalscheduledForoptionaltopicTyperequiredalertTypeoptionalsummaryoptionalctaoptionaleventoptionalofferoptionalmediaoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_bulkPreview
Read: works with any token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Dry-run a bulk post import. csv is the text of a CSV file with a header row (get the columns from the Import page's template): location (name or id), type (STANDARD default, EVENT, OFFER), summary, optional cta_type, cta_url, scheduled (YYYY-MM-DD HH:MM in the client's time zone, remembered on the draft only), image_url, event_title, event_start_date, event_end_date, event_start_time, event_end_time, coupon_code, redeem_url, terms. Variables {name}, {city}, {phone}, {address}, {website} in any text are filled from each row's location; an unknown variable or one with no stored value for that location is a row error (never left blank). At most 500 rows. Writes nothing. Returns per-row errors (the row cannot be created) and warnings (guardrail findings: the draft would exist but could not be submitted, for example a phone number written into the text). fileErrors means the file itself cannot be read and no rows are listed.
workspaceIdrequiredcsvrequired
posts_bulkCreateDrafts
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Create one DRAFT post per row of a CSV (same format and variables as posts.bulkPreview, at most 500 rows). ALL OR NOTHING: the file is re-validated here, and if the file or any row has an error nothing is created (INVALID_INPUT lists the first problems; run posts.bulkPreview and fix them). Each draft is made exactly as posts.createDraft makes it (one location, the workspace's default language, audit row per draft), so it still needs posts.submit, approval and posts.schedule: nothing is submitted, scheduled or sent. Guardrail findings do not stop a draft (posts.check shows them; submit blocks).
workspaceIdrequiredcsvrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_updateDraft
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Change a post that is a draft or blocked (a blocked post goes back to draft, with its guardrail result cleared). Send only the fields to change; a field sent as null (cta, event, offer, alertType) is cleared; media replaces the list; locationIds replaces the target locations. Posts that are pending approval, approved, scheduled or published cannot be edited: reject or cancel first. language changes the post's language. scheduledFor changes the remembered send time (null clears it; not in the past); omitted keeps it.
idrequiredlocationIdsoptionallanguageoptionalscheduledForoptionaltopicTypeoptionalalertTypeoptionalsummaryoptionalctaoptionaleventoptionalofferoptionalmediaoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_submit
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Submit a draft post: runs the guardrails for every target location. Any block-severity violation sets status blocked and returns the violations (not an error). Warnings only: the post stays a draft with outcome needs_acknowledgement and code WARNINGS_REQUIRE_ACKNOWLEDGEMENT; call again with acknowledgeWarnings true. Otherwise the post becomes pending_approval: posts always need a person with approval rights (there is no auto-approve). Guardrails run again, per location, just before the post is sent to Google.
idrequiredacknowledgeWarningsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_approve
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Approve a post that is pending approval (pending_approval -> approved). Approving does not send it: call posts.schedule. Client approvers can approve posts in their own workspaces only.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_reject
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Reject a post that is pending approval: it goes back to draft with the reason shown to the author (pending_approval -> draft). The author edits and resubmits.
idrequiredreasonrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_schedule
Write, own approval steps: needs a Read & write token
Needs the review:publish permission. Roles with it: owner, admin, manager.
Schedule an approved post. Google's native scheduling is not used: Synectus keeps the schedule and a worker sweeps every minute, sending posts that are due (so a send can be up to about a minute late). Omit scheduledFor to send now (the worker is queued in this call, nothing is sent to Google inside it). scheduledFor is an ISO datetime with offset (an instant), not in the past. recurrence { freq weekly|monthly, interval (default 1), and until (inclusive, ISO) and/or count (total sends including the first) } repeats it; one of until or count is required; a series keeps the same local clock time in the workspace's time zone (workspaces.list timeZone) across daylight-saving changes. locationIds optionally replaces the target locations. The worker runs the guardrails again for each location right before sending; one location failing does not stop the others. Poll posts.get for per-location results.
idrequiredscheduledForoptionalrecurrenceoptionallocationIdsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_cancel
Write, own approval steps: needs a Read & write token
Needs the review:publish permission. Roles with it: owner, admin, manager.
Cancel a post that has not been sent: draft, blocked, pending_approval, approved or scheduled (a recurring series stops; posts already published stay on Google, use posts.deletePublished to remove them). A post that is being sent right now (publishing) cannot be cancelled: CONFLICT.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_deletePublished
Write, own approval steps: needs a Read & write token
Needs the review:publish permission. Roles with it: owner, admin, manager.
Queue removal of the Google posts this post published (at all its locations, or only locationIds). Asynchronous: audits the request and queues a worker job in the same transaction, returning { queued: true }. When the job finishes those per-location results are deleted (Google 404 counts as deleted). CONFLICT if there is nothing published to delete.
idrequiredlocationIdsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_proposeEdit
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Propose a change to a post that is already published on Google (post status published). Nothing is sent to Google until a person with approval rights approves it (posts.approveEdit); then the worker patches the live post at each location with Google's localPosts.patch, naming only the changed fields in the updateMask. Send only the fields to change: summary, cta, event, offer, media (a null or empty field is cleared on Google). The topic type and language cannot change; a different type is a new post. The guardrails run now for every location the post is live at (a block-severity violation stores nothing and returns outcome blocked; warnings need acknowledgeWarnings) and again per location right before the patch. One open edit per post. CONFLICT if the post is not published, has no live Google post, or already has an open edit. Posts made on Google outside OpenGMB cannot be edited here. Google writes stay off unless GOOGLE_BUSINESS_WRITES is live: the edit then fails per location with google_writes_disabled.
idrequiredsummaryoptionalctaoptionaleventoptionalofferoptionalmediaoptionalacknowledgeWarningsoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
posts_approveEdit
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Approve a proposed edit of a published post (pending_approval -> applying). This is the step that lets the change reach Google: it queues a worker job that patches the live post at each location, running the guardrails again per location first. Poll posts.editGet for the per-location results. Client approvers can approve edits in their own workspaces only.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_rejectEdit
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Reject a proposed edit of a published post, with the reason shown to the author (pending_approval -> rejected). The live post is untouched; propose a new edit to try again.
idrequiredreasonrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_cancelEdit
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Withdraw a proposed edit that is still waiting for approval (pending_approval -> cancelled). The live post is untouched.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
posts_editGet
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The latest proposed edit of a published post (any status), with the per-location results once it was approved, and whether the caller may propose a new one (canPropose: the post is published, has a live Google post and no open edit, and the caller may draft).
idrequired
geogrid tools
geogrid_configs_list
Read: works with any token
Needs the geogrid:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List geo-grid configurations the caller can see (a business, keywords, grid size and radius, data source, schedule). Optional filters: workspaceId, locationId. kind defaults to 'tracker'; pass 'quick_scan' for quick scans of businesses that are not managed locations (their locationId is null). Each config carries driverLabel and isMapsRank: the 'places_relevance' source is labelled 'Relevance check (not Maps rank)' and its positions are NOT Google Maps rank. Needs geogrid:read.
workspaceIdoptionallocationIdoptionalkindoptional
geogrid_configs_create
Write, proposal: needs a Read & write token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Create a geo-grid configuration for a location. centerLat/centerLng are required; geogrid.locationCenter reads them (and the place id) from the location's Google profile. gridSize is odd, 3 to 13; radiusM is the distance from the centre to the edge (100 to 50000). targetName defaults to the location's title; targetPlaceId (Google place id) is required for driverId 'places_relevance', which is a relevance check, NOT Maps rank. driverId 'dataforseo_standard' is the Maps-rank source and costs money (see geogrid.preview). Needs geogrid:manage (owner, admin, manager).
locationIdrequiredkeywordsrequiredgridSizerequiredradiusMrequiredcenterLatrequiredcenterLngrequiredtargetNameoptionaltargetPlaceIdoptionaldriverIdoptionalscheduleoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_locationCenter
Read: works with any token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Where a new tracker for a location should be centred, read from the location's Google profile: centerLat, centerLng (null when Google has no coordinates for it) and placeId (Google's place id, null when it cannot be read). note says why a value is missing (not linked to Google, no connection, Google could not be read) so the caller can ask the person to type it. Read only; does not change the location. Needs geogrid:manage (owner, admin, manager).
locationIdrequired
geogrid_configs_update
Write, proposal: needs a Read & write token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Change a geo-grid configuration (any of keywords, favoriteKeywords, gridSize, radiusM, centerLat, centerLng, targetName, targetPlaceId, driverId, schedule, active). favoriteKeywords is the full list of starred keywords (a subset of keywords, matched case-insensitively); removing a keyword drops its star. Past runs keep the settings they ran with. Schedules (daily, weekly, monthly) enqueue runs automatically and are subject to the org's monthly budget. Needs geogrid:manage.
idrequiredkeywordsoptionalfavoriteKeywordsoptionalgridSizeoptionalradiusMoptionalcenterLatoptionalcenterLngoptionaltargetNameoptionaltargetPlaceIdoptionaldriverIdoptionalscheduleoptionalactiveoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_configs_delete
Write, proposal: needs a Read & write token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Delete a geo-grid configuration together with its runs and results. Spend already charged still counts toward this month's budget only while the runs exist, so prefer setting active=false to keep history. Needs geogrid:manage.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_preview
Read: works with any token
Needs the geogrid:cost permission. Roles with it: owner, admin, manager.
Cost preview before running: estimate = points (gridSize squared) x keywordCount x the driver's per-task price x (1 + the org's markup). Pass speed ('standard' or 'fast', default the org's default speed) to price one speed; `speeds` always lists every speed side by side (standard: normal queue, about 5 min, $0.0006/task; fast: DataForSEO high priority, about 1 min, $0.0012/task). Returns the estimate, this UTC month's spend so far (queued and running runs count at their estimate), the monthly budget, what remains, and wouldExceed. The relevance check (places_relevance) is free and not Maps rank. Needs geogrid:cost (owner, admin, manager; hidden from client roles).
driverIdrequiredgridSizerequiredkeywordCountrequiredspeedoptional
geogrid_run
Write, proposal: needs a Read & write token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Run a geo-grid now: queues one run per keyword of the configuration (results arrive asynchronously; poll geogrid.runs.get). Fails with FORBIDDEN 'BUDGET_EXCEEDED' if the total estimate does not fit in the org's remaining monthly budget, or 'PLATFORM_CAP_EXCEEDED' when the service-wide daily DataForSEO limit is used up (the org's owners and admins are notified either way); call geogrid.preview first. Optional speed ('standard' or 'fast', default the org's default speed) picks the DataForSEO queue: fast is high priority, about 1 min, twice the price. Needs geogrid:manage.
configIdrequiredspeedoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_quickScans_create
Write, proposal: needs a Read & write token
Needs the geogrid:manage permission. Roles with it: owner, admin, manager.
Quick scan of any business (for example a prospect) that is not a managed location: one keyword over a grid around centerLat/centerLng, matched by its Google place id (placeId, required; business search is not available on this server, so the id is pasted). Creates a quick-scan configuration (kind 'quick_scan', no location, schedule manual) in workspaceId and queues its first run in the same step; uses the same budget, prices and own-key rules as trackers and fails with FORBIDDEN 'BUDGET_EXCEEDED' (nothing created) when the estimate does not fit (see geogrid.preview). Re-run with geogrid.run, read with geogrid.runs.list kind 'quick_scan' and geogrid.runs.get, remove with geogrid.configs.delete. Needs geogrid:manage (owner, admin, manager).
workspaceIdrequiredbusinessNamerequiredplaceIdrequiredkeywordrequiredspeedoptionalgridSizerequiredradiusMrequiredcenterLatrequiredcenterLngrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_runs_list
Read: works with any token
Needs the geogrid:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List geo-grid runs, newest first, each with average rank (not found counts as 21), top-3 share and found share. Use it as history: filter by configId to see one configuration over time. limit defaults to 50 (max 200). Runs from the relevance check carry isMapsRank=false. kind (default 'tracker') picks trackers or quick scans. costEstimateUsd, costChargedUsd and providerCostUsd are null unless the role has geogrid:cost. dataSource is fixture, sandbox or live: only live runs are real Google Maps data. Needs geogrid:read.
configIdoptionalworkspaceIdoptionalkindoptionallimitoptional
geogrid_runs_get
Read: works with any token
Needs the geogrid:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One geo-grid run with every point (row 0 is north, col 0 is west; rank null = not found in the top 20 or not collected yet) and its analytics: average rank (not found counts as 21), top-3 share, found share. Each point has pending (not collected yet); before the worker starts, points are the planned grid, all pending. progress counts collected points. If isMapsRank is false the numbers are a relevance check, NOT Google Maps rank, and must be presented as such. The run's cost fields are null unless the role has geogrid:cost. Needs geogrid:read.
runIdrequired
geogrid_competitors
Read: works with any token
Needs the geogrid:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Competitor table for a run: every business seen at the grid points with appearances, average rank among those appearances, best rank, address, rating and Google review count (address and review count are null for runs stored before they were collected), most frequent first. Give runId, or configId for that configuration's latest finished run. includeTarget=true adds the tracked business itself as the first row (isTarget). Relevance-check runs list place ids only (no business names). Needs geogrid:read.
runIdoptionalconfigIdoptionalincludeTargetoptional
geogrid_settings_get
Read: works with any token
Needs the geogrid:cost permission. Roles with it: owner, admin, manager.
The organization's geo-grid billing settings: monthly budget (USD), markup percent on the data-source price, this month's spend, and the available data sources with their per-task price and its source. Defaults apply until an owner or admin changes them. Needs geogrid:cost (owner, admin, manager; hidden from client roles).
geogrid_settings_update
Write, proposal: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Set the organization's monthly geo-grid budget (USD), markup percent and/or defaultSpeed ('standard' or 'fast'; used by scheduled runs and pre-selected on manual runs). Needs google:manage (owner, admin): the same org-level billing-style gate as Google connections, chosen over a new permission to keep the matrix small.
monthlyBudgetUsdoptionalmarkupPercentoptionaldefaultSpeedoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_byoKey_get
Read: works with any token
Needs the google:manage permission. Roles with it: owner, admin.
Whether this organization has its own DataForSEO API key (bring your own key) and the masked login. Never returns the password. With a key, geo-grid Maps-rank runs use it, are billed at cost with no markup, and do not count against the monthly resold-spend budget. Needs google:manage (owner, admin).
geogrid_byoKey_set
Write, own approval steps: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Store (or replace) the organization's DataForSEO API login and API password (from the API Access page of the DataForSEO dashboard; not the account password). The password is encrypted at rest and never returned or audited. Replacing the key clears the last-verified time; call geogrid.byoKey.verify afterwards. Needs google:manage (owner, admin).
loginrequiredpasswordrequireddryRunoptional- Preview only: returns a preview and changes nothing.
geogrid_byoKey_delete
Write, proposal: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Remove the organization's DataForSEO key. Later runs go back to our key with the markup and the monthly budget. Runs already requested with the customer key fail instead of using ours. Needs google:manage (owner, admin).
dryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_byoKey_verify
Write, proposal: needs a Read & write token
Needs the google:manage permission. Roles with it: owner, admin.
Check the stored DataForSEO key with the driver's credential check (a free DataForSEO user_data call when the server has a live rank source, otherwise an offline fixture). Returns ok or failed with a message and records the last-verified time on success. Needs google:manage (owner, admin).
dryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
geogrid_usage
Read: works with any token
Needs the geogrid:cost permission. Roles with it: owner, admin, manager.
Geo-grid usage and cost per UTC month for runs created from `from` to `to` (inclusive dates, YYYY-MM-DD, at most about 26 months). Per month: runs, points (tasks submitted), tasks (finished, billable), cost_at_dataforseo (tasks x DataForSEO's per-task price), charged (what we charged: BYO runs at cost with no markup, resold runs with the markup), split into byo and resold. BYO runs are not part of the monthly budget. Needs geogrid:cost (owner, admin, manager; hidden from client roles).
fromrequiredtorequired
performance tools
performance_summary
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Business Profile performance for a workspace (workspaceId) or specific locations (locationIds) over from..to (YYYY-MM-DD, inclusive): totals per metric and per KPI (impressions split Maps/Search, calls, website clicks, direction requests), each compared with the equal-length period just before it (delta and deltaPct, null when the earlier period was 0), and a daily series per KPI. Data is what the nightly snapshot captured; days Google omitted count as 0 and hasData is false when nothing was captured. Needs report:read.
workspaceIdoptionallocationIdsoptionalfromrequiredtorequired
performance_keywords
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Top Google search keywords (unique users who searched and saw the business) for a workspace or locations over the last `months` complete calendar months (default 3, ending at the previous month, or at endMonth YYYY-MM). Google hides small counts: such a month adds nothing to value and sets isLowerBound, with hiddenBelow the sum of thresholds (the real figure was below it). Needs report:read.
workspaceIdoptionallocationIdsoptionalmonthsoptionalendMonthoptionallimitoptional
performance_backfill
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Queue a re-fetch of a location's full Business Profile performance history (the last 18 months Google serves) and its monthly search keywords. Asynchronous: audits the request and queues a worker job in the same transaction. Existing stored days are overwritten with Google's current values; nothing is deleted. The location must be active and linked to Google. Needs report:manage.
locationIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
performance_byLocation
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Per-location calls, website clicks and direction requests for a workspace (workspaceId) or locations (locationIds) over from..to (YYYY-MM-DD, inclusive), each compared with the equal-length period just before, plus `actions` (the three added together), the location's status, needsRelink (Google was disconnected) and lastDataDate (newest stored day). Ordered by title. Needs report:read.
workspaceIdoptionallocationIdsoptionalfromrequiredtorequired
performance_activity
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Reviews and posts for a workspace (workspaceId) or locations (locationIds) over from..to (YYYY-MM-DD, inclusive, UTC): newReviews (created in the range), averageRating (of those, one decimal, null when none is rated), unreplied (of those, reviews that still need a reply, by the shared reply-stage rule) and postsPublished (distinct posts published in the range). Counts only, never review text. Needs review:read.
workspaceIdoptionallocationIdsoptionalfromrequiredtorequired
reports tools
reports_definitions_list
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List report definitions the caller can see (optionally one workspace): name, scope (whole workspace or chosen locations), period (last_month, last_30_days, custom), monthly email schedule, recipients and branding. Needs report:read.
workspaceIdoptional
reports_definitions_create
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Create a report definition for a workspace. scope 'workspace' covers every location in it (locationIds empty); scope 'locations' needs locationIds from that workspace. period: last_month, last_30_days, or custom (customFrom/customTo, YYYY-MM-DD). schedule 'monthly' emails recipients a 30-day link to last month's PDF on the 1st (needs at least one recipient). branding: agencyName and colour (#RRGGBB) shown on the PDF. Reports contain performance numbers and keywords only, never review text. scope 'group' needs groupId (a location group in that workspace; its members are read when each run is generated). language: en (default) or es, for the PDF's labels. comment: optional text for the reader, at most 500 characters, printed last; curly quotes and dashes are normalised and characters the PDF cannot print are refused. kind: performance (default) or reviews. A reviews report holds review counts, ratings, reply rate and time to reply by location, never review text or reviewer names; kind cannot be changed later. Needs report:manage.
workspaceIdrequiredkindoptionalnamerequiredscoperequiredlocationIdsrequiredgroupIdoptionallanguageoptionalcommentoptionalperiodrequiredcustomFromrequiredcustomTorequiredschedulerequiredrecipientsrequiredbrandingrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reports_definitions_update
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Change a report definition (send only the fields to change). The same rules as create apply to the result. Needs report:manage.
nameoptionalscopeoptionallocationIdsoptionalgroupIdoptionallanguageoptionalcommentoptionalperiodoptionalcustomFromoptionalcustomTooptionalscheduleoptionalrecipientsoptionalbrandingoptionalidrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reports_definitions_delete
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Delete a report definition together with its runs and share links (links stop working). Needs report:manage.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reports_generate
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Generate the PDF for a report definition now. Asynchronous: records a run for the definition's current period, audits it and queues a worker job in the same transaction; poll reports.runs.get until status is 'done', then use reports.download or reports.share. Needs report:manage.
definitionIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reports_runs_list
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List report runs (newest first), optionally for one definition. Metadata only (period, status, size); use reports.download for the PDF. requestedByName is the person who generated a manual run (null for scheduled runs). Needs report:read.
definitionIdoptionallimitoptional
reports_runs_get
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One report run's metadata plus its share links (id, expiry, revoked or not; never the token). requestedByName is the person who generated a manual run (null for scheduled runs). Needs report:read.
runIdrequired
reports_download
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Download a finished report as a PDF, base64-encoded (filename, contentType, sizeBytes, base64). Refuses PDFs over 1048576 bytes: use reports.share to get a link instead. Needs report:read.
runIdrequired
reports_share
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Create a public share link for a finished report: anyone with the URL can download the PDF without logging in until it expires (expiresInDays 1-30, default 7) or is revoked. The URL is returned ONCE and cannot be recovered; only its hash is stored. Every access is audited. Needs report:manage.
runIdrequiredexpiresInDaysoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reports_share_revoke
Write, proposal: needs a Read & write token
Needs the report:manage permission. Roles with it: owner, admin, manager.
Revoke a share link by its id (from reports.runs.get); the URL stops working immediately. Needs report:manage.
linkIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
profile tools
profile_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Read a location's editable Business Profile live from Google (the mock, today): title, description, categories (primary + additional ids), regularHours, specialHours, serviceItems, serviceArea, websiteUri, openingDate, phoneNumbers, storeCode, storefrontAddress, plus attributes (each `attributes/{id}` with its value type). Values are normalised: unset fields are null; hours periods are sorted. Calls Google, so it runs outside any database transaction. Also returns display: Google's category display names by id, (the store code and address are in profile.fields.storeCode and storefrontAddress). display.regionCode and display.languageCode are the locale to pass to profile.categories.* and profile.attributes.metadata.
locationIdrequired
profile_preview
Read: works with any token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Dry run of a profile edit across one or more locations of one workspace. Reads each location's current profile live from Google (outside any transaction), diffs it against `fields`, and returns per location { changes, updateMask, attributeMask, guardrail, noChange, current }. Only fields that differ are in the updateMask. `fields` sets whole values: title, description (max 750 characters, no links), categories { primaryCategory { name }, additionalCategories [{ name }] } (Google category ids such as categories/gcid:dentist), regularHours { periods [{ openDay MONDAY..SUNDAY, openTime {hours, minutes}, closeDay, closeTime }] } (24 hours open is 00:00 to 24:00), specialHours { specialHourPeriods [{ startDate {year,month,day}, endDate, openTime, closeTime, closed }] }, serviceItems, serviceArea, websiteUri, openingDate {year,month,day}, phoneNumbers { primaryPhone, additionalPhones }, storeCode (null clears) and storefrontAddress { regionCode, postalCode, administrativeArea, locality, addressLines (max 5) } (the whole address; changing it adds the warning PR.address-reverification, because Google may send the location back to verification), and attributes { 'attributes/has_wifi': { values: [true] } | null (null deletes) }. null clears websiteUri, regularHours, specialHours, serviceArea, openingDate. Guardrails (pack profile + U7) run on the values to be written. Writes nothing. To propose, pass the same `fields` (and `addServiceItems`) and each location's `current` as snapshots to profile.propose. `addServiceItems` appends services to each location's CURRENT list (an item with the same name and category is skipped, everything else is kept as it is); it cannot be combined with `fields.serviceItems`, which replaces the whole list. With addServiceItems, `fields` may be empty. `skipUnofferedServices: true` (used by Copy services) also sets aside, per location, free-form items whose category is not one of the location's, structured items whose service type none of the location's categories offers (or that could not be verified), and everything when the merged list would pass 300 items; each location's `serviceAdd` says which (`send`, `alreadyThere`, `skipped` with a reason, as indexes into addServiceItems). Google documents no category rule or item limit, so this is conservative: flag rather than send. An existing item with the same name and category keeps its own price and description. profile.propose takes the preview's `serviceAdd.send` as `serviceAddSend`. `addCategories` adds categories ([{ name }], Google ids such as categories/gcid:dentist) to each location's CURRENT additional categories: the primary and every category already there are kept, and one already there is skipped. It cannot be combined with `fields.categories`, which replaces both. A location without a primary category errors in the preview. With `addServiceItems` + `skipUnofferedServices`, each location's services are checked against its categories AFTER the edit (the additions, or `fields.categories` when that replaces them).
locationIdsrequiredfieldsrequiredaddServiceItemsoptionaladdCategoriesoptionalskipUnofferedServicesoptional
profile_propose
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Record a profile change set: ONE edit (`fields`) for 1-100 locations of one workspace, with the preview snapshot each diff is based on. Pass `snapshots` = the `current` of each location from profile.preview. Per location the diff and minimal updateMask are recomputed here; locations where nothing changes become no_change targets (at least one location must change). Guardrails run on every changing location: any block-severity violation sets status blocked (returned, not an error; propose again with corrected fields); otherwise the change set is pending_approval (warnings do not block). Nothing is sent to Google. The snapshot is the baseline for the conflict check: if Google's value of a changed field differs from it when applying, that location fails with error `conflict` and nothing is written there. Needs profile:edit; approval needs review:approve. `addServiceItems` appends services to each location's CURRENT list (an item with the same name and category is skipped, everything else is kept as it is); it cannot be combined with `fields.serviceItems`, which replaces the whole list. With addServiceItems, `fields` may be empty. `skipUnofferedServices: true` (used by Copy services) also sets aside, per location, free-form items whose category is not one of the location's, structured items whose service type none of the location's categories offers (or that could not be verified), and everything when the merged list would pass 300 items; each location's `serviceAdd` says which (`send`, `alreadyThere`, `skipped` with a reason, as indexes into addServiceItems). Google documents no category rule or item limit, so this is conservative: flag rather than send. An existing item with the same name and category keeps its own price and description. profile.propose takes the preview's `serviceAdd.send` as `serviceAddSend`. `addCategories` adds categories ([{ name }], Google ids such as categories/gcid:dentist) to each location's CURRENT additional categories: the primary and every category already there are kept, and one already there is skipped. It cannot be combined with `fields.categories`, which replaces both. A location without a primary category errors in the preview. With `addServiceItems` + `skipUnofferedServices`, each location's services are checked against its categories AFTER the edit (the additions, or `fields.categories` when that replaces them).
workspaceIdrequiredlocationIdsrequiredfieldsrequiredaddServiceItemsoptionaladdCategoriesoptionalskipUnofferedServicesoptionalserviceAddSendoptionalsnapshotsrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_approve
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Approve a change set that is pending approval (pending_approval -> approved). Approving does not send anything to Google: call profile.apply. Client approvers can approve change sets in their own workspaces only.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_reject
Write, own approval steps: needs a Read & write token
Needs the review:approve permission. Roles with it: owner, admin, manager, client_approver.
Reject a change set that is pending approval, with a reason (pending_approval -> cancelled). The proposer edits the values and proposes again.
idrequiredreasonrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_apply
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Apply an approved change set: approved -> queued and one worker job per changing location (no_change locations are skipped). Asynchronous: nothing is sent to Google inside this call. Each job re-reads the location from Google; if a changed field no longer has the value the preview saw, that location fails with error `conflict` and nothing is written there (someone edited it on Google). Otherwise guardrails run again and the edit is written with a minimal updateMask through the per-location queue (Google allows 10 edits per minute per location; an 11th waits). The change set ends applied (all changing locations applied), partially_applied or failed. Poll profile.changeSets.get for per-location results.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_cancel
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Cancel a change set that has not been applied: draft, blocked, pending_approval or approved. Once applying has started (queued) it cannot be cancelled: CONFLICT.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_changeSets_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Profile change sets the caller can see, newest first. Filters: workspaceId, status, locationId (change sets that target it). limit 1-100 (default 50). Use status pending_approval for the approval queue. Each change set names its drafter (createdByName; createdSurface mcp means an agent drafted it for that person) and approver (approvedByName).
workspaceIdoptionalstatusoptionallocationIdoptionallimitoptional
profile_changeSets_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
One profile change set: desired values, status, guardrail result, what the caller may do next (can.*) and the per-location results (status, error reason code, the field changes and masks). Each change set names its drafter (createdByName; createdSurface mcp means an agent drafted it for that person) and approver (approvedByName).
idrequired
profile_categories_search
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Search Google's Business Profile categories by display name, for a region and language (pass display.regionCode and display.languageCode from profile.get). Returns up to 20 { name (the id to write, categories/gcid:...), displayName }. Fewer than 2 characters returns nothing without calling Google. Cached for a day per query. source "sample" means this server uses the simulated Google.
locationIdrequiredregionCoderequiredlanguageCoderequiredqueryrequired
profile_categories_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Google's details for up to 10 category ids (categories/gcid:...): displayName and serviceTypes (the structured services a location in that category can list; write them as serviceItems[].structuredServiceItem.serviceTypeId). Unknown ids are left out. Cached for a day per id.
locationIdrequiredregionCoderequiredlanguageCoderequirednamesrequired
profile_attributes_metadata
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The attributes Google offers for a primary category in a region and language: name (attributes/{id}, the key for profile.preview attributes), displayName, groupDisplayName, valueType (BOOL, ENUM, URL, REPEATED_ENUM), repeatable, and for enums the allowed values with display names. Deprecated attributes are left out. Social profile links, where Google offers them, are URL attributes such as attributes/url_facebook. Cached for a day per category.
locationIdrequiredregionCoderequiredlanguageCoderequiredcategoryNamerequired
profile_changes_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Profile changes found by the change watch, newest first: nightly snapshot diffs (someone edited the profile outside OpenGMB) and Google-suggested edits (GOOGLE_UPDATE push; googleSuggested true, `before` is the merchant value, `after` what Google shows). Without locationId it covers every location in the caller's scope (the org-wide alerts inbox). Filters: workspaceId, locationId, groupId, status (open, accepted, reverted, dismissed), googleSuggested, fields (profile field names such as regularHours or websiteUri; a change matches when it touches any of them). total counts every match, past the limit. Each change has fieldPaths, before/after values of those fields, status and can.{accept,revert,dismiss}. limit 1-200 (default 100). Each change also names who resolved it (resolvedByName) and, for a revert, where its change set was drafted (revertChangeSetSurface: ui, or mcp for an agent).
workspaceIdoptionallocationIdoptionalgroupIdoptionalstatusoptionalgoogleSuggestedoptionalfieldsoptionallimitoptional
profile_changes_accept
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Accept an open profile change: record that the new value is fine (open -> accepted). Nothing is written to Google. For a Google-suggested change this means keeping Google's value; note that Google keeps showing its own value as a difference from the merchant's profile until the profile is patched, which this build does not do on accept.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_changes_revert
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Revert a profile change found by the nightly snapshot: creates a profile change set that restores the previous values of the changed fields (profile.changeSets.get shows it) and marks the change reverted. Nothing is written to Google here: the change set waits for approval (review:approve) and is applied by profile.apply with the usual conflict check, so if the field changed again on Google since the change was detected, that location fails with `conflict` and nothing is written. Not available for Google-suggested changes (the merchant value already equals the restored value): accept or dismiss those. A reverted change whose change set was cancelled, blocked or failed can be reverted again.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
profile_changes_dismiss
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Dismiss an open profile change without acting on it (open -> dismissed). Nothing is written to Google.
idrequireddryRunoptional- Preview only: returns a preview and changes nothing.
invitations tools
invitations_create
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Invite someone by email (owner, admin, manager). role is client_approver or client_viewer (needs workspaceId: they see and act on that workspace only) or manager (organization-wide, owner and admin only; no workspaceId). The invitee gets an email with a link to /invite/<token>; the link is a deep link only: they must still sign up or sign in and complete TOTP before the invitation is applied, and their account email must match. The invitation lasts 7 days. The link (inviteUrl) is returned ONLY when no email provider is configured (RESEND_API_KEY and EMAIL_FROM), so a developer can test; otherwise inviteUrl is null and the token exists nowhere but the email. An account holds one client role: inviting someone who already has a different client role, another organization, or a pending invite is CONFLICT.
emailrequiredrolerequiredworkspaceIdoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
invitations_list
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Invitations of the caller's organization, newest first (owner, admin, manager). Optional status filter: pending, accepted, revoked, expired. limit 1-200 (default 100). The token is never returned.
statusoptionallimitoptional
invitations_revoke
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Revoke a pending invitation (owner, admin, manager; a manager cannot revoke a manager invitation). The link stops working at once. An invitation that was accepted, already revoked or expired is CONFLICT.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
integrations tools
integrations_clear
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Platform administrators only. Remove the in-app value of one integration key. A value set by the server environment is unaffected. The audit row names the key only.
keyrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
integrations_list
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Platform administrators only (everyone else gets FORBIDDEN). Each optional integration key (Google Maps browser key, Resend email, Pub/Sub push, browser push VAPID, Anthropic) with where its value comes from: env (set by the server environment, read-only here), app (entered in the app), unreadable (stored value cannot be decrypted, enter it again) or missing. Shows at most the last four characters of an in-app value; never the value.
integrations_set
Write, own approval steps: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Platform administrators only. Store (or replace) one optional integration key, encrypted at rest. Refused with CONFLICT while the server environment sets that key (the environment wins). The value is never returned or audited; the audit row names the key only. Boot secrets such as ENCRYPTION_KEY are not accepted.
keyrequiredvaluerequireddryRunoptional- Preview only: returns a preview and changes nothing.
integrations_testDataForSeo
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Platform administrators only. Checks the DataForSEO login and password the server has (environment or entered in the app) with a free user_data call and returns the account balance in USD. Never returns the credentials. Returns ok false with a message when the keys are missing or refused.
domains tools
domains_get
Read: works with any token
Needs the workspace:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The caller's organization's custom address: host (null when none), senderEmail, senderVerified (the sender is used for client emails only once a platform administrator marked it verified in Resend) and dnsTarget, the hostname a CNAME record must point to. Any member can read it; it never returns another organization's row.
domains_list
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Every organization with its custom address and organization name (platform administrators only: accounts on PLATFORM_ADMIN_EMAILS with a verified email; everyone else gets FORBIDDEN). An organization without an address has host null, so an address can be set for it with domains.set.
domains_set
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Set or remove an organization's custom address (platform administrators only; everyone else gets FORBIDDEN). host is a bare hostname such as portal.agency.com (no scheme, path, port or wildcard), or null to remove the row. A host already used by another organization, or the main host, is refused (CONFLICT / INVALID_INPUT). senderEmail is the agency's own From address; senderVerified true means Resend shows its domain as Verified, and only then is it used (it needs a senderEmail). The change is audited. The hostname also has to be added to the web app's domain list in Coolify before it serves traffic.
orgIdrequiredhostrequiredsenderEmailoptionalsenderVerifiedoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
orgInvites tools
orgInvites_create
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Invite someone to start a NEW organization (platform administrators only: accounts on PLATFORM_ADMIN_EMAILS with a verified email; everyone else gets FORBIDDEN). The invitee gets an email link to /invite/<token>; signing up (also while sign-up is invite only) or signing in from it creates the organization with them as its owner. Their account email must match, they must have no organization yet, and the link lasts 7 days and works once. organizationName is optional (default: the invitee's name). The link (inviteUrl) is returned ONLY when no email provider is configured; otherwise inviteUrl is null. A pending organization invite for the same email, or an account that already belongs to an organization, is CONFLICT.
emailrequiredorganizationNameoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
orgInvites_list
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Organization invites, newest first (platform administrators only; everyone else gets FORBIDDEN). They belong to no organization, so every platform administrator sees all of them. Optional status filter: pending, accepted, revoked, expired. limit 1-200 (default 100). The token is never returned.
statusoptionallimitoptional
orgInvites_revoke
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Revoke a pending organization invite (platform administrators only). The link stops working at once. An invite that was accepted, already revoked or expired is CONFLICT; a team invitation id is NOT_FOUND here.
idrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
members tools
members_list
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Members of the caller's organization with their role (owner, admin, manager). Organization-wide members have workspaceId null; client members belong to one workspace. Pass workspaceId to get that workspace's clients plus the organization-wide members.
workspaceIdoptional
members_remove
Write, proposal: needs a Read & write token
Needs the member:invite permission. Roles with it: owner, admin, manager.
Remove a membership (owner, admin, manager). An owner can remove anyone; an admin anyone but an owner; a manager only client members. The last owner of an organization cannot be removed (CONFLICT). The person's account stays; they lose access to this organization at once: their sessions end and their API tokens for it are revoked.
membershipIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
members_resetTwoFactor
Write, proposal: needs a Read & write token
Needs the member:reset_two_factor permission. Roles with it: owner.
Reset a member's two-factor authentication (owner only; never your own; not available to API tokens). Deletes their authenticator secret and backup codes and signs them out everywhere. Until they set up a new authenticator app at their next sign-in, their password (or Google) alone signs them in, and they cannot use OpenGMB until they do. CONFLICT when the member has not set up two-factor or also belongs to another organization.
membershipIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
portal tools
portal_overview
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The client portal's data in one call, for any role that can read reviews: pending (review replies AND posts waiting for approval, oldest submission first, across the caller's workspaces or one workspaceId) and recentlyPublished (replies and post sends published most recently, newest first). Each pending item carries can.approve / can.reject from the caller's role, so a client_viewer sees the queue read-only; act with reviewReplies.approve / reviewReplies.reject / posts.approve / posts.reject. Only active locations are included. Published replies carry autoApprovedMinStars (the star rule that approved them; null when a person approved).
workspaceIdoptionalrecentLimitoptional
portal_results
Read: works with any token
Needs the report:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The client portal's results in one call, over the caller's active locations (or one workspaceId): calls and direction requests from the nightly performance snapshot, and new reviews with their average star rating, for the 30 complete days ending yesterday (UTC) compared with the 30 days before (deltaPct is null when the earlier period was 0; hasData is false when no snapshot exists for the range); plus ratingTrend, the average star rating per calendar month for the last 6 months including the current one (average null when the month has no rated review). Needs report:read.
workspaceIdoptional
approvals tools
approvals_queue
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Everything waiting for a person to approve, across the caller's workspaces or one workspaceId, oldest submission first: review replies, posts, profile change sets and edits of published posts with status pending_approval. Each item has a one-line title, the text, where it is for, who drafted it (provenance.createdSurface is mcp for an agent draft), a guardrail summary and can.approve / can.reject from the caller's role; act with reviewReplies.approve / reject, posts.approve / reject, profile.approve / reject, posts.approveEdit / rejectEdit (a postedit item's id is the edit id; the post stays published while its edit waits). An edit is included only while a live Google post it would patch is at an active location. counts are the totals before limit; truncated is true when limit cut the list. Replies at inactive locations are not included. A change set is included only while at least one location it changes is active, and only active locations are named.
workspaceIdoptionallocationIdsoptionalgroupIdoptionallimitoptional
approvals_counts
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
How many items wait for approval (replies, posts, profile change sets, post edits), across the caller's workspaces or one workspaceId. Count queries only: cheap enough to call on every page, unlike approvals.queue. Same scope and the same numbers as approvals.queue counts.
workspaceIdoptionallocationIdsoptionalgroupIdoptional
attention tools
attention_counts
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
How many things need a person, across the caller's workspaces or one workspaceId, in disjoint buckets: approvals (replies, posts, profile change sets pending approval; the same numbers as approvals.counts), reviews to answer (negative = rated 1 to negativeMaxStars, other = higher or unrated; the workspace reply policy applies, and a review whose reply is already pending approval, approved or failed is not counted; the rule is the shared reply stage), waitingToPublish (reviews whose approved reply is not yet on Google; reported apart, not in total), open profile changes, the caller's own pending agent proposals (not narrowed by workspaceId), and failed publishes (replies, posts, change sets failed or partially applied). total is the sum. Count queries only: cheap enough for every page.
workspaceIdoptional
attention_queue
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Everything that needs a person, as one list sorted by urgency (failed publishes, negative reviews, approvals, your agent proposals, open profile changes, other reviews to answer; newest first within each), across the caller's workspaces or one workspaceId. Same buckets and counts as attention.counts; truncated is true when limit cut the list. Also returns what the Home page needs: activeLocations in the requested scope (Home shows its owner layout up to 3, the agency layout above), org-wide setup facts, locations that lost their Google connection (relink), per-client rows with an attention count and a 6-month rating trend, cards for up to 3 active locations with reviews, open changes, last post and 30-day calls and directions, the workspaces with an auto-approve rule, and when reviews last synced (UTC). Act on items with the action named by subject (reviewReplies.*, posts.*, profile.*, profile.changes.*, mcp.proposals.*).
workspaceIdoptionallimitoptional
onboarding tools
onboarding_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Whether the first-run checklist facts stored on the organization are set: healthReportSeen (someone opened a location's health report) and dismissed (an owner or admin hid the checklist).
onboarding_update
Write, own approval steps: needs a Read & write token
Needs the location:manage permission. Roles with it: owner, admin, manager.
Keep the first-run checklist on Home honest. healthReportSeen true records that someone opened a location's health report (it stays on). dismissed true hides the checklist for the whole organization, false brings it back; dismissing needs google:manage (owner, admin). Pass only the fields to change. Writes nothing to Google.
healthReportSeenoptionaldismissedoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
branding tools
branding_get
Read: works with any token
Needs the workspace:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The caller's organization branding: agencyName (falls back to the organization name), logoUrl (https), primaryColor and accentColor (#rrggbb). Any member can read it; the app, the client portal and emails use it.
branding_update
Write, proposal: needs a Read & write token
Needs the branding:manage permission. Roles with it: owner, admin.
Set the organization's branding (owner, admin). Every field is optional and null clears it: agencyName (1-100 chars), logoUrl (https URL only; a logo file uploaded in the web app wins over it in the app and portal, see branding.logos), primaryColor and accentColor (#rrggbb). Fields you leave out are unchanged.
agencyNameoptionallogoUrloptionalprimaryColoroptionalaccentColoroptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
branding_logos
Read: works with any token
Needs the workspace:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
The uploaded logo files the caller may see: orgLogoFileId (the agency logo, or null) and workspaceLogos (one per client in the caller's scope that has one). A file is shown at /api/files/<fileId>. An uploaded logo wins over the logoUrl link. Logos are uploaded in the web app (Settings, Branding); agents cannot upload.
branding_removeLogo
Write, proposal: needs a Read & write token
Needs the branding:manage permission. Roles with it: owner, admin.
Delete an uploaded logo file (owner, admin): the agency logo, or one client's when workspaceId is given. Frees its storage. Returns removed false when there was none.
workspaceIdoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
storage tools
storage_usage
Read: works with any token
Needs the branding:manage permission. Roles with it: owner, admin.
How much of the organization's file storage is used (owner, admin): usedBytes, limitBytes (the per-organization allowance, 50 MB unless the server sets STORAGE_QUOTA_MB) and a breakdown by store: storedFiles (logos), postImages (the post image library), mediaUploads (photo uploads not yet sent to Google) and reportPdfs. An upload that would pass the limit is refused.
media tools
media_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List a location's photos live from Google (the mock, today) with their category (COVER, PROFILE = the logo, EXTERIOR, INTERIOR, PRODUCT, AT_WORK, FOOD_AND_DRINK, MENU, COMMON_AREA, ROOMS, TEAMS, ADDITIONAL), plus the most recent photo operations queued from here (media.add / media.delete are asynchronous: status pending, applied or failed with a reason code). Calls Google, so it runs outside any database transaction. Photo requirements: JPG or PNG, 10 KB to 5 MB, at least 250px on the short edge, 720px recommended (https://support.google.com/business/answer/6103862).
locationIdrequired
media_add
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Add a photo to a location from a public https image URL (JPG or PNG; to send the file itself use media.upload) in a category: COVER (the cover photo, one per location), PROFILE (the logo, one per location; LOGO is a deprecated alias and is not accepted), EXTERIOR, INTERIOR, PRODUCT, AT_WORK, FOOD_AND_DRINK, MENU, COMMON_AREA, ROOMS, TEAMS or ADDITIONAL. Setting the cover or logo is simply adding with category COVER or PROFILE; Google replaces the previous one. Asynchronous: records the operation and queues a worker job (returns status pending); nothing is sent to Google inside this call and the URL is never fetched by OpenGMB. Poll media.list for the outcome. Needs profile:edit.
locationIdrequiredsourceUrlrequiredcategoryrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
media_upload
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Upload a photo FILE to a location (base64 content, JPG or PNG, at most 5 MB, so at most 7000000 base64 characters) in a category: COVER, PROFILE (the logo), EXTERIOR, INTERIOR, PRODUCT, AT_WORK, FOOD_AND_DRINK, MENU, COMMON_AREA, ROOMS, TEAMS or ADDITIONAL. The format is detected from the bytes (GIF, HEIC and WebP are rejected) and the size and pixels are checked against Google's rules (10 KB to 5 MB and 250px on the short edge, except COVER and PROFILE). Asynchronous like media.add: records the operation and queues a worker job (status pending); the bytes are kept only until Google accepts them, then deleted. Poll media.list. Needs profile:edit. Over MCP this is a two-phase write: the proposal preview shows file facts only, never the image.
locationIdrequiredcategoryrequiredfilenamerequiredcontentBase64requireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
media_uploadMany
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Upload ONE photo FILE (base64, same rules as media.upload) to several locations at once, now or at a later time. Each location gets its own operation (its own result): a location you cannot edit, or that is not linked to Google, is reported in its own result (error code) and does not stop the others. scheduledFor (optional, ISO datetime with offset = an instant, not in the past, at most 90 days ahead; the web app converts the location's local wall time) holds the photo until then: its operations have status scheduled, and a worker sweeps every minute and sends the due ones (so a send can be up to about a minute late). Without scheduledFor the operations are queued at once (status pending). The photo is kept only until Google accepts it. Poll media.batch with the returned batchId for per-location results. Needs profile:edit on each location. Over MCP this is a two-phase write.
locationIdsrequiredcategoryrequiredfilenamerequiredcontentBase64requiredscheduledForoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
media_batch
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Per-location results of one photo sent to several locations (the batchId media.uploadMany returned) of one workspace (client): for each location its operation status (scheduled, pending, applied or failed with a reason code such as google_http_<n>), the scheduled time and the Google media name once applied. Only locations you can read are listed.
workspaceIdrequiredbatchIdrequired
media_cancelScheduled
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Cancel a photo that is still waiting for its scheduled time (the operation id from media.list or media.batch, status scheduled) in one workspace (client). Moves the operation to the terminal status cancelled and deletes the staged photo bytes. Only works while the status is scheduled: if the minute sweep already took it, nothing changes and cancelled is false (already sent or being sent). Needs profile:edit.
workspaceIdrequiredopIdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
media_delete
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Delete a photo from a location (`mediaName` as returned by media.list, accounts/{a}/locations/{l}/media/{id}). Asynchronous: records the operation and queues a worker job (status pending); a photo Google no longer has counts as deleted. Poll media.list. Needs profile:edit.
locationIdrequiredmediaNamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
media_customer_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List photos contributed by customers at a location, live from Google (outside any transaction). Each item carries the contributor attribution, which Google requires to be shown unaltered, and the takedown URL to report an inappropriate photo. The nightly job notifies (media.customer_photo) once per new photo.
locationIdrequired
verification tools
verification_state
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
A location's verification state live from Google (outside any transaction): Voice of Merchant (hasVoiceOfMerchant = in good standing and in control of the listing; hasBusinessAuthority = ownership), which action Google wants next (standing: good_standing, wait_for_review, verify, comply_with_guidelines = fix guideline problems, resolve_ownership_conflict = duplicate of a location in good standing, unknown) with the recommendation reason, and the location's verification attempts (method, PENDING / COMPLETED / FAILED). Read only: OpenGMB starts no verification and submits no appeal; those are manual.
locationIdrequired
suspension tools
suspension_cases_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Suspension / reinstatement cases the caller can see, newest first, with the evidence checklist (business registration, licence, tax certificate, utility bill, storefront / signage / interior photos, video walkthrough, website match ...), dates (opened, appeal submitted, outcome) and status (open, appealed, reinstated, closed_lost). Filters: locationId, workspaceId, status. This is a record-keeping tool for a manual process: nothing is sent to Google.
locationIdoptionalworkspaceIdoptionalstatusoptional
suspension_cases_create
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Open a suspension case for a location: the reason (what Google said or what you see), when it started (openedAt, default now) and a fresh evidence checklist. Records only; nothing is sent to Google. Needs profile:edit.
locationIdrequiredreasonrequiredopenedAtoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
suspension_cases_update
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Update a suspension case. checklist: [{ key, done?, note? }] toggles items and sets notes (keys as in suspension.cases.list; unknown keys are rejected). status: open -> appealed (sets appealSubmittedAt, default now) -> reinstated or closed_lost (sets outcomeAt, default now); open may also go straight to reinstated or closed_lost. Google allows one appeal, so there is no second appeal. appealSubmittedAt can be corrected while appealed; outcomeAt and outcomeNotes can be set with the outcome and outcomeNotes edited after it; a finished case is otherwise read only. reason can be reworded while the case is open or appealed. Records only; nothing is sent to Google. Needs profile:edit.
idrequiredstatusoptionalreasonoptionalappealSubmittedAtoptionaloutcomeAtoptionaloutcomeNotesoptionalchecklistoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
placeActions tools
placeActions_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List a location's place action links (booking / ordering buttons on the listing) live from Google (outside any transaction), plus the most recent link operations queued from here (status pending, applied, failed with a reason code). Types: APPOINTMENT, ONLINE_APPOINTMENT, DINING_RESERVATION, FOOD_ORDERING, FOOD_DELIVERY, FOOD_TAKEOUT, SHOP_ONLINE. Only one link per (uri, type) and one preferred link per type exist at a location. Links with isEditable false (managed by an aggregator) cannot be changed.
locationIdrequired
placeActions_create
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Add a place action link (a booking or ordering URL) to a location. placeActionType: APPOINTMENT, ONLINE_APPOINTMENT, DINING_RESERVATION, FOOD_ORDERING, FOOD_DELIVERY, FOOD_TAKEOUT, SHOP_ONLINE. uri must be https. isPreferred marks it the preferred link for its type (any previous preferred link of that type loses it). Asynchronous: records the operation and queues a worker job (status pending); nothing is sent to Google inside this call. A link with the same uri and type that already exists fails with google_http_409. Needs profile:edit.
locationIdrequiredplaceActionTyperequiredurirequiredisPreferredoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
placeActions_update
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Change a place action link (`name` as returned by placeActions.list): any of uri (https), placeActionType, isPreferred; only the fields you pass are written (Google's updateMask is exactly those). Links with isEditable false fail at Google. Asynchronous: records the operation and queues a worker job (status pending). Needs profile:edit.
locationIdrequirednamerequiredurioptionalplaceActionTypeoptionalisPreferredoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
placeActions_delete
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Delete a place action link (`name` as returned by placeActions.list). Asynchronous: records the operation and queues a worker job (status pending); a link Google no longer has counts as deleted. Needs profile:edit.
locationIdrequirednamerequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
foodMenus tools
foodMenus_get
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Read a location's food menus live from Google (v4 getFoodMenus), outside any transaction, plus the most recent food menu saves queued from here (status pending, applied, failed with a reason code). menus is the list Google returns: each menu has labels, sections (labels, items) and cuisines; each item has labels, attributes (price, spiciness, allergen, dietaryRestriction, ...) and optional options. Only restaurants and similar locations have a food menu; supported is false (menus empty) when Google says the location cannot have a food menu, such as a clinic; call this only when a menu is wanted, since it spends a Google call.
locationIdrequired
foodMenus_update
Write, proposal: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Replace a location's whole food menu. Pass the complete list, starting from foodMenus.get: anything left out is removed at Google, and fields this tool does not edit (nutritionFacts, ingredients, cuisines ...) must be passed back unchanged. Each menu needs labels (displayName up to 140 characters, description up to 1000) and at least one section; each section labels and at least one item; each item labels and attributes.price {currencyCode, units, nanos}. Asynchronous: records the operation and queues a worker job (status pending); nothing is sent to Google inside this call, and nothing at all while Google writes are off. Needs profile:edit.
locationIdrequiredmenusrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
locationManagers tools
locationManagers_list
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Who manages a location on Google, read live (Account Management API locations.admins.list, outside any transaction). Each manager has a display name (an invited person who has not accepted yet shows the invited email), a role (PRIMARY_OWNER, OWNER, MANAGER, SITE_MANAGER; anything else is returned as OTHER) and pendingInvitation. Read only: OpenGMB does not invite, change or remove managers. Spends a Google call, so call it only when the list is wanted. Whether Google includes managers inherited from the account is not documented.
locationIdrequired
mcp tools
mcp_proposals_list
Read: works with any token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
List your own write proposals, newest first, with status (pending, applied, expired, cancelled, failed), expiry, the preview that was shown and the name of the token that made each. Over MCP: this token's proposals. In the web app: every token of the signed-in person. status filters before limit; expired includes pending proposals past their expiry. A failed proposal's error reads CODE: message.
statusoptionallimitoptional
mcp_proposals_apply
Write, own approval steps: needs a Read & write token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Apply a proposal returned by a write tool (phase 2 of propose -> check -> approve -> publish). Single use: it re-checks that the proposal is still pending and unexpired, was created by this API token and user (or, in the web app, that the signed-in person owns the token that created it; then the token must not be revoked and its read-only or client limits still apply), that its stored input is intact, that you are still authorized, and that the policy findings still do not block it; then it runs the write exactly as if you had called the tool, audit rows included. A second apply is CONFLICT. Returns the write's own result.
proposalIdrequireddryRunoptional- Preview only: returns a preview and changes nothing.
mcp_proposals_cancel
Write, own approval steps: needs a Read & write token
Needs the api_token:manage_own permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Cancel a pending proposal so it can no longer be applied. Only the API token that created it, or its owner signed in to the web app, can cancel it.
proposalIdrequireddryRunoptional- Preview only: returns a preview and changes nothing.
system tools
system_status
Read: works with any token
Needs the location:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Scheduled background jobs on this server (schedule in UTC, last run, result ok/failed/running/never, next run, late when two scheduled runs in a row were missed; error text for owners and admins only) and, for the locations you can see (sorted by name, up to 500), when reviews were last synced, the newest sync attempt and its reason code, the last performance snapshot date and when a profile change was last found. Never calls Google.
monitoring tools
monitoring_overview
Read: works with any token
Needs the member:invite permission. Roles with it: owner, admin, manager.
System health for the whole server (platform administrators only; everyone else gets FORBIDDEN): the worker's last heartbeat and whether it is stale, how alerts are delivered (email to ALERT_EMAIL, or only written to the log), the most recent distinct server errors with how often each was seen (messages are stripped of secrets and personal data), and Google Business API calls per day and method against the 300 requests per minute limit. Read-only, never calls Google.
search tools
search_everything
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Search locations (name, title, address), review text (and the reviewer's name unless anonymous) and post text in one call, for the ⌘K box. q is matched literally, case-insensitively. Reviews and posts are only searched from 3 characters (locations from 1), so a short q returns locations only. Returns at most limitPerKind (1-10, default 5) of each kind, newest first for reviews and posts. Scope with workspaceId, groupId or locationIds, the same as reviews.list; client roles only see their own workspaces. Reviews are active locations only. Internal notes and assignments are never searched or returned.
qrequiredworkspaceIdoptionalgroupIdoptionallocationIdsoptionallimitPerKindoptional
ai tools
ai_draftText
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Draft text with AI for a client. purpose 'reply' (a reply to a review: sourceText is the review text; optional rating and reviewerName) or 'post' (a Google post: sourceText is the topic). The draft uses the client's brand voice (tone, banned words, sign-off, language), is metered (tokens, model, cost), and then runs through the same guardrails as replies and posts for the client's profile. status 'ok' returns the draft (warningRuleIds lists non-blocking findings); status 'blocked' returns blockedRuleIds and NO text. The call is refused before it is made when it would exceed the platform's or the client's monthly AI limit, and fails with NOT_CONFIGURED when this server has no AI key. A draft is only a proposal: it still goes through approval. Needs review:draft (owner, admin, manager).
workspaceIdrequiredpurposerequiredsourceTextrequiredratingoptionalreviewerNameoptionallocationIdoptionallanguageoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftReply
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Draft a reply to one review with AI. Reads the review itself (text, star rating, reviewer first name only, location, the client's brand voice and a few of its reply templates as style examples) and writes in the review's language unless the client's brand voice sets one (language is a hint you may pass). A 1-2 star review gets an apology and an offer to take it offline, with no admission of fault. The draft is metered, em dashes are replaced, and it runs through the same guardrails as a typed reply for this location (including the duplicate check against its recent replies). status 'ok' returns the draft text (warningRuleIds lists non-blocking findings, for example wording the writing style bans); status 'blocked' returns blockedRuleIds and NO text. Refused with AI_BUDGET_EXCEEDED over the monthly cap, NOT_CONFIGURED when this server has no AI key. Nothing is saved: put the text in reviewReplies.createDraft, then reviewReplies.submit. Needs review:draft (owner, admin, manager).
reviewIdrequiredlanguageoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftReplies
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Draft replies with AI for up to 20 reviews and put each into the approval queue. One AI call per review, one after another. For each review: drafted (saved and submitted; replyStatus pending_approval, or approved if the client's star rule approves it), blocked (a guardrail blocked the draft; blockedRuleIds; nothing saved), refused (over the monthly cap: the run stops there and the rest are not_attempted), skipped (the review already has a reply or a draft, or is not found or not allowed), failed (the AI call failed). Warnings (for example banned wording) do not stop a draft: they are stored on it and a person sees them in approval. If the client's star rule would auto-approve the draft, a draft with warnings stays a draft instead (replyStatus draft) until a person reads it. Each draft goes through the same metering, guardrails and audit as ai.draftReply. NOT_CONFIGURED when this server has no AI key. Needs review:draft (owner, admin, manager).
reviewIdsrequireddryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftBusinessDescription
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Draft the business description for a location with AI. At most 750 characters (a longer answer is retried once, then cut at a sentence end), plain text, no links, in the client's brand voice and the writing style. The location's top Google search keywords from the stored Performance data are offered to the model as context; keywordsIncluded says which of them the draft happens to use (a hint, never forced). Optional facts the caller already has: categories, services and currentDescription (to improve it). status 'ok' returns the draft; status 'blocked' returns blockedRuleIds and NO text. The draft is only returned: nothing is saved, so it still goes through profile.preview, profile.propose and approval. Metered and capped like ai.draftText; the text sent to the model is never logged. Needs profile:edit and review:draft (owner, admin, manager).
locationIdrequiredcategoriesoptionalservicesoptionalcurrentDescriptionoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftServiceDescription
Write, own approval steps: needs a Read & write token
Needs the profile:edit permission. Roles with it: owner, admin, manager.
Draft the description of one service for a location with AI. At most 1000 characters (a longer answer is retried once, then cut at a sentence end), plain text, no links, in the client's brand voice and the writing style. serviceName is required; categoryName and currentDescription are optional context. status 'ok' returns the draft; status 'blocked' returns blockedRuleIds and NO text. The draft is only returned: nothing is saved, so it still goes through profile.preview, profile.propose and approval. Metered and capped like ai.draftText; the text sent to the model is never logged. Needs profile:edit and review:draft (owner, admin, manager).
locationIdrequiredserviceNamerequiredcategoryNameoptionalcurrentDescriptionoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_postIdeas
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Suggest 5 short Google post ideas for one location with AI, drawn from its services, a general theme of its recent positive reviews (never a quote or a reviewer's name; none at all for healthcare clients) and the occasions coming up in the next 60 days for the client's market (US, AU or IN, from the client's time zone). One AI call, metered and audited like ai.draftText. status 'ok' returns ideas; status 'blocked' returns blockedRuleIds and no ideas. Pick one, then call ai.draftPost with it. Refused with AI_BUDGET_EXCEEDED over the monthly cap, NOT_CONFIGURED when this server has no AI key. Nothing is saved. Needs review:draft (owner, admin, manager).
workspaceIdrequiredlocationIdrequiredlanguageoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftPost
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Write one Standard Google post for one location with AI, ready to drop into the composer. idea (optional, up to 300 characters) is one of the ai.postIdeas lines; without it the AI picks from the location's services, a general theme of its recent positive reviews and the next 60 days of occasions. Aims at about 600 characters (the post limit is 1500). Metered, em dashes removed, and run through the post guardrails for that location. status 'ok' returns the text (warningRuleIds lists non-blocking findings such as banned wording); status 'blocked' returns blockedRuleIds and NO text. Nothing is saved: put the text in posts.createDraft, then posts.submit. Needs review:draft (owner, admin, manager).
workspaceIdrequiredlocationIdrequiredideaoptionallanguageoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
ai_draftPostVariants
Write, own approval steps: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Write a different Standard post for each of up to 20 locations of one client with AI and put each into the approval queue as its own post (one location per post). One AI call per location, one after another, each committed on its own: a failure on one location never undoes the others. Each text names the location or its city and opens differently from the posts already written in the run. idea is optional (see ai.draftPost). For each location: drafted (saved and submitted; postStatus pending_approval, with any warnings stored on the post for the approver to read), blocked (a guardrail blocked the text; nothing saved), refused (over the monthly cap: the run stops there and the rest are not_attempted), skipped (not an active location of this client), failed (the AI call or the save failed). Posts always need a person to approve them; nothing is scheduled or sent. Same metering, guardrails and audit as ai.draftPost. NOT_CONFIGURED when this server has no AI key. Needs review:draft (owner, admin, manager).
workspaceIdrequiredlocationIdsrequiredideaoptionallanguageoptionaldryRunoptional- Preview only: returns a preview and changes nothing.
aiVoice tools
aiVoice_get
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
A client's AI brand voice: tone, bannedWords, signOff and language (empty language = the language of the source text). A client that was never set up returns empty values. Needs review:read.
workspaceIdrequired
aiVoice_update
Write, proposal: needs a Read & write token
Needs the review:draft permission. Roles with it: owner, admin, manager.
Set a client's AI brand voice; only the fields you pass change. tone: up to 200 characters (for example 'warm, plain, no jargon'). bannedWords: up to 50 words or phrases the drafts must not use. signOff: up to 200 characters, added at the end of every draft. language: up to 40 characters, a language name or code; empty means the language of the source text. These feed the AI prompt; the guardrails still check every output. Needs review:draft (owner, admin, manager).
workspaceIdrequiredtoneoptionalbannedWordsoptionalsignOffoptionallanguageoptionaldryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
aiUsage tools
aiUsage_setClientCap
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Set (or clear with null) one client's monthly AI spend cap in USD. A draft that would take the client over it is refused before the model is called. The platform-wide cap (AI_MONTHLY_BUDGET_USD) applies on top. The month is the UTC calendar month. Needs review:configure (owner, admin).
workspaceIdrequiredmonthlyCapUsdrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
aiUsage_get
Read: works with any token
Needs the review:configure permission. Roles with it: owner, admin.
This month's (UTC) AI spend per client the caller can see, with each client's cap (null = none), and whether AI is set up on this server. platform (spend and cap across all organizations) is returned only to platform admins, otherwise null. Needs review:configure (owner, admin).
reviewTopics tools
reviewTopics_setAuto
Write, proposal: needs a Read & write token
Needs the review:configure permission. Roles with it: owner, admin.
Turn the daily automatic classification of a client's new reviews by topic and sentiment on or off. Off by default, because every classification uses the client's AI allowance. Needs review:configure (owner, admin).
workspaceIdrequiredenabledrequireddryRunoptional- Ignored: this tool always stores a proposal, which changes nothing until it is applied.
reviewTopics_status
Read: works with any token
Needs the review:read permission. Roles with it: owner, admin, manager, client_approver, client_viewer.
Where a client's review classification stands: whether the daily automatic classification is on (autoClassify), whether AI is set up on this server (aiOn), how many reviews are classified (classified), could not be classified (unclassified) and still wait (pending: with text and no current classification, including unclassified ones a manual run would retry). Counts only. Needs review:read.
workspaceIdrequired