The information about a physical business is scattered — website, Facebook page, LINE account, Google Business Profile, directory profiles. Without a single source of truth, what AI sees is always a collage of contradictions.
For physical businesses, Google Business Profile (GBP) is the most authoritative entity-identity node. Three reasons:
flowchart LR
GBP[(GBP<br/>source of truth)] -->|API read| Sync[Baiyuan sync service]
Sync -->|normalize| DB[(Baiyuan DB<br/>brand_*)]
DB -->|generate| JSONLD[Schema.org JSON-LD]
JSONLD --> AXP[AXP shadow doc]
AXP -->|CF Worker injection| AI[AI bot]
AXP -->|sitemap.xml| GB[Googlebot]
Fig 8-1: Data flows in one direction. GBP edited → Baiyuan DB follows → JSON-LD regenerated → AXP updated → AI crawls. The customer maintains data in only one place.
Key principle: the sync is one-way. Baiyuan platform does not write back to GBP (at least in Phase 1–2) to avoid dual-write conflicts and accidental overrides. Phase 3 will open up the LocalPosts write path (see §8.7).
The GBP API is not available by self-registration. It requires an approval process. Noteworthy checkpoints:
| Stage | Content | Timeline | Notes |
|---|---|---|---|
| 1. Prerequisites | Own a Google Cloud project + at least one verified GBP | 1 day | If no existing GBP, use a managed brand’s GBP |
| 2. Submit application | Use-case description, estimated QPM, data purpose | Half a day | Use case must focus on “tools for business owners to manage their own profile” |
| 3. Google review | Google team assesses eligibility | 7–10 business days | Officially stated; real timelines can run longer |
| 4. Approval | Quota granted, relevant scopes opened | Instant | Default QPM = 300, higher quotas available on further application |
Our strategy: accumulate verified GBPs during Phase 1 (Schema.org manual fill), then submit Phase 2’s application with 5 verified case studies as eligibility evidence.
To let Baiyuan read a customer’s GBP, two hosting models are available:
flowchart TB
subgraph Manager["Model A: Add Manager"]
C1[Customer adds Baiyuan as Manager<br/>in GBP UI]
C1 --> S1[Baiyuan uses Service Account<br/>to read the location]
S1 --> Pro1["+ one-time setup, long-lived<br/>- requires customer to use GBP UI<br/>- Baiyuan sees all locations"]
end
subgraph OAuth["Model B: OAuth"]
C2[Customer clicks 'Connect Google'<br/>in Baiyuan UI]
C2 --> S2[OAuth flow obtains<br/>refresh_token]
S2 --> Pro2["+ familiar UX (like FB connect)<br/>+ fine-grained scope<br/>- refresh_token expires periodically<br/>- token storage maintenance"]
end
Fig 8-2: Model A is simpler but has a higher user-skill bar. Model B’s UX is familiar but has token-maintenance cost.
The platform runs both models in parallel: the UI defaults to OAuth (B); if OAuth fails to obtain permissions (e.g., Workspace accounts with management restrictions), it falls back to Manager-add (A).
The GBP data model does not align one-to-one with Schema.org. An explicit mapping table is required. Twelve commonly needed mappings:
| GBP field | Schema.org property | Conversion rule |
|---|---|---|
title |
Organization.name |
Direct map, trim whitespace |
storefrontAddress |
Organization.address |
Build PostalAddress object (split multi-line address) |
primaryPhone |
Organization.telephone |
Normalize to E.164 |
websiteUri |
Organization.url |
Validate resolvable URL |
regularHours.periods |
openingHoursSpecification |
Convert day-of-week + open/close times to array |
categories.primaryCategory |
@type choice |
Map to Baiyuan’s 25-industry industry_code |
profile.description |
Organization.description |
Max 750 chars (GBP limit) |
metadata.placeId |
Organization.identifier + sameAs |
identifier carries the place_id; sameAs carries the Maps URL |
moreHours |
specialOpeningHoursSpecification |
Split special periods (lunch breaks, holidays) |
attributes |
amenityFeature / hasOfferCatalog |
Assign to different properties by attribute type |
media.photos |
image / logo |
First photo becomes logo; rest become image array |
reviews |
aggregateRating + review |
Rating + review sample (capped, not all) |
Each rule is implemented as a pure function in gbpToSchema.js and tested with fixtures that assert expected JSON-LD output.
GBP API’s default quota is 300 QPM (queries per minute). The trade-off is between data freshness and quota exhaustion.
| Field type | Sync frequency | Daily QPS | Rationale |
|---|---|---|---|
| Basic info (name, address, hours) | once daily | very low | Low change rate |
| Opening hours changes | hourly | low | Ad-hoc closures, holiday hours need timely reflection |
| Photos, attributes | once daily | low | Medium change rate |
| Reviews | every 10 minutes | medium | Reviews arrive frequently and affect aggregateRating |
| Q&A | hourly | low | Lower velocity than reviews |
Fig 8-3: Each location consumes ~150–200 quota calls per day. A 300 QPM account supports ~2,000 locations concurrently.
When brand count exceeds per-account QPM:
The GBP API does not provide webhooks.1 When a customer edits their GBP, there is no real-time notification path back to Baiyuan. Remedies:
metadata.updateTime; only rebuild JSON-LD if the time has advanced, reducing unnecessary downstream work.Stacked, these three compress “GBP edit → AI visible” latency to 5–10 minutes. For most scenarios this is enough. Truly real-time use cases (e.g., “are they open right now” queries) would require further work.
flowchart LR
P1["Phase 1<br/>🟢 live<br/>Local Schema.org<br/>manual fill + GBP URL paste"]
P2["Phase 2<br/>🟡 waiting on API approval<br/>GBP API read<br/>auto-sync basic info"]
P3["Phase 3<br/>⚪ planned<br/>LocalPosts write<br/>active ClaimReview publication"]
P4["Phase 4<br/>⚪ future<br/>Organization Account<br/>chain-brand batch management"]
P1 --> P2 --> P3 --> P4
Fig 8-4: Four phases progressing from read → write → batch. Phase 1 is live independent of API approval; Phase 2 activates on approval; Phases 3–4 scheduled by business demand.
| Phase | Features | Dependency | Status |
|---|---|---|---|
| Phase 1 | 25-industry Schema.org, manual fill, GBP URL → Place ID, Wizard+Edit, AXP injection | None | ✅ shipped (v2.19.x) |
| Phase 2 | GBP API read: basic info, opening hours, reviews, photos auto-sync | GBP API approval | 🟡 under review |
| Phase 3 | LocalPosts write (brand announcements / events), active ClaimReview publication to Google | Phase 2 stable for 3 months | ⚪ planned |
| Phase 4 | Organization Account: chain brands managed through one entry, batch edit, aggregated metrics | Google enables Organization Account for Partner | ⚪ future |
Phase 1’s completion is not gated on GBP API approval — the customer pastes a Maps URL, the platform extracts Place ID, and Schema.org produces sameAs linking to Google Maps. This lets the platform ship while the Google review runs.
Navigation: ← Ch 7: Schema.org Phase 1 · 📖 Index · Ch 9: Closed-Loop Hallucination Remediation →
Google Business Profile API. Notifications overview. https://developers.google.com/my-business/content/notification-setup ↩