googlemaps-kit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -2
- package/dist/books.d.ts +30 -0
- package/dist/books.d.ts.map +1 -0
- package/dist/books.js +77 -0
- package/dist/books.js.map +1 -0
- package/dist/client/http-client.d.ts +3 -1
- package/dist/client/http-client.d.ts.map +1 -1
- package/dist/client/http-client.js +14 -3
- package/dist/client/http-client.js.map +1 -1
- package/dist/client/namespaces.d.ts +1 -4
- package/dist/client/namespaces.d.ts.map +1 -1
- package/dist/client/namespaces.js +1 -5
- package/dist/client/namespaces.js.map +1 -1
- package/dist/finance/client.d.ts +19 -0
- package/dist/finance/client.d.ts.map +1 -0
- package/dist/finance/client.js +75 -0
- package/dist/finance/client.js.map +1 -0
- package/dist/finance/parsers.d.ts +13 -0
- package/dist/finance/parsers.d.ts.map +1 -0
- package/dist/finance/parsers.js +146 -0
- package/dist/finance/parsers.js.map +1 -0
- package/dist/finance/types.d.ts +76 -0
- package/dist/finance/types.d.ts.map +1 -0
- package/dist/finance/types.js +2 -0
- package/dist/finance/types.js.map +1 -0
- package/dist/finance.d.ts +5 -0
- package/dist/finance.d.ts.map +1 -0
- package/dist/finance.js +4 -0
- package/dist/finance.js.map +1 -0
- package/dist/flights/client.d.ts +9 -0
- package/dist/flights/client.d.ts.map +1 -0
- package/dist/flights/client.js +14 -0
- package/dist/flights/client.js.map +1 -0
- package/dist/flights/parsers.d.ts +11 -0
- package/dist/flights/parsers.d.ts.map +1 -0
- package/dist/flights/parsers.js +64 -0
- package/dist/flights/parsers.js.map +1 -0
- package/dist/flights/types.d.ts +52 -0
- package/dist/flights/types.d.ts.map +1 -0
- package/dist/flights/types.js +2 -0
- package/dist/flights/types.js.map +1 -0
- package/dist/flights.d.ts +5 -0
- package/dist/flights.d.ts.map +1 -0
- package/dist/flights.js +4 -0
- package/dist/flights.js.map +1 -0
- package/dist/gemini-web/client.d.ts +16 -0
- package/dist/gemini-web/client.d.ts.map +1 -0
- package/dist/gemini-web/client.js +110 -0
- package/dist/gemini-web/client.js.map +1 -0
- package/dist/gemini-web/parsers.d.ts +5 -0
- package/dist/gemini-web/parsers.d.ts.map +1 -0
- package/dist/gemini-web/parsers.js +62 -0
- package/dist/gemini-web/parsers.js.map +1 -0
- package/dist/gemini-web/types.d.ts +47 -0
- package/dist/gemini-web/types.d.ts.map +1 -0
- package/dist/gemini-web/types.js +2 -0
- package/dist/gemini-web/types.js.map +1 -0
- package/dist/gemini-web.d.ts +5 -0
- package/dist/gemini-web.d.ts.map +1 -0
- package/dist/gemini-web.js +4 -0
- package/dist/gemini-web.js.map +1 -0
- package/dist/google-search/client.d.ts +16 -0
- package/dist/google-search/client.d.ts.map +1 -0
- package/dist/google-search/client.js +117 -0
- package/dist/google-search/client.js.map +1 -0
- package/dist/google-search/errors.d.ts +8 -0
- package/dist/google-search/errors.d.ts.map +1 -0
- package/dist/google-search/errors.js +13 -0
- package/dist/google-search/errors.js.map +1 -0
- package/dist/google-search/html.d.ts +12 -0
- package/dist/google-search/html.d.ts.map +1 -0
- package/dist/google-search/html.js +135 -0
- package/dist/google-search/html.js.map +1 -0
- package/dist/google-search/parsers.d.ts +6 -0
- package/dist/google-search/parsers.d.ts.map +1 -0
- package/dist/google-search/parsers.js +177 -0
- package/dist/google-search/parsers.js.map +1 -0
- package/dist/google-search/types.d.ts +66 -0
- package/dist/google-search/types.d.ts.map +1 -0
- package/dist/google-search/types.js +2 -0
- package/dist/google-search/types.js.map +1 -0
- package/dist/google-search.d.ts +6 -0
- package/dist/google-search.d.ts.map +1 -0
- package/dist/google-search.js +4 -0
- package/dist/google-search.js.map +1 -0
- package/dist/hotels/client.d.ts +9 -0
- package/dist/hotels/client.d.ts.map +1 -0
- package/dist/hotels/client.js +14 -0
- package/dist/hotels/client.js.map +1 -0
- package/dist/hotels/parsers.d.ts +7 -0
- package/dist/hotels/parsers.d.ts.map +1 -0
- package/dist/hotels/parsers.js +74 -0
- package/dist/hotels/parsers.js.map +1 -0
- package/dist/hotels/types.d.ts +55 -0
- package/dist/hotels/types.d.ts.map +1 -0
- package/dist/hotels/types.js +2 -0
- package/dist/hotels/types.js.map +1 -0
- package/dist/hotels.d.ts +4 -0
- package/dist/hotels.d.ts.map +1 -0
- package/dist/hotels.js +3 -0
- package/dist/hotels.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/known-surfaces.d.ts +0 -6
- package/dist/known-surfaces.d.ts.map +1 -1
- package/dist/known-surfaces.js +0 -6
- package/dist/known-surfaces.js.map +1 -1
- package/dist/lens/client.d.ts +14 -0
- package/dist/lens/client.d.ts.map +1 -0
- package/dist/lens/client.js +116 -0
- package/dist/lens/client.js.map +1 -0
- package/dist/lens/errors.d.ts +8 -0
- package/dist/lens/errors.d.ts.map +1 -0
- package/dist/lens/errors.js +13 -0
- package/dist/lens/errors.js.map +1 -0
- package/dist/lens/types.d.ts +27 -0
- package/dist/lens/types.d.ts.map +1 -0
- package/dist/lens/types.js +2 -0
- package/dist/lens/types.js.map +1 -0
- package/dist/lens.d.ts +8 -0
- package/dist/lens.d.ts.map +1 -0
- package/dist/lens.js +5 -0
- package/dist/lens.js.map +1 -0
- package/dist/news.d.ts +46 -0
- package/dist/news.d.ts.map +1 -0
- package/dist/news.js +202 -0
- package/dist/news.js.map +1 -0
- package/dist/pagespeed/client.d.ts +28 -0
- package/dist/pagespeed/client.d.ts.map +1 -0
- package/dist/pagespeed/client.js +222 -0
- package/dist/pagespeed/client.js.map +1 -0
- package/dist/pagespeed/errors.d.ts +9 -0
- package/dist/pagespeed/errors.d.ts.map +1 -0
- package/dist/pagespeed/errors.js +15 -0
- package/dist/pagespeed/errors.js.map +1 -0
- package/dist/pagespeed/parsers.d.ts +7 -0
- package/dist/pagespeed/parsers.d.ts.map +1 -0
- package/dist/pagespeed/parsers.js +236 -0
- package/dist/pagespeed/parsers.js.map +1 -0
- package/dist/pagespeed/types.d.ts +156 -0
- package/dist/pagespeed/types.d.ts.map +1 -0
- package/dist/pagespeed/types.js +2 -0
- package/dist/pagespeed/types.js.map +1 -0
- package/dist/pagespeed/wire.d.ts +10 -0
- package/dist/pagespeed/wire.d.ts.map +1 -0
- package/dist/pagespeed/wire.js +96 -0
- package/dist/pagespeed/wire.js.map +1 -0
- package/dist/pagespeed.d.ts +6 -0
- package/dist/pagespeed.d.ts.map +1 -0
- package/dist/pagespeed.js +4 -0
- package/dist/pagespeed.js.map +1 -0
- package/dist/platform/catalog.d.ts.map +1 -1
- package/dist/platform/catalog.js +0 -9
- package/dist/platform/catalog.js.map +1 -1
- package/dist/services/environment/air-quality.d.ts.map +1 -1
- package/dist/services/environment/air-quality.js +3 -7
- package/dist/services/environment/air-quality.js.map +1 -1
- package/dist/services/environment/weather.d.ts +4 -1
- package/dist/services/environment/weather.d.ts.map +1 -1
- package/dist/services/environment/weather.js +12 -3
- package/dist/services/environment/weather.js.map +1 -1
- package/dist/services/reviews.d.ts.map +1 -1
- package/dist/services/reviews.js +4 -1
- package/dist/services/reviews.js.map +1 -1
- package/dist/translate.d.ts +75 -0
- package/dist/translate.d.ts.map +1 -0
- package/dist/translate.js +126 -0
- package/dist/translate.js.map +1 -0
- package/dist/travel-google/common.d.ts +24 -0
- package/dist/travel-google/common.d.ts.map +1 -0
- package/dist/travel-google/common.js +72 -0
- package/dist/travel-google/common.js.map +1 -0
- package/dist/trends/client.d.ts +17 -0
- package/dist/trends/client.d.ts.map +1 -0
- package/dist/trends/client.js +86 -0
- package/dist/trends/client.js.map +1 -0
- package/dist/trends/errors.d.ts +8 -0
- package/dist/trends/errors.d.ts.map +1 -0
- package/dist/trends/errors.js +13 -0
- package/dist/trends/errors.js.map +1 -0
- package/dist/trends/links.d.ts +8 -0
- package/dist/trends/links.d.ts.map +1 -0
- package/dist/trends/links.js +71 -0
- package/dist/trends/links.js.map +1 -0
- package/dist/trends/parsers.d.ts +5 -0
- package/dist/trends/parsers.d.ts.map +1 -0
- package/dist/trends/parsers.js +126 -0
- package/dist/trends/parsers.js.map +1 -0
- package/dist/trends/types.d.ts +71 -0
- package/dist/trends/types.d.ts.map +1 -0
- package/dist/trends/types.js +2 -0
- package/dist/trends/types.js.map +1 -0
- package/dist/trends.d.ts +9 -0
- package/dist/trends.d.ts.map +1 -0
- package/dist/trends.js +8 -0
- package/dist/trends.js.map +1 -0
- package/dist/types/common.d.ts +0 -2
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js.map +1 -1
- package/dist/utils/google-web.d.ts +24 -0
- package/dist/utils/google-web.d.ts.map +1 -0
- package/dist/utils/google-web.js +150 -0
- package/dist/utils/google-web.js.map +1 -0
- package/dist/youtube/client.d.ts +19 -0
- package/dist/youtube/client.d.ts.map +1 -0
- package/dist/youtube/client.js +115 -0
- package/dist/youtube/client.js.map +1 -0
- package/dist/youtube/errors.d.ts +8 -0
- package/dist/youtube/errors.d.ts.map +1 -0
- package/dist/youtube/errors.js +13 -0
- package/dist/youtube/errors.js.map +1 -0
- package/dist/youtube/parsers.d.ts +9 -0
- package/dist/youtube/parsers.d.ts.map +1 -0
- package/dist/youtube/parsers.js +213 -0
- package/dist/youtube/parsers.js.map +1 -0
- package/dist/youtube/types.d.ts +90 -0
- package/dist/youtube/types.d.ts.map +1 -0
- package/dist/youtube/types.js +2 -0
- package/dist/youtube/types.js.map +1 -0
- package/dist/youtube.d.ts +9 -0
- package/dist/youtube.d.ts.map +1 -0
- package/dist/youtube.js +6 -0
- package/dist/youtube.js.map +1 -0
- package/docs/books.md +18 -0
- package/docs/environment-research.md +65 -0
- package/docs/finance-research.md +153 -0
- package/docs/finance.md +43 -0
- package/docs/gemini-web.md +36 -0
- package/docs/google-ai-books-research.md +53 -0
- package/docs/google-media-research.md +105 -0
- package/docs/google-search-research.md +36 -0
- package/docs/google-search.md +53 -0
- package/docs/google-services-research.md +135 -0
- package/docs/google-travel-research.md +86 -0
- package/docs/internal/reverse-engineering.md +85 -0
- package/docs/lens.md +54 -0
- package/docs/maps-revalidation.md +31 -0
- package/docs/news.md +35 -0
- package/docs/pagespeed-research.md +153 -0
- package/docs/pagespeed.md +135 -0
- package/docs/reviews-research.md +33 -0
- package/docs/translate.md +78 -0
- package/docs/trends-research.md +82 -0
- package/docs/trends.md +75 -0
- package/docs/youtube.md +72 -0
- package/package.json +77 -2
- package/dist/services/aerial-view.d.ts +0 -22
- package/dist/services/aerial-view.d.ts.map +0 -1
- package/dist/services/aerial-view.js +0 -107
- package/dist/services/aerial-view.js.map +0 -1
- package/dist/types/aerial-view.d.ts +0 -39
- package/dist/types/aerial-view.d.ts.map +0 -1
- package/dist/types/aerial-view.js +0 -2
- package/dist/types/aerial-view.js.map +0 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Google services: pricing, access, and investigation inventory
|
|
2
|
+
|
|
3
|
+
Source review date: **2026-10-29**. This is an investigation catalog of 25 relevant
|
|
4
|
+
service families, not an inventory of every Google product or a claim that all
|
|
5
|
+
Google interfaces have been reverse engineered.
|
|
6
|
+
|
|
7
|
+
Google's charges for its supported APIs, paid consumer subscriptions, advertising
|
|
8
|
+
spend, and third-party scraping vendors are separate things. A public consumer
|
|
9
|
+
page with no per-query charge does not provide the same data, throughput,
|
|
10
|
+
features, authorization, retention rights, or stability as a supported paid API.
|
|
11
|
+
Prices below are Google-published USD list prices, where available, rather than
|
|
12
|
+
third-party SERP-provider prices. Free allocations are not unlimited access.
|
|
13
|
+
|
|
14
|
+
## Current catalog
|
|
15
|
+
|
|
16
|
+
**Existing** means code was already present in this repository; it does not mean
|
|
17
|
+
every surface was revalidated during this investigation. **Implemented** denotes
|
|
18
|
+
a bounded client added in this task, with individual methods qualified below.
|
|
19
|
+
**Investigated** denotes consumer-surface or access-boundary research without
|
|
20
|
+
claiming complete implementation. Individual methods can remain
|
|
21
|
+
blocked or require authentication even when their service family has code.
|
|
22
|
+
|
|
23
|
+
| # | Service | Google pricing and official access | Repository/investigation state |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| 1 | Maps display and tiles | Metered Maps SKUs; Dynamic Maps starts at $7/1,000 after 10,000 monthly free loads. Embed has an unlimited no-cost SKU. A billing-enabled project and API key are normally required. [Pricing](https://developers.google.com/maps/billing-and-pricing/pricing), [setup](https://developers.google.com/maps/get-started). | **Existing**: map tiles, static maps, panorama, and other consumer transports. This is partial product coverage. |
|
|
26
|
+
| 2 | Places search/details | SKU and requested fields determine cost: Details Essentials $5/1,000 after 10,000 monthly free; Pro $17/1,000 after 5,000. Text/Nearby Search Pro starts at $32/1,000 after 5,000. [Pricing](https://developers.google.com/maps/billing-and-pricing/pricing), [field masks](https://developers.google.com/maps/documentation/places/web-service/place-details). | **Existing**: `places.search`, details, enrichment, photos, and suggestions. |
|
|
27
|
+
| 3 | Place reviews | No separate general-purpose paid “Google Reviews API.” Places `reviews` triggers Enterprise + Atmosphere fields; Details is $25/1,000 after 1,000 monthly free. Public Places returns at most five reviews, relevance-sorted. Authorized Business Profile reviews are a different paginated API for verified managed locations. [Fields](https://developers.google.com/maps/documentation/places/web-service/place-details), [five-review limit](https://developers.google.com/maps/documentation/places/web-service/reference/rest/v1/places), [owner API](https://developers.google.com/my-business/reference/rest/v4/accounts.locations.reviews/list). | **Existing, revalidated**: anonymous BOQ pagination and rating totals succeeded live; authenticated fallback cursor progression was fixed and tested offline. See [validation](reviews-research.md). The public Places cap is not the consumer BOQ pagination contract. |
|
|
28
|
+
| 4 | Routes and distance matrix | Compute Routes/Matrix Essentials $5/1,000 after 10,000 monthly free; Pro/Enterprise and matrix billable elements change cost. [Pricing](https://developers.google.com/maps/billing-and-pricing/pricing). | **Existing, partly revalidated**: consumer directions and matrix fan-out; a fresh driving route returned duration, distance and a leg. Transit and matrix were not revalidated here. See [evidence](maps-revalidation.md). |
|
|
29
|
+
| 5 | Geocoding | $5/1,000 after 10,000 monthly free requests. Key, enabled API, and billing project. [Pricing](https://developers.google.com/maps/billing-and-pricing/pricing), [setup](https://developers.google.com/maps/get-started). | **Existing, revalidated**: forward/reverse geocoding through Maps search succeeded. See [evidence](maps-revalidation.md). |
|
|
30
|
+
| 6 | Street View | Static panoramas $7/1,000 after 10,000 monthly free; Dynamic Street View $14/1,000 after 5,000. Metadata is a no-cost SKU. [Pricing](https://developers.google.com/maps/billing-and-pricing/pricing). | **Existing**: consumer panorama search/metadata/tiles and static rendering. |
|
|
31
|
+
| 7 | Trends | Consumer Trends has a public UI. An official API **does exist as a limited-access alpha**; applications are open, but access is not available to everyone. The reviewed alpha page publishes no generally available per-request price schedule. Its consistently scaled five-year data is not identical to UI normalization. [Official alpha](https://developers.google.com/search/apis/trends). | **Implemented, partial**: topic suggestions and trending RSS succeeded; Explore/embed URL builders use shipped contracts. Explore data returned 429 in HTTP and browser tests. No unverified widget-data client is exposed. See [guide](trends.md). |
|
|
32
|
+
| 8 | Web Search results | Consumer Search has no ordinary per-query charge. Custom Search JSON API is closed to new customers; existing users receive 100 free queries/day, then $5/1,000 up to 10,000/day, until discontinuation on 2027-01-01. It is not a full consumer SERP API. [Current official notice](https://developers.google.com/custom-search/v1/overview). | **Implemented, partial**: public autocomplete succeeded. Search requests expose explicit access states and experimental HTML parsing; live organic-result retrieval was blocked. See [guide](google-search.md). |
|
|
33
|
+
| 9 | Search AI Overviews / AI Mode | No supported API promising the exact consumer AI Overview was identified in the reviewed official material. Overviews do not trigger for every query. Gemini Search grounding is a separate API capability, not the same rendered answer. [Search behavior](https://developers.google.com/search/docs/appearance/ai-features), [grounding](https://ai.google.dev/gemini-api/docs/google-search). | **Investigated, blocked**: Search returned a JavaScript interstitial in Node and an unusual-traffic challenge in a normal browser. Positive Overview extraction is unverified, with only an experimental parser contract. See [evidence](google-search-research.md). |
|
|
34
|
+
| 10 | Gemini | Developer API has model-specific free and paid tiers. Paid inference is metered by tokens/modalities; Search grounding on Gemini 3+ has 5,000 free search requests/month shared across those models, then $14/1,000. Model and date-specific prices vary. API credentials are separate from consumer app subscriptions. [Pricing](https://ai.google.dev/gemini-api/docs/pricing), [limits](https://ai.google.dev/gemini-api/docs/rate-limits). | **Implemented, partial**: anonymous text generation was observed through the browser composer. The client requires a caller-owned browser Page; HTTP bootstrap inspection is separate. WebChannel/protobuf traffic was observed, but standalone HTTP generation and the browser anti-abuse token remain unresolved. See [guide](gemini-web.md) and [evidence](google-ai-books-research.md). |
|
|
35
|
+
| 11 | Translate | Cloud Translation NMT grants 500,000 characters/month through a $10 credit, then the standard rate is $20/million characters; models/document methods have other rates. Consumer Translate is a separate surface. [Pricing](https://cloud.google.com/products/translate/pricing), [quotas](https://docs.cloud.google.com/translate/quotas). | **Implemented, partial**: text translation/detection, suggestions, language lists and MP3 speech succeeded through anonymous web RPCs. Enterprise Cloud features are outside this client. See [guide and evidence](translate.md). |
|
|
36
|
+
| 12 | Finance | Public Finance pages and the Sheets `GOOGLEFINANCE` function are not a documented general paid quote API. Quotes can be delayed; Sheets historical data cannot be accessed through Sheets API or Apps Script. No general Finance API price schedule was identified. [Function restrictions](https://support.google.com/docs/answer/3093281?hl=en), [data terms](https://www.google.com/googlefinance/disclaimer/). | **Implemented, partial**: quotes, instrument search and sampled charts across eight ranges succeeded through public FinHubUi RPCs. Regular/extended sessions and timestamps are preserved; delay is not assumed real-time. See [guide](finance.md). |
|
|
37
|
+
| 13 | News | A general supported Google News query API and corresponding Google per-query price were not identified in reviewed official docs. Search Console's Google News reports concern the authorized site's performance, not arbitrary news retrieval. [Report distinction](https://developers.google.com/search/blog/2021/10/search-analytics-discover-gnews). | **Implemented, partial**: public headline and search RSS succeeded; article redirects, source metadata and feed notices are preserved. No full-article or arbitrary pagination claim. See [guide](news.md). |
|
|
38
|
+
| 14 | Shopping / Merchant Center | Merchant Center and free product listings are distinct from paid Shopping ads. Merchant API manages a merchant's account/products/inventory using OAuth or a service account; it is not an API for arbitrary consumer Shopping SERPs. Content API for Shopping sunset on 2026-08-18. [Merchant Center](https://business.google.com/us/merchant-center/), [Merchant API](https://developers.google.com/merchant/api/overview). | **Investigated, blocked**: consumer `udm=28` search returned an enable-JavaScript page over HTTP and a CAPTCHA in an ordinary browser. No positive product-result parser or anonymous merchant-account access is claimed. See [evidence](google-travel-research.md). |
|
|
39
|
+
| 15 | Flights | Google describes Flights Search as free organic metasearch. Its developer material is for airline/OTA onboarding; some integration material is invite-only. No generally available paid consumer flight-search API price was identified. [Official Flights developer page](https://developers.google.com/travel/flights). | **Implemented, partial**: `LqxFAb` search replay returned one-way economy offers for one adult, with segments, local dates/times and available prices. Exact airport codes and explicit date required; no booking or round-trip contract. See [guide and evidence](google-travel-research.md). |
|
|
40
|
+
| 16 | Hotels | Travel Partner/Hotel APIs manage the partner's Hotel Center data, price feeds, diagnostics, and reports; OAuth/service-account access must be granted to that hotel data. They are not a general public hotel-price search API. [Resources](https://developers.google.com/hotels/hotel-prices/api-reference/rest), [authorization](https://developers.google.com/hotels/hotel-prices/dev-guide/api-auth). | **Implemented, partial**: `MQghPc` search replay returned hotel cards, displayed prices, echoed stay dates/currency and page tokens; a second page was retrieved. Displayed prices are not labeled nightly totals; duplicates can occur across pages. No booking or partner-account API. See [guide and evidence](google-travel-research.md). |
|
|
41
|
+
| 17 | YouTube | Public data uses a project/API key; private data and writes use OAuth. Current default allocations are 100 `search.list` calls/day, 100 `videos.insert` calls/day, plus 10,000 units/day across other endpoints. These are quota units, not dollar charges. Additional quota requires review. [Current overview](https://developers.google.com/youtube/data/getting-started), [quota/audit](https://developers.google.com/youtube/data/guides/quota_and_compliance_audits). | **Implemented, partial**: public watch metadata, caption-track metadata, oEmbed, search and continuation succeeded. Caption-content probes returned empty bodies; no transcript-content or media-download API is exposed. See [guide](youtube.md) and [evidence](google-media-research.md). |
|
|
42
|
+
| 18 | Ads / Keyword Planner | Ads API use is free at Explorer/Basic/Standard access levels; ad spend is separate. Keyword Planning is an authenticated Ads-account capability. Developer tokens sunset on 2026-09-09: access levels now attach to the Cloud project owning OAuth credentials; old token headers are optional. [API pricing](https://developers.google.com/google-ads/api/docs/productionize/access-levels), [current migration](https://developers.google.com/google-ads/api/docs/api-policy/developer-token), [keyword planning](https://developers.google.com/google-ads/api/docs/keyword-planning/overview). | **Investigated, authentication required**: Planner UI redirected to sign-in and the read-only accessible-customer API returned 401. KeywordPlanIdeaService requires appropriate higher access than Explorer. No anonymous keyword metrics were retrieved. See [evidence](google-ai-books-research.md). |
|
|
43
|
+
| 19 | Search Console | API is free, subject to quotas, and requires OAuth authorization for the user's accessible properties. It reports site performance rather than unrestricted Google search volume or rankings. [Pricing](https://developers.google.com/webmaster-tools/pricing), [authorization](https://developers.google.com/webmaster-tools/v1/how-tos/authorizing), [limits](https://developers.google.com/webmaster-tools/limits). | **Investigated, authentication required**: UI returned the public about page; the read-only property-list API returned 401. Private property analytics and inspection were not retrieved. See [evidence](google-ai-books-research.md). |
|
|
44
|
+
| 20 | PageSpeed Insights | Public UI plus documented API. Official documentation allows API use with or without a key, recommending a key for automated queries; actual quota may still reject requests. The no-key official probe here returned 429 with quota limit zero. [Official getting started](https://developers.google.com/speed/docs/insights/v5/get-started). | **Implemented**: create/get/poll/wait/analyze consumer RPC workflow, saved analyses, and official `runPagespeed` transport. Successful web report had six completed records; see [wire research](pagespeed-research.md). |
|
|
45
|
+
| 21 | CrUX | Supported CrUX API requires a Cloud API key and provides 150 queries/minute/project without charge. Coverage depends on available aggregated real-user data; lack of data is not a billing issue. [API/auth](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference/rest/), [rate/price](https://developer.chrome.com/docs/crux/api). | **Implemented** through PageSpeed's page/origin records for mobile/desktop. Standalone keyed CrUX API transport is not claimed here. |
|
|
46
|
+
| 22 | Weather | Weather API starts at $0.15/1,000 after 10,000 monthly free billable events; project/key setup applies. [Current Maps pricing](https://developers.google.com/maps/billing-and-pricing/pricing). | **Existing, partial; corrected**: viewport current-condition chip revalidated. Official current-condition/forecast routes require a caller key; forecast now calls forecast rather than current conditions. No-key official probe returned 403. See [evidence](environment-research.md). |
|
|
47
|
+
| 23 | Air Quality | Air Quality API starts at $5/1,000 after 10,000 monthly free billable events; project/key setup applies. [Current Maps pricing](https://developers.google.com/maps/billing-and-pricing/pricing). | **Existing, partial; corrected**: official point lookup now sends the required POST JSON body. No-key probe returned 403; a successful keyed execution was not performed. Heatmap/RPC plumbing does not establish anonymous point-data parity. See [evidence](environment-research.md). |
|
|
48
|
+
| 24 | Vision / Lens | Cloud Vision meters each image-feature unit: first 1,000 monthly units free; common label/OCR features then $1.50/1,000; Web Detection $3.50/1,000. Cloud Vision is not the full consumer Lens experience. No general dedicated Lens API contract was identified in reviewed official docs. [Vision pricing](https://cloud.google.com/vision/pricing), [Vision capabilities](https://docs.cloud.google.com/vision/docs), [consumer Lens](https://lens.google.com/). | **Implemented, limited Lens transport**: actual image upload returned a search-session redirect. Result navigation hit CAPTCHA, so no OCR or visual-match parser is exposed. No-key Cloud Vision POST returned 403. See [Lens guide](lens.md), [media evidence](google-media-research.md), and [official boundary](environment-research.md). |
|
|
49
|
+
| 25 | Books | Supported Books API exposes public book search/metadata and authorized personal bookshelves. Official docs require an API key or OAuth for public requests and OAuth for private data. No per-query price table was identified in reviewed docs; quotas do not by themselves imply payment. [Using the API](https://developers.google.com/books/docs/v1/using). | **Implemented, partial**: public bibliographic page by volume ID returned title, authors, publisher/year, edition, ISBNs and page count. Anonymous v1 API calls returned 429. No full-text, purchase, library or query-search client. See [guide](books.md) and [evidence](google-ai-books-research.md). |
|
|
50
|
+
|
|
51
|
+
Maps prices above are **global list prices** for the first paid band and depend
|
|
52
|
+
on the actual billable SKU/event. Google publishes a separate [India pricing
|
|
53
|
+
schedule](https://developers.google.com/maps/billing-and-pricing/pricing-india);
|
|
54
|
+
eligibility is not inferred from the user's current timezone. Per-SKU monthly
|
|
55
|
+
free caps supersede older blanket-credit descriptions in stale summaries.
|
|
56
|
+
|
|
57
|
+
## Coverage and unresolved questions
|
|
58
|
+
|
|
59
|
+
All 25 rows have an evidence-based disposition. New clients cover the successful
|
|
60
|
+
public surfaces; existing Maps families were inspected and selected operations
|
|
61
|
+
were revalidated. This is not complete reverse engineering of every feature or
|
|
62
|
+
every Google product. The detailed reports retain the unanswered questions:
|
|
63
|
+
|
|
64
|
+
- Trends Explore data, live Search/AI Overview extraction, Shopping results and
|
|
65
|
+
Lens recognition were blocked in the tested environment. A challenge response
|
|
66
|
+
is not a successful dataset and does not establish a permanent universal block.
|
|
67
|
+
- Gemini plain-HTTP generation remains unresolved; successful generation uses
|
|
68
|
+
the actual browser composer. Model entitlement and developer API parity were
|
|
69
|
+
not established.
|
|
70
|
+
- Ads, Search Console and the official Weather/Air Quality/Vision routes require
|
|
71
|
+
authorized caller identity. No credentials were supplied for positive
|
|
72
|
+
authenticated execution.
|
|
73
|
+
- Flights currently supports one-way economy search for one adult; Hotels
|
|
74
|
+
preserves displayed-price semantics and raw occupancy. Booking, partner
|
|
75
|
+
account operations and full Travel parity remain outside these contracts.
|
|
76
|
+
- YouTube caption content was empty in the actual probe. Track metadata does
|
|
77
|
+
not establish a transcript. Books metadata does not establish full text or
|
|
78
|
+
successful anonymous v1 query search.
|
|
79
|
+
- Maps display/tiles, Places, Street View, transit, matrix, and the broader
|
|
80
|
+
environment surface retain existing partial coverage; their every method was
|
|
81
|
+
not revalidated in this pass.
|
|
82
|
+
|
|
83
|
+
Support is promoted only after a successful response is captured and the parser
|
|
84
|
+
is tested on it. Experimental Search HTML parsers are explicitly separated from
|
|
85
|
+
verified live capabilities. Google's [Finance data terms](https://www.google.com/googlefinance/disclaimer/)
|
|
86
|
+
also distinguish public rendering from unrestricted redistribution.
|
|
87
|
+
|
|
88
|
+
## Evidence ledger
|
|
89
|
+
|
|
90
|
+
The sources above were discovered with TinyFish Search, then relevant primary
|
|
91
|
+
pages were fetched on 2026-10-29. Search snippets were not treated as the final
|
|
92
|
+
authority where body text differed. In particular:
|
|
93
|
+
|
|
94
|
+
- The Maps global price list body was marked updated **2026-10-28**; its SKU
|
|
95
|
+
table was used instead of older $200-credit summary text.
|
|
96
|
+
- The Custom Search overview body explicitly limits its published pricing to
|
|
97
|
+
existing customers and gives the **2027-01-01** discontinuation date.
|
|
98
|
+
- Ads pages still contained older autogenerated “developer token required”
|
|
99
|
+
summaries, while their current body text explained the **2026-09-09** sunset.
|
|
100
|
+
The current body/migration instructions govern the catalog entry.
|
|
101
|
+
- YouTube's current body describes separate search/upload call allocations;
|
|
102
|
+
historical references to 100 quota units per search were not reused.
|
|
103
|
+
- No supported general News/Finance/Lens consumer API price was established.
|
|
104
|
+
This is an absence of evidence in the reviewed scope, not proof that no
|
|
105
|
+
private, partner, limited-access, or future Google API can exist.
|
|
106
|
+
- Existing repository coverage was checked against `src/client/namespaces.ts`,
|
|
107
|
+
`src/platform/catalog.ts`, `src/known-surfaces.ts`, and the environment
|
|
108
|
+
service implementations. Weather/Air Quality are explicitly partial.
|
|
109
|
+
- PageSpeed runtime observations and REA evidence identifiers are recorded in
|
|
110
|
+
[pagespeed-research.md](pagespeed-research.md); that report distinguishes a
|
|
111
|
+
browser 429, successful direct replay, and the official API quota response.
|
|
112
|
+
|
|
113
|
+
Third-party products named “Google Search API,” “Google Trends API,” or
|
|
114
|
+
“Google News API” may charge for their own infrastructure and collection work.
|
|
115
|
+
Those vendor prices are not evidence that Google charges the corresponding
|
|
116
|
+
consumer UI or offers an equivalent official API.
|
|
117
|
+
|
|
118
|
+
## Integrated verification
|
|
119
|
+
|
|
120
|
+
The final integration passed `npm run build`, `npm run type-check`, and
|
|
121
|
+
`npm test`: **732 offline tests across 72 files**. All twelve added package
|
|
122
|
+
entry points imported and constructed without network access. An npm pack
|
|
123
|
+
dry run contained every declared JavaScript and declaration export.
|
|
124
|
+
|
|
125
|
+
`npm run test:google-public:live` passed **14 checks across eight files**;
|
|
126
|
+
the optional browser-generation test was skipped by that default command.
|
|
127
|
+
The Books/Gemini file was also run separately with caller-supplied Playwright
|
|
128
|
+
and browser paths: all three checks passed, including actual anonymous Gemini
|
|
129
|
+
generation. The dedicated PageSpeed live workflow also passed during release verification.
|
|
130
|
+
Search's live access-state check reported `javascript-required` and an
|
|
131
|
+
`unverified` AI Overview; its passing assertion is not positive result extraction.
|
|
132
|
+
|
|
133
|
+
These checks validate the bounded contracts above. They do not turn the
|
|
134
|
+
unresolved or authentication-required entries into implemented anonymous APIs.
|
|
135
|
+
Release verification also checks the packed artifact and a fresh package install.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Google Flights, Hotels and Shopping research
|
|
2
|
+
|
|
3
|
+
Verified 2026-10-29 against ordinary anonymous Google web pages, downloaded application JavaScript, captured browser requests and direct HTTP replays. The implementation covers two observed search protocols. It does not claim complete Travel/Shopping coverage or equivalence to a commercial booking API.
|
|
4
|
+
|
|
5
|
+
| Service | Result | Shipped entry point |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Flights | Search replay succeeded with real fares and itinerary segments | `googlemaps-kit/flights` |
|
|
8
|
+
| Hotels | Explicit-date search and next-page replay succeeded with property cards and prices | `googlemaps-kit/hotels` |
|
|
9
|
+
| Shopping | Browser was redirected to an unusual-traffic CAPTCHA; direct HTTP returned an enable-JavaScript challenge | None; investigated and blocked |
|
|
10
|
+
|
|
11
|
+
## Flights
|
|
12
|
+
|
|
13
|
+
The browser rendered a one-way BLR → BOM search on 2026-11-15, one adult, economy, INR. Its shipped bundle describes `LqxFAb` as `/FlightsFrontendService.GetShoppingResultsPrefetch`. A direct POST to `https://www.google.com/_/FlightsFrontendUi/data/batchexecute` succeeded with 35 offers: four in the best group and 31 in the other group. A browser request also used the streaming `FlightsFrontendService/GetShoppingResults` transport with RPC identifier `Sipqjf`; that separate transport is not implemented.
|
|
14
|
+
|
|
15
|
+
The client first loads the public Flights page and reads the current `WIZ_global_data` application path, session and build values. It sends the observed prefetch argument shape `[[], constraints]`. One-based constraint fields are:
|
|
16
|
+
|
|
17
|
+
| Field | Observed value / meaning |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| 3 | `2`, one-way |
|
|
20
|
+
| 6 | `1`, economy |
|
|
21
|
+
| 7 | `[1,0,0,0]`, the captured one-adult passenger tuple |
|
|
22
|
+
| 14 | Dated leg list |
|
|
23
|
+
|
|
24
|
+
Each leg has airport endpoints in fields 1/2, with endpoint tuples such as `['BLR',0]`; airport identifier type `0` was successfully replayed. Field 7 is the explicit departure date. The remaining captured constants are preserved rather than given speculative names.
|
|
25
|
+
|
|
26
|
+
The response has best offers under field 3, subfield 1, and other offers under field 4, subfield 1. Each offer's field 1 is an itinerary, and field 2 holds its price and opaque selection state. The price amount is in display currency units, not cents or micros; the capture's first IndiGo 6E 5205 fare was INR 6,559. A separate successful USD request returned a first price of USD 74, preserved without client-side conversion. One Air India Express offer had no price and remains unpriced in the client. Currency is negotiated with the request's `curr` parameter; the observed per-offer money wrapper omits its own currency label.
|
|
27
|
+
|
|
28
|
+
Itinerary field 3 holds segments. Segment fields 4/7 are origin/destination airport codes, 9/11 are local departure/arrival times, 21/22 are local dates, 12 is duration in minutes, 18 is aircraft, and 23 contains carrier code, flight number and carrier name. Dates and times are airport-local. They are never labeled UTC. A present time `[null,10]` represents 00:10 through an omitted zero hour; an absent time message is an error. The implementation checks every returned itinerary's origin, destination and first departure date against the request.
|
|
29
|
+
|
|
30
|
+
`searchUrl` is a constructed public search link using the requested route/date/currency/language. `selectionToken` is the captured opaque state. It is not a booking link, a reserved seat or a fare guarantee. No selection, checkout, reservation or purchase action was attempted.
|
|
31
|
+
|
|
32
|
+
Supported input is deliberately limited to one-way economy searches for one adult with distinct IATA airport codes. Return trips, multicity journeys, city IDs, passenger counts, cabins, filters, baggage, emissions, calendar fares, booking links and streaming updates are not exposed by this client.
|
|
33
|
+
|
|
34
|
+
## Hotels
|
|
35
|
+
|
|
36
|
+
The public Hotels page rendered Mumbai properties for 2026-11-15 to 2026-11-16 in INR. The shipped bundle describes `MQghPc` as `/HotelService.Search`. Successful direct POST replays used `https://www.google.com/_/TravelFrontendUi/data/batchexecute` with:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
["Mumbai",null,null,[null,null,null,"INR",[[2026,11,15],[2026,11,16],1,1]]]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Request field 4 carries currency and explicit stay dates. The trailing occupancy tuple is kept as captured; its individual meanings have not been established. The client does not expose invented adult/room controls. Field 5 carries the opaque page token returned by the prior response. First-page token `CAw` produced a successful second page with token `CBg`.
|
|
43
|
+
|
|
44
|
+
Response field 2 echoes search settings, including currency in field 4 and stay dates in field 5. Field 3 is the next page token, field 9 is the result-card list, and field 10 contains the approximate total result count. The first capture contained 12 HotelEntity cards and a reported total of 2,995; the next page contained 14 HotelEntity cards. Results can overlap across pages and ranking can change.
|
|
45
|
+
|
|
46
|
+
Only card extension `179305178` is decoded as HotelEntity, matching the application's own registered message extension. Other card kinds are ignored. Within that entity:
|
|
47
|
+
|
|
48
|
+
| Field | Decoded value |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| 2 | Property name |
|
|
51
|
+
| 3 | Detail message: coordinates, address, phone and returned links |
|
|
52
|
+
| 4 | Hotel class label and stars |
|
|
53
|
+
| 7 | Price wrapper; field 3 within it contains displayed price data |
|
|
54
|
+
| 8 | Rating and review count |
|
|
55
|
+
| 10 | Maps hexadecimal feature ID, retained as a string |
|
|
56
|
+
| 12 | Description |
|
|
57
|
+
| 13 | Image URL |
|
|
58
|
+
| 21 | Opaque Travel entity ID |
|
|
59
|
+
|
|
60
|
+
The detail message contains latitude/longitude in field 1, address in field 2, phone in field 3, the returned Maps link in field 14 and website link in field 30. Website links can be third-party listings. These links are copied from the response; no property or booking URLs are fabricated from opaque IDs.
|
|
61
|
+
|
|
62
|
+
Price data field 2 contains separately formatted, precise numeric and rounded numeric values. Field 9 contains stay dates and the opaque occupancy tuple; field 16 contains the actual currency. For example, one precise amount is `672.46875 INR` while Google's text reads `₹672`. The client preserves both. Search echoes must match the requested dates and currency, and each priced property must match the echoed currency and stay dates.
|
|
63
|
+
|
|
64
|
+
The UI supports nightly and stay-total presentations with taxes/fees. This capture used a one-night stay and does not establish the complete selector semantics. Therefore `basis` is `displayed`; the client does not label amounts as guaranteed per-night, tax-inclusive or full-stay totals. Tax breakdowns, merchant offers, room availability, cancellation policies and checkout are not normalized. Missing prices remain absent. Changing dates, occupancy or display options can change the result.
|
|
65
|
+
|
|
66
|
+
## Access limits and evidence
|
|
67
|
+
|
|
68
|
+
These are unofficial public web protocols, without stability guarantees. The shared transport uses the actual captured Chrome user agent for ordinary device negotiation, permits a caller-supplied user agent, fetch implementation, timeout and abort signal, and surfaces HTTP, RPC, access-guard and parse failures. There is no CAPTCHA solving, login bypass, proxy rotation or automatic request retry. An access failure is not converted to an empty results list.
|
|
69
|
+
|
|
70
|
+
The Shopping investigation stopped at the observed guard. The ordinary browser navigated to `/sorry/` and displayed a CAPTCHA; a separate direct request returned a 200 status with a JavaScript challenge instead of product data. This does not establish a usable product or merchant schema. No Shopping SDK wrapper is shipped.
|
|
71
|
+
|
|
72
|
+
The following REA evidence records document browser discovery and static bundle parsing. Static analysis corroborates RPC descriptors and message slots; it does not by itself prove server behavior. Runtime success is separately established by the decoded HTTP replay fixtures.
|
|
73
|
+
|
|
74
|
+
| Evidence | REA ID |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| Flights browser page | `ev_6077386c8c3bb2086bd186fd19f35f47d9c945442f0ede1fe9728023719b4578` |
|
|
77
|
+
| Flights bundle, 47 scripts | `ev_f4ac1e11d08184432c1f01f0c1b7f0ac0ba9b2545ade55a76a6872c5fd5060ab` |
|
|
78
|
+
| Hotels browser page | `ev_3981019501b2f88271da2adbe24455430a150592a4489454d5589c2ce703e2b2` |
|
|
79
|
+
| Hotels bundle, 98 scripts | `ev_70bcd4d43649387b20b1590f0819fd2f74507b8435277c3c19a1982aa63e9447` |
|
|
80
|
+
| Shopping guarded page | `ev_d4d801bdebf3c4c610767b8c1215df7023e5677500188dabbbbf61079154c0b4` |
|
|
81
|
+
|
|
82
|
+
Offline fixtures live in `tests/fixtures/flights` and `tests/fixtures/hotels`, with capture provenance. They retain the original research dates. The opt-in live suite uses a date 17 days ahead by default and accepts `GOOGLE_TRAVEL_DATE=YYYY-MM-DD`:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
GMAPS_LIVE=1 GOOGLE_TRAVEL_LIVE=1 npx vitest run tests/live/google-travel.test.ts
|
|
86
|
+
```
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Reverse-engineering notes — Maps web client internals
|
|
2
|
+
|
|
3
|
+
Field notes from deobfuscating the Google Maps web app bundles
|
|
4
|
+
(`maps.m.en.*` bootstrap + lazy modules) and its Web Worker loaders. Everything
|
|
5
|
+
documented here is implemented somewhere in `src/`; this file records *how the
|
|
6
|
+
client does it* so future changes can be re-derived.
|
|
7
|
+
|
|
8
|
+
## Bundle layout
|
|
9
|
+
|
|
10
|
+
| Piece | URL shape | Notes |
|
|
11
|
+
|-------|-----------|-------|
|
|
12
|
+
| Bootstrap | `/maps/_/js/k=maps.m.en.<key>.O/m=<initial>/am=<am>/rs=<rs>` | WIZ loader, `eptZe` = batchexecute prefix |
|
|
13
|
+
| Lazy modules | same + `ck=` client key | The server validates module *sets*; arbitrary lists 404 |
|
|
14
|
+
| Workers / WASM | `/maps/_/wa/<wli-entry>[.loader.js]` | `_/js/` → `_/wa/` swap decoded from `_.bTc` |
|
|
15
|
+
|
|
16
|
+
The `wli` preload hints in the page HTML (`m.<bundle>.<feature>.O`) name the
|
|
17
|
+
worker bundles: `smIQCHgOkp8` → **mapcore** (3D renderer),
|
|
18
|
+
`7P4nUyqPXWw` → **loadSv** (Street View), `syLOIf-d1F0` → **loadSvVtl**
|
|
19
|
+
(SV vector tiles), `yDBEh32NTLI` → labeler.
|
|
20
|
+
|
|
21
|
+
Workers are Emscripten shells; the renderers are WASM sidecars fetched
|
|
22
|
+
relative to the loader (`renderer_binary_web_release.wasm`,
|
|
23
|
+
`streetview_imp_wasm_cc_binary.wasm`, …). Message protocol is
|
|
24
|
+
`{ command, payload }` with transferable `ArrayBuffer`s (command 6 =
|
|
25
|
+
label/paint prep).
|
|
26
|
+
|
|
27
|
+
## vt layer descriptors (`_.er`)
|
|
28
|
+
|
|
29
|
+
Named overlay layers serialise into the `/maps/vt?pb=` layer block as
|
|
30
|
+
field 1 = type enum, field 2 = name string, field 3 = per-layer number,
|
|
31
|
+
field 4 = repeated key/value app options:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
!2m2!1e5!2sshading hillshade raster (global, z8+)
|
|
35
|
+
!2m2!1e6!2scontours contour lines (z13–15)
|
|
36
|
+
!2m2!1e2!2sair-quality-heatmap AQI heatmap (z5–15, city detail)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The JS switch also defines traffic (+`incidents`/`incidents_text`/
|
|
40
|
+
`seconds_into_week` options), transit (+`sp=2`, number 999999), bike,
|
|
41
|
+
`svv` (SV coverage vectors with camera/epoch options), indoor,
|
|
42
|
+
`crisis2`, `area-busyness`, `hotel-categorical-search`, `lore-p13n`,
|
|
43
|
+
`lore-rec`, `travel-map-reachability`. Those answer only inside the full
|
|
44
|
+
client style context — probed directly they return a valid-but-blank ~220-byte
|
|
45
|
+
placeholder PNG. That placeholder is how "no data" is signalled for the
|
|
46
|
+
working layers too.
|
|
47
|
+
|
|
48
|
+
## rocktree octree (`kh.google.com/rt/<planetoid>`)
|
|
49
|
+
|
|
50
|
+
- `PlanetoidMetadata` → root epoch (key field 1 → subfield 2) and radius.
|
|
51
|
+
- `BulkMetadata/pb=!1m2!1s<path>!2u<epoch>` → nodes carry packed
|
|
52
|
+
path+flags (level = low 2 bits + 1, 3 bits per octant), per-node epochs,
|
|
53
|
+
quantised OBB (centre deltas × metres-per-texel + Euler angles), and
|
|
54
|
+
imagery epoch. Flag bit 16 = NodeData requires `!3u{imageryEpoch}` —
|
|
55
|
+
sending it unrequested yields HTTP 404; flag bit 8 = metadata-only node.
|
|
56
|
+
- `NodeData/pb=!1m2!1s<path>!2u<epoch>!2e1[!3u<img>]!4b0` → globe-from-mesh
|
|
57
|
+
matrix (16 doubles), meshes whose vertices are three byte planes of running
|
|
58
|
+
deltas, triangle strips encoded as back-references, UVs as two delta planes
|
|
59
|
+
mod a wrap value, plus a 512×512 JPEG texture.
|
|
60
|
+
- Planets: `earth` (r 6371010 m), `mars` (3389500 m), `moon` (1737400 m).
|
|
61
|
+
|
|
62
|
+
## Street View
|
|
63
|
+
|
|
64
|
+
- `photometa v1` pb includes section list ids; id **18** opts into the
|
|
65
|
+
quantised depth raster (512×256) shipped alongside tiles.
|
|
66
|
+
- Panorama tile pyramid geometry comes from `tileSizes` /
|
|
67
|
+
`maxTileDimensions` / `tileFaceSize`; there is no video endpoint — the web
|
|
68
|
+
client renders equirectangular panoramas from these tiles.
|
|
69
|
+
- Imagery: `streetviewpixels-pa.googleapis.com/v1/{thumbnail,tile}`
|
|
70
|
+
(`cb_client=maps_sv.tactile`), no auth.
|
|
71
|
+
- Legacy `GeoPhotoService.SingleImageQuery` is gone from current bundles;
|
|
72
|
+
photometa is the canonical metadata surface.
|
|
73
|
+
|
|
74
|
+
## batchexecute registrations (`_.cy`)
|
|
75
|
+
|
|
76
|
+
Service-path format (`/MapsService.Method` as rpcid) works anonymously;
|
|
77
|
+
legacy short ids require the WIZ `SNlM0e` token. Confirmed id ↔ path pairs:
|
|
78
|
+
`EvxQ3b`→GetAreaTraffic, `hspqX`→ListEntityPhotos, `T4jwAf`→GetViewportMetadata,
|
|
79
|
+
`JGUSi`→GetUserPrefs, `PDqRpc`→WriteUserPrefs, `erVIH`→GetMapDetails,
|
|
80
|
+
`EGR9cd`→CallAskMapsAgent (signed-in only).
|
|
81
|
+
|
|
82
|
+
## Worker sources
|
|
83
|
+
|
|
84
|
+
Loader sources (captured locally during analysis, not checked in) are
|
|
85
|
+
Emscripten glue; no Maps business logic ships in them.
|
package/docs/lens.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Google Lens
|
|
2
|
+
|
|
3
|
+
The Lens client starts an image search and returns Google's issued results URL.
|
|
4
|
+
It also builds image-URL navigation links. OCR and visual-match results remain
|
|
5
|
+
unverified because the observed results page required a traffic challenge.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { lens } from 'googlemaps-kit/lens';
|
|
10
|
+
|
|
11
|
+
const client = lens({ locale: 'en-US' });
|
|
12
|
+
const image = await readFile('/absolute/path/to/image-you-want-to-search.png');
|
|
13
|
+
const session = await client.createSearch(image, {
|
|
14
|
+
filename: 'image.png',
|
|
15
|
+
mimeType: 'image/png',
|
|
16
|
+
});
|
|
17
|
+
console.log(session.url);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`createSearch()` uploads the caller-supplied `Uint8Array` or `Blob` as multipart
|
|
21
|
+
`encoded_image`. The result contains the redirect URL and original redirect
|
|
22
|
+
status, location header and body. It stops at that redirect and does not load
|
|
23
|
+
results pages. Opening the URL can still require consent, sign-in, or a traffic
|
|
24
|
+
challenge.
|
|
25
|
+
|
|
26
|
+
`width` and `height`, when supplied together, populate the website's optional
|
|
27
|
+
`processed_image_dimensions` field. They should describe the supplied image.
|
|
28
|
+
The client does not resize or inspect image contents. PNG, JPEG, WebP and GIF
|
|
29
|
+
media types are accepted by its interface.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const link = client.searchUrl('https://example.com/public-image.png');
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`searchUrl()` constructs the current shipped upload service's URL-image
|
|
36
|
+
navigation using `/v3/upload?url=...`. This is supported by static source evidence;
|
|
37
|
+
the URL-image path was not separately executed after the observed upload results
|
|
38
|
+
hit a challenge. Building the link performs no upload or request. Google's
|
|
39
|
+
[image-search help](https://support.google.com/websearch/answer/1325808?hl=en)
|
|
40
|
+
describes file upload and image-URL search in the consumer interface.
|
|
41
|
+
|
|
42
|
+
The live investigation used only a synthetic image containing test text. The
|
|
43
|
+
actual file upload returned HTTP 303, then its Google Search destination showed
|
|
44
|
+
an unusual-traffic CAPTCHA. No CAPTCHA was solved, and no OCR or visual-match
|
|
45
|
+
response schema is claimed from that session. The library therefore exposes
|
|
46
|
+
upload/navigation transport, without an unverified recognition parser.
|
|
47
|
+
|
|
48
|
+
Configuration accepts an injected `fetch`, `locale`, and `timeoutMs` (30 seconds
|
|
49
|
+
by default). Upload options accept an `AbortSignal`. `LensError.kind` distinguishes
|
|
50
|
+
`http`, `blocked`, `auth-required`, `rate-limit`, `parse`, `network`, and `timeout`.
|
|
51
|
+
Requests are issued once and redirects to challenge pages are reported explicitly.
|
|
52
|
+
|
|
53
|
+
Run offline tests with `npx vitest run tests/unit/lens`. The media live suite
|
|
54
|
+
covers YouTube; it does not repeat an upload into the observed Lens challenge.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Existing Maps capabilities
|
|
2
|
+
|
|
3
|
+
The Maps implementation predates the additional Google consumer clients.
|
|
4
|
+
This pass reused its source, wire builders, captured fixtures and explicit
|
|
5
|
+
surface-status catalog rather than treating every registered RPC as verified.
|
|
6
|
+
`src/known-surfaces.ts` and `src/platform/catalog.ts` retain the per-surface
|
|
7
|
+
working, partial, authentication and unsupported boundaries.
|
|
8
|
+
|
|
9
|
+
Representative anonymous live checks on 2026-10-29:
|
|
10
|
+
|
|
11
|
+
| Capability | Observed result |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| Reviews | Five-review page plus rating total/aggregate; 20 deduplicated reviews over two further pages |
|
|
14
|
+
| Forward geocoding | HSR Layout resolved to coordinates and its Bengaluru address |
|
|
15
|
+
| Reverse geocoding | Existing HSR fixture coordinates resolved to a Bengaluru address |
|
|
16
|
+
| Driving directions | HSR→Koramangala returned a 14-minute, 4.5km route with one leg and turn instructions |
|
|
17
|
+
| Viewport weather | Populated HSR response returned `28°` and `Sunny`, following an initial metadata stub |
|
|
18
|
+
|
|
19
|
+
These values describe captured checks, not fixed expected travel times or
|
|
20
|
+
weather. The existing core offline suite covers place/search parsers, reviews,
|
|
21
|
+
directions, tiles, photo/panorama formats and auth boundaries. This pass also
|
|
22
|
+
fixed authenticated review fallback cursor propagation and corrected two
|
|
23
|
+
supported environment-API request contracts; see [Reviews](reviews-research.md)
|
|
24
|
+
and [environment access](environment-research.md).
|
|
25
|
+
|
|
26
|
+
The consumer SDK is not full parity with every Maps Platform SKU. In particular,
|
|
27
|
+
keyed enterprise fields, authenticated Ask Maps/history, private lists,
|
|
28
|
+
session-dependent overlays, and endpoints marked unverified retain their
|
|
29
|
+
existing limits. Public Places' five-review cap and the consumer review page
|
|
30
|
+
protocol are separate contracts. Official API prices and credentials remain
|
|
31
|
+
documented in the [service inventory](google-services-research.md).
|
package/docs/news.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Google News public feeds
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { googleNews } from 'googlemaps-kit/news';
|
|
5
|
+
|
|
6
|
+
const news = googleNews({ language: 'en-US', country: 'US' });
|
|
7
|
+
const headlines = await news.headlines();
|
|
8
|
+
const results = await news.search('Google AI');
|
|
9
|
+
for (const article of results.articles) {
|
|
10
|
+
console.log(article.title, article.source?.name, article.publishedAt, article.url);
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The client reads public `/rss` and `/rss/search` feeds without an API key or
|
|
15
|
+
browser. It returns channel metadata, titles, publication times, source names,
|
|
16
|
+
source homepages and article links. Article links remain Google's RSS redirect
|
|
17
|
+
URLs; the client does not claim to decode them into publisher article URLs.
|
|
18
|
+
Descriptions remain HTML strings supplied by the feed. Full articles, arbitrary
|
|
19
|
+
pagination, personalized feeds and a complete news index are outside this API.
|
|
20
|
+
|
|
21
|
+
Configure `fetch`, `timeoutMs`, `language`, `country`, and optional `edition`
|
|
22
|
+
(`US:en`, for example). Each method accepts locale overrides and `signal`.
|
|
23
|
+
Default deadline is 30 seconds including the response body. Errors propagate
|
|
24
|
+
as `GoogleWebError`; no automatic retries occur. XML parsing is limited to the
|
|
25
|
+
observed RSS contract, never evaluates HTML and rejects entity declarations.
|
|
26
|
+
CDATA contents are preserved verbatim, ordinary XML entities are decoded once,
|
|
27
|
+
and comments are ignored. The parser rejects mismatched or truncated elements
|
|
28
|
+
and bounds input to 10 million characters, 50,000 elements and 64 nesting levels.
|
|
29
|
+
|
|
30
|
+
The search feed returned HTTP 200 and valid public data on 2026-10-29. Its
|
|
31
|
+
`hl`, `gl`, `ceid`, and `q` parameters were captured directly. Feed metadata
|
|
32
|
+
includes Google's usage notice; the returned `copyright` field preserves it.
|
|
33
|
+
No general paid Google News query API was established in the official-source
|
|
34
|
+
[service catalog](google-services-research.md). Paid third-party news APIs are
|
|
35
|
+
separate products.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# PageSpeed Insights wire research
|
|
2
|
+
|
|
3
|
+
Investigated on 2026-10-29 against `pagespeed.web.dev`, build
|
|
4
|
+
`boq_chrome-lightbrary-ui_20261027.04_p0`. These are observations of Google's
|
|
5
|
+
public web client, not a claim that undocumented interfaces are stable.
|
|
6
|
+
|
|
7
|
+
## Evidence and verification
|
|
8
|
+
|
|
9
|
+
- Bootstrap HTML exposes `eptZe=/_/PagespeedUi/`, `cfb2h` as the build label,
|
|
10
|
+
`FdrFJe` as the page session identifier, and `pDzS6=3`.
|
|
11
|
+
- Browser network capture observed `nqfuif` with arguments
|
|
12
|
+
`["https://example.com/",3]`; that browser attempt received an automated-query
|
|
13
|
+
HTTP 429 page. Direct HTTP replay subsequently returned a successful creation
|
|
14
|
+
response. A browser failure therefore does not establish that the web RPC is
|
|
15
|
+
unavailable.
|
|
16
|
+
- Successful create, `LsX2he` poll, and `CBayme` get responses were captured.
|
|
17
|
+
Analysis `bidxril0yk` for `https://example.com/` contained six completed
|
|
18
|
+
records: page CrUX, origin CrUX, and Lighthouse for both mobile and desktop.
|
|
19
|
+
The saved analysis page also contained the complete analysis in its server
|
|
20
|
+
preload data (`ds:0`).
|
|
21
|
+
- The public `runPagespeed` endpoint was probed without an API key and returned
|
|
22
|
+
HTTP 429 with `quota_limit_value=0`. This is the observed quota state, not
|
|
23
|
+
evidence that every caller needs a key or that the web RPC shares that quota.
|
|
24
|
+
- Static analysis inspected 25 downloaded scripts, all parsed successfully,
|
|
25
|
+
totaling 257,599 AST nodes. Browser inventory evidence:
|
|
26
|
+
`ev_33511f751b9d5da9383dae0f6f3ad5ac7b56056f11c6fb9ab0b66a8fba60d3b8`.
|
|
27
|
+
Bundle analysis evidence:
|
|
28
|
+
`ev_a9a73ecc0dc732329bf2835d27fe016bb9717d1e528a9d905dbc0885dbfc864e`.
|
|
29
|
+
- Original captures and downloaded bundles remain in the untracked research
|
|
30
|
+
scratch directory. Shipped code and tests must not depend on those files.
|
|
31
|
+
|
|
32
|
+
## Transports and RPCs
|
|
33
|
+
|
|
34
|
+
Web calls POST form-encoded `f.req` to
|
|
35
|
+
`https://pagespeed.web.dev/_/PagespeedUi/data/batchexecute`. The observed request
|
|
36
|
+
used `rpcids`, `source-path=/analysis`, `f.sid`, `bl`, `hl`, `_reqid`, and `rt=c`.
|
|
37
|
+
Its body was `[[[rpcid, JSON.stringify(args), null, "generic"]]]` under `f.req`;
|
|
38
|
+
the observed anonymous create omitted `at`. Responses use Google's XSSI prefix,
|
|
39
|
+
length-framed JSON, and `wrb.fr` records containing JSON-encoded payloads.
|
|
40
|
+
|
|
41
|
+
| RPC | Purpose | Request arguments | Response | Evidence |
|
|
42
|
+
| --- | --- | --- | --- | --- |
|
|
43
|
+
| `nqfuif` | Create analysis | `[url, context, null, useOriginalUrl]`; trailing defaults can be omitted | Field 1 contains Analysis | Builder and successful live response |
|
|
44
|
+
| `CBayme` | Get saved analysis | `[analysisId]` | Analysis directly | Explicit `/Pagespeed.GetAnalysis` descriptor and successful live response |
|
|
45
|
+
| `LsX2he` | Refresh pending records | `[analysisId, [recordId, ...]]` | Field 1 is repeated Result | Polling code and successful live response |
|
|
46
|
+
| `deISwc` | Legacy report preparation; URL resolution is an inference | `[url, null, formFactor]` | Observed `[url, url]`; response getter reads field 2 as string | Legacy `/report` builder and live probe; no complete semantic descriptor |
|
|
47
|
+
| `zKzUAb` | Unknown | Unknown | Unknown | Descriptor only; request class `dIqFbe`, response `CAV36d`; no caller or field accesses found |
|
|
48
|
+
|
|
49
|
+
The create context comes from `WIZ_global_data.pDzS6`, observed as `3`. Its
|
|
50
|
+
semantic enum name is unknown. It must not be interpreted as mobile or desktop:
|
|
51
|
+
the successful creation produced both form factors. Static create code attaches
|
|
52
|
+
`X-Rawurl: <url>` and places the `use_original_url` boolean in field 4.
|
|
53
|
+
|
|
54
|
+
The official API is a separate JSON transport:
|
|
55
|
+
`GET https://www.googleapis.com/pagespeedonline/v5/runPagespeed`. Its options
|
|
56
|
+
and quota behavior must not be inferred from the web client's positional RPCs.
|
|
57
|
+
|
|
58
|
+
## Analysis and result layouts
|
|
59
|
+
|
|
60
|
+
Field numbers below are one-based protobuf field numbers; ordinary JSON array
|
|
61
|
+
indices are one less. This distinction matters when writing parsers.
|
|
62
|
+
|
|
63
|
+
| Analysis field | Meaning |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| 1 | Saved analysis ID |
|
|
66
|
+
| 2 | Analysis URL |
|
|
67
|
+
| 3 | Status; `1` initiates polling, `2` observed for completed analysis |
|
|
68
|
+
| 4 | Opaque context/location value; observed `3`, forwarded to the Lighthouse renderer |
|
|
69
|
+
| 5 | Repeated Result records |
|
|
70
|
+
| 6 | Map entries `[formFactor, originalUrl]`, used for redirect comparison |
|
|
71
|
+
| 7 | Timestamp `[seconds, nanos]`, displayed as the report creation time |
|
|
72
|
+
|
|
73
|
+
| Result field | Meaning |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| 1 | Original subject URL |
|
|
76
|
+
| 2 | Resolved/final subject URL; origin records omit the trailing slash |
|
|
77
|
+
| 3 | Form factor: `1` mobile, `2` desktop |
|
|
78
|
+
| 4 | Kind: `1` Lighthouse, `2` origin CrUX, `3` page CrUX |
|
|
79
|
+
| 5 | Unidentified data alternative; not exercised in the successful capture |
|
|
80
|
+
| 6 | CrUX record; mutually exclusive with fields 5 and 10 |
|
|
81
|
+
| 7 | Status: `1` pending, `2` complete |
|
|
82
|
+
| 8 | Error/status message; code field 1, message field 2 |
|
|
83
|
+
| 9 | Record ID used by polling and cache replacement |
|
|
84
|
+
| 10 | Lighthouse result serialized as a JSON string |
|
|
85
|
+
|
|
86
|
+
The UI polls every 3,000 ms, requesting only records whose status is `1`, and
|
|
87
|
+
replaces records by ID. It stops when none are pending. A completed record can
|
|
88
|
+
carry an error; completion does not imply successful Lighthouse or CrUX data.
|
|
89
|
+
The UI recognizes error code `5` as missing CrUX data. Redirect handling compares
|
|
90
|
+
the original and final URL's origin plus pathname, ignoring query and fragment.
|
|
91
|
+
|
|
92
|
+
Saved links use `/analysis/<analysisId>` or
|
|
93
|
+
`/analysis/<sanitizedUrl>/<analysisId>`, optionally with `form_factor=mobile` or
|
|
94
|
+
`form_factor=desktop`. The sanitized URL is decorative: retrieval uses the ID.
|
|
95
|
+
The UI removes the `url` query parameter after creation and retains the ID.
|
|
96
|
+
|
|
97
|
+
## CrUX layout and units
|
|
98
|
+
|
|
99
|
+
For `crux = result[5]` using zero-based JavaScript indices:
|
|
100
|
+
|
|
101
|
+
- `crux[0][0]` is the record key. Index 0 holds an origin URL; index 4 holds a
|
|
102
|
+
page URL. Index 2 is the CrUX device enum: `2` PHONE and `1` DESKTOP in the
|
|
103
|
+
successful capture. This is the reverse of the outer Result form-factor enum.
|
|
104
|
+
- `crux[1]` contains entries `[metricName, metricValue]`.
|
|
105
|
+
- For the observed numeric metrics, `distribution = metricValue[1]`.
|
|
106
|
+
`distribution[0][0]` contains histogram bins;
|
|
107
|
+
`distribution[1][0]` contains the 75th-percentile typed value.
|
|
108
|
+
- Each bin is `[typedStart, typedEndOrNull, density]`. A missing upper bound
|
|
109
|
+
denotes the final open-ended bin. Densities are fractions, not percentages.
|
|
110
|
+
- Typed values contain numeric milliseconds at index 1, or decimal strings at
|
|
111
|
+
index 2 for dimensionless CLS values. Preserve numeric zero.
|
|
112
|
+
- `crux[3]` is the collection period:
|
|
113
|
+
`[[startYear,startMonth,startDay],[endYear,endMonth,endDay]]`, with one-based
|
|
114
|
+
months. The successful capture covered 2026-09-30 through 2026-10-27.
|
|
115
|
+
|
|
116
|
+
Metrics can omit histograms while retaining a percentile, as observed for the
|
|
117
|
+
LCP image subparts. Entries can also have `null` values, as observed for
|
|
118
|
+
`navigation_types` and `largest_contentful_paint_resource_type`. Unknown metric
|
|
119
|
+
names and raw values should survive parsing; do not assume every entry has
|
|
120
|
+
three bins or a percentile.
|
|
121
|
+
|
|
122
|
+
The bootstrap metric configuration supplied these thresholds:
|
|
123
|
+
|
|
124
|
+
| Metric | UI enum | Good upper bound | Needs-improvement upper bound | Unit |
|
|
125
|
+
| --- | --- | --- | --- | --- |
|
|
126
|
+
| `largest_contentful_paint` | 1 | 2500 | 4000 | ms |
|
|
127
|
+
| `first_contentful_paint` | 2 | 1800 | 3000 | ms |
|
|
128
|
+
| `cumulative_layout_shift` | 3 | 0.10 | 0.25 | unitless |
|
|
129
|
+
| `experimental_time_to_first_byte` | 10 | 800 | 1800 | ms |
|
|
130
|
+
| `interaction_to_next_paint` | 11 | 200 | 500 | ms |
|
|
131
|
+
|
|
132
|
+
Static UI code includes metrics in the Core Web Vitals assessment only when
|
|
133
|
+
they have three histogram bins and a numeric or decimal percentile. It marks
|
|
134
|
+
the assessment unavailable if LCP or CLS is missing. It passes when their
|
|
135
|
+
percentiles are within the good thresholds and INP is also good when present;
|
|
136
|
+
missing INP alone does not fail the assessment. Good and needs-improvement
|
|
137
|
+
upper bounds are inclusive in the UI's percentile-based rating code.
|
|
138
|
+
|
|
139
|
+
## Lighthouse and remaining limits
|
|
140
|
+
|
|
141
|
+
Both successful Lighthouse records used Lighthouse 13.5.0, contained 159 audits,
|
|
142
|
+
and included all of `performance`,
|
|
143
|
+
`accessibility`, `best-practices`, `seo`, and `agentic-browsing`. Preserve the full
|
|
144
|
+
Lighthouse JSON, dynamic audit/category names, screenshots, warnings,
|
|
145
|
+
configuration, environment, and timings rather than hard-coding four categories.
|
|
146
|
+
Scores use the original 0–1 representation.
|
|
147
|
+
|
|
148
|
+
Unknowns remain explicit: the semantic name of the create context enum, the
|
|
149
|
+
field-5 Result alternative, the purpose and arguments of `zKzUAb`, all enum
|
|
150
|
+
values not exercised here, and the complete semantics of legacy `deISwc`.
|
|
151
|
+
Descriptor registration alone does not establish a working endpoint. No claim
|
|
152
|
+
is made that automated-query blocking, quotas, or saved-report retention are
|
|
153
|
+
constant across networks, sessions, or future builds.
|