googlemaps-kit 0.5.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 +56 -3
- package/dist/advanced/parsers.d.ts +1 -1
- package/dist/advanced/parsers.d.ts.map +1 -1
- package/dist/advanced/parsers.js +1 -1
- package/dist/advanced/parsers.js.map +1 -1
- package/dist/advanced.d.ts +2 -2
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js.map +1 -1
- 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/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +9 -11
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/tui/app.d.ts.map +1 -1
- package/dist/cli/tui/app.js +7 -7
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli.js +14 -11
- package/dist/cli.js.map +1 -1
- package/dist/client/gmaps-client.d.ts +7 -29
- package/dist/client/gmaps-client.d.ts.map +1 -1
- package/dist/client/gmaps-client.js +15 -131
- package/dist/client/gmaps-client.js.map +1 -1
- 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/intent.d.ts +1 -11
- package/dist/client/intent.d.ts.map +1 -1
- package/dist/client/intent.js +17 -13
- package/dist/client/intent.js.map +1 -1
- package/dist/client/maps-tools.d.ts +8 -4
- package/dist/client/maps-tools.d.ts.map +1 -1
- package/dist/client/maps-tools.js +20 -11
- package/dist/client/maps-tools.js.map +1 -1
- package/dist/client/namespaces.d.ts +51 -19
- package/dist/client/namespaces.d.ts.map +1 -1
- package/dist/client/namespaces.js +82 -28
- package/dist/client/namespaces.js.map +1 -1
- package/dist/client/place-workflows.d.ts +7 -0
- package/dist/client/place-workflows.d.ts.map +1 -0
- package/dist/client/place-workflows.js +113 -0
- package/dist/client/place-workflows.js.map +1 -0
- 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 +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/known-surfaces.d.ts +35 -5
- package/dist/known-surfaces.d.ts.map +1 -1
- package/dist/known-surfaces.js +35 -5
- 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/parsers/geocode.d.ts.map +1 -1
- package/dist/parsers/geocode.js +30 -1
- package/dist/parsers/geocode.js.map +1 -1
- package/dist/parsers/reviews.d.ts +8 -1
- package/dist/parsers/reviews.d.ts.map +1 -1
- package/dist/parsers/reviews.js +46 -9
- package/dist/parsers/reviews.js.map +1 -1
- package/dist/platform/catalog.d.ts +18 -0
- package/dist/platform/catalog.d.ts.map +1 -0
- package/dist/platform/catalog.js +320 -0
- package/dist/platform/catalog.js.map +1 -0
- package/dist/platform/parity.d.ts +12 -0
- package/dist/platform/parity.d.ts.map +1 -0
- package/dist/platform/parity.js +25 -0
- package/dist/platform/parity.js.map +1 -0
- package/dist/services/elevation.d.ts +6 -4
- package/dist/services/elevation.d.ts.map +1 -1
- package/dist/services/elevation.js +39 -4
- package/dist/services/elevation.js.map +1 -1
- package/dist/services/environment/air-quality.d.ts +39 -0
- package/dist/services/environment/air-quality.d.ts.map +1 -0
- package/dist/services/environment/air-quality.js +82 -0
- package/dist/services/environment/air-quality.js.map +1 -0
- package/dist/services/environment/weather.d.ts +42 -0
- package/dist/services/environment/weather.d.ts.map +1 -0
- package/dist/services/environment/weather.js +63 -0
- package/dist/services/environment/weather.js.map +1 -0
- package/dist/services/geocode.d.ts +5 -1
- package/dist/services/geocode.d.ts.map +1 -1
- package/dist/services/geocode.js +13 -0
- package/dist/services/geocode.js.map +1 -1
- package/dist/services/keyed.d.ts +80 -0
- package/dist/services/keyed.d.ts.map +1 -0
- package/dist/services/keyed.js +152 -0
- package/dist/services/keyed.js.map +1 -0
- package/dist/services/knowledge.d.ts +6 -2
- package/dist/services/knowledge.d.ts.map +1 -1
- package/dist/services/knowledge.js +30 -5
- package/dist/services/knowledge.js.map +1 -1
- package/dist/services/mobility.d.ts.map +1 -1
- package/dist/services/mobility.js +13 -2
- package/dist/services/mobility.js.map +1 -1
- package/dist/services/nearby-search.d.ts +32 -0
- package/dist/services/nearby-search.d.ts.map +1 -0
- package/dist/services/nearby-search.js +85 -0
- package/dist/services/nearby-search.js.map +1 -0
- package/dist/services/panorama.d.ts +8 -1
- package/dist/services/panorama.d.ts.map +1 -1
- package/dist/services/panorama.js +48 -0
- package/dist/services/panorama.js.map +1 -1
- package/dist/services/photos.d.ts.map +1 -1
- package/dist/services/photos.js +9 -2
- package/dist/services/photos.js.map +1 -1
- package/dist/services/places.d.ts.map +1 -1
- package/dist/services/places.js +1 -0
- package/dist/services/places.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/services/search.d.ts +8 -3
- package/dist/services/search.d.ts.map +1 -1
- package/dist/services/search.js +28 -9
- package/dist/services/search.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 +28 -2
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js.map +1 -1
- package/dist/types/directions.d.ts +1 -1
- package/dist/types/directions.d.ts.map +1 -1
- package/dist/types/dx.d.ts +23 -10
- package/dist/types/dx.d.ts.map +1 -1
- package/dist/types/panorama.d.ts +19 -0
- package/dist/types/panorama.d.ts.map +1 -1
- package/dist/types/reviews.d.ts +3 -4
- package/dist/types/reviews.d.ts.map +1 -1
- package/dist/types/suggest.d.ts +4 -6
- package/dist/types/suggest.d.ts.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/utils/place-ref.d.ts +14 -4
- package/dist/utils/place-ref.d.ts.map +1 -1
- package/dist/utils/place-ref.js +49 -1
- package/dist/utils/place-ref.js.map +1 -1
- 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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Gemini consumer web interface
|
|
2
|
+
|
|
3
|
+
Anonymous browser generation actually returned two marker answers during research on October 29, 2026. HTTP bootstrap alone does not establish that generation works. This module keeps the two operations separate.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { geminiWeb } from 'googlemaps-kit/gemini-web';
|
|
7
|
+
|
|
8
|
+
const metadata = await geminiWeb().inspect();
|
|
9
|
+
console.log(metadata.build, metadata.generation); // generation: 'unverified'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`inspect()` fetches the public app HTML and reports its build plus the presence of anonymous session/prompt-token fields. It does not expose token values or generate an answer.
|
|
13
|
+
|
|
14
|
+
## Actual generation through a browser
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { geminiWeb } from 'googlemaps-kit/gemini-web';
|
|
18
|
+
|
|
19
|
+
const client = geminiWeb({ page });
|
|
20
|
+
const answer = await client.generate('Explain a binary search in two sentences.');
|
|
21
|
+
console.log(answer.text, answer.conversationUrl);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`page` is a caller-owned browser Page implementing the exported `GeminiBrowserPage` subset: `url`, `goto`, `content`, and the needed locator methods. A normal Playwright Page implements this interface. No browser package is bundled or required by the package's other methods; the caller supplies and closes its own browser. Use a fresh anonymous context to reproduce the research environment.
|
|
25
|
+
|
|
26
|
+
`generate()` navigates that page to Gemini if necessary, fills the observed text composer and submits with Enter. It uses the page's existing conversation. It returns only after a **new**, prompt-matched model response has nonempty text, `aria-busy="false"`, and the observed completed-response footer. Existing answers, echoed prompts and incomplete responses cannot satisfy the wait. Output is visible plain text with paragraph boundaries, not the original Markdown source. Generation requires this browser adapter; no HTTP-only generation method is claimed.
|
|
27
|
+
|
|
28
|
+
The current anonymous app used `geminiweb-pa.clients6.google.com/v1/processSession` with browser WebChannel/protobuf traffic. Its generation request contained a browser anti-abuse token. The SDK lets the genuine website perform that protocol; it does not manufacture, harvest or replay browser tokens, cookies or account credentials.
|
|
29
|
+
|
|
30
|
+
Configuration accepts `page`, `fetch`, `timeoutMs` (90 seconds by default) and `pollIntervalMs` (500 ms). `generate(prompt, { signal?, timeoutMs? })` supports caller cancellation and an overall deadline. Cancellation stops the SDK's wait and prevents subsequent submission steps; a prompt already submitted to the website may continue generating. Concurrent generations through one client are rejected so responses cannot be mixed. No automatic retries or model-selection options are implemented.
|
|
31
|
+
|
|
32
|
+
Only ordinary anonymous text generation and its observed DOM are verified. Availability varies by device, region and Google policy. Sign-in, consent or access challenges are surfaced. Images, files, connected apps, account history, saved state, paid plans, model identity and API-equivalent quotas are not established by this interface. The app's displayed `Flash-Lite` label is an observation, not a verified model-version guarantee.
|
|
33
|
+
|
|
34
|
+
Google's [Gemini Apps help](https://support.google.com/gemini/answer/13275745?hl=en) describes limited signed-out text features. This consumer website is separate from Google's supported developer Gemini API and its billing. See the [research ledger](./google-ai-books-research.md) for runtime evidence and limitations.
|
|
35
|
+
|
|
36
|
+
Offline tests run with `npx vitest run tests/unit/gemini-web`. Optional network probes are in `tests/live/google-ai-books.test.ts`; set `GMAPS_LIVE=1 GOOGLE_AI_BOOKS_LIVE=1` and run that file explicitly. The browser-generation case additionally requires `GEMINI_PLAYWRIGHT_MODULE` (an installed Playwright module path) and `GEMINI_BROWSER_EXECUTABLE` (the browser executable path). Without them, only Books metadata and Gemini bootstrap are probed.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Gemini, Books, Ads Keyword Planner and Search Console
|
|
2
|
+
|
|
3
|
+
Observed October 29, 2026. Each service has its own evidence boundary. All probes used anonymous public requests or a new browser context. No account credentials, cookies, paid entitlements or existing user sessions were read. Ads probes were read-only; no campaigns, budgets or account settings were changed.
|
|
4
|
+
|
|
5
|
+
## Gemini consumer web
|
|
6
|
+
|
|
7
|
+
| Question | Observed evidence | Outcome |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Is HTTP bootstrap available? | `gemini.google.com/app?hl=en` returned HTTP 200 with current `WIZ_global_data` build/session metadata and no `SNlM0e` field. | Bootstrap implemented; generation remains unverified from this alone. |
|
|
10
|
+
| Is signed-out browser text generation allowed here? | A fresh Chromium 156 context displayed a composer and returned `GEMINI_PUBLIC_PROBE_20261029` and `GEMINI_PROTOCOL_PROBE_20261029` for the two synthetic echo prompts. | Actual anonymous generation observed. |
|
|
11
|
+
| Which current transport is used? | Browser resource and request capture showed `geminiweb-pa.clients6.google.com/v1/processSession`, WebChannel framing and base64/protobuf request data. The generation request included a long browser anti-abuse token. | Transport shape observed; token algorithm, full schema and a working plain-HTTP replay remain unresolved. No token evasion is implemented. |
|
|
12
|
+
| Which DOM identifies completed answers? | `model-response` → `message-content` → `.markdown[aria-busy="false"]`, accompanied by `.response-footer.complete`. User echoes live in separate `user-query` containers. | Verified parser and caller-owned browser adapter implemented. |
|
|
13
|
+
| Does the implemented SDK work beyond inspection? | A separate fresh browser run through `geminiWeb({ page }).generate(...)` returned exactly `GEMINI_SDK_PROBE_20261029`, with a response ID. | Actual SDK generation verified. |
|
|
14
|
+
|
|
15
|
+
REA inventory evidence: `ev_936d2cf1a5b355fb214a409714f31613616df92589bf54e8cad669a0f76d9c9f`. Initial bundle evidence, limited to the app and the general gstatic origin: `ev_3691a13b7b3097660d166432bbacd1c80690ce95955d379af515a3122df11cff` (16 scripts). Expanded evidence including the actually observed `gemini.gstatic.com` origin: `ev_6f400a58e6634b7ace918f4215cffd6c7609bb4625625dbc155b5e608d3a517a` (68 scripts, 3,766,371 AST nodes, no parse failures). The latter resolves the original incomplete CDN boundary.
|
|
16
|
+
|
|
17
|
+
REA statically analyzes captured source; it does not execute it or prove every function ran. Generation was separately observed through real page interaction and model-response DOM. Server-side internals, uncaptured dynamic behavior, signed-in features and underlying model versions remain unknown. Sanitized executed DOM and bootstrap fixture provenance is recorded in `tests/fixtures/gemini-web/README.md`; neither fixture retains account data or anti-abuse tokens.
|
|
18
|
+
|
|
19
|
+
Google's [Gemini Apps help](https://support.google.com/gemini/answer/13275745?hl=en) documents that some signed-out text interactions are available, subject to device and location. These observations do not establish unlimited use, developer API equivalence, paid-model access, image generation, account history or connected-app permissions.
|
|
20
|
+
|
|
21
|
+
## Google Books
|
|
22
|
+
|
|
23
|
+
| Surface | Actual outcome | Implementation |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| Books v1 `volumes?q=isbn:9780131103627&maxResults=1` | HTTP 429, query quota exceeded for Google's default consumer project. | No successful v1 search client claimed. |
|
|
26
|
+
| Books v1 `volumes/zyTCAlFPjgYC` | Same HTTP 429 quota denial. | No successful v1 retrieval client claimed. |
|
|
27
|
+
| Public `books.google.com/books?id=zyTCAlFPjgYC&hl=en` | HTTP 200 with a regional redirect to books.google.co.in; OpenGraph metadata and an English bibliographic table contained title, two authors, publisher/year, edition, two ISBNs and 384-page length. | Bounded metadata-by-volume-ID client and actual sanitized fixture implemented. |
|
|
28
|
+
|
|
29
|
+
Google's [Books v1 guide](https://developers.google.com/books/docs/v1/using) documents public metadata search/get, API keys, and separately authorized library operations. Documentation of those methods is not evidence that the unauthenticated calls succeeded here. The [Dynamic Links guide](https://developers.google.com/books/docs/dynamic-links) describes preview/viewability links but specifically says its geography-dependent interface is not designed for server-side or offline queries; that surface was not repurposed as a server metadata service.
|
|
30
|
+
|
|
31
|
+
No scanned pages, preview content, full text, purchases or paywalled material were requested. Current implementation is public bibliographic metadata only; query search and broader Books API parity remain unresolved. Fixture provenance is in `tests/fixtures/books/README.md`.
|
|
32
|
+
|
|
33
|
+
## Ads Keyword Planner
|
|
34
|
+
|
|
35
|
+
| Boundary | Actual evidence | Outcome |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| Consumer UI | `ads.google.com/aw/keywordplanner/home?hl=en` redirected to `accounts.google.com/v3/signin/identifier`, titled Google Ads sign-in. | No anonymous keyword metrics observed. |
|
|
38
|
+
| Read-only Ads API | `googleads.googleapis.com/v26/customers:listAccessibleCustomers` returned HTTP 401 missing authentication. | No account data retrieved and no mutation attempted. |
|
|
39
|
+
| Documented feature mapping | Google's keyword planning docs map keyword ideas, historical metrics and forecasts to `KeywordPlanIdeaService`. | Documented capability, not an executed anonymous equivalent. |
|
|
40
|
+
|
|
41
|
+
The current [access-level policy](https://developers.google.com/google-ads/api/docs/api-policy/access-levels) says developer tokens were sunset on September 9, 2026 and access is managed per Google Cloud project. Its Explorer restrictions explicitly include KeywordPlanIdeaService, so planning requires an appropriate higher access level. Some older generated summaries on Google's OAuth/header pages still mention developer tokens; those summaries are not treated as overriding the newer policy body.
|
|
42
|
+
|
|
43
|
+
[Google Ads authorization](https://developers.google.com/google-ads/api/rest/auth) requires OAuth with `https://www.googleapis.com/auth/adwords`, appropriate customer access, and a manager login-customer-id where applicable. The [keyword planning guide](https://developers.google.com/google-ads/api/docs/keyword-planning/overview) describes the supported operations and tighter rate limits. No authorized planning request, account billing behavior or keyword metric response was executed. No fake anonymous metrics or paid-service replacement is implemented.
|
|
44
|
+
|
|
45
|
+
## Search Console
|
|
46
|
+
|
|
47
|
+
| Boundary | Actual evidence | Outcome |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| Public UI entry | `search.google.com/search-console?hl=en` returned its public `/search-console/about` page. | Public marketing entry, not property analytics. |
|
|
50
|
+
| Read-only property list | `www.googleapis.com/webmasters/v3/sites` returned HTTP 401 missing authentication. | No private properties, analytics or URL Inspection data retrieved. |
|
|
51
|
+
| Documented authorization | OAuth token plus appropriate property access; readonly scope is `https://www.googleapis.com/auth/webmasters.readonly`, read/write scope is `https://www.googleapis.com/auth/webmasters`. | Access boundary established, not anonymously bypassed. |
|
|
52
|
+
|
|
53
|
+
Google's [authorization guide](https://developers.google.com/webmaster-tools/v1/how-tos/authorizing) requires authenticated requests, and its [overview](https://developers.google.com/webmaster-tools/about) requires appropriate owner/full/read access to managed properties. Public page checks and private Search Console analytics are distinct. No credential flow, property ownership verification, account data extraction or account mutation was performed. Authorized API execution remains unverified and no anonymous equivalent is claimed.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# YouTube and Lens investigation
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-29. Scope: anonymous consumer metadata and search surfaces, plus a
|
|
4
|
+
Lens upload using a synthetic image. No account, subscription, age restriction,
|
|
5
|
+
CAPTCHA, or protected-media gate was bypassed. Browser interception aborted media
|
|
6
|
+
resources, googlevideo hosts and videoplayback paths before they downloaded
|
|
7
|
+
content.
|
|
8
|
+
|
|
9
|
+
## Findings
|
|
10
|
+
|
|
11
|
+
| ID | Evidence and result | Implementation and boundary |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| YM-01 | Direct watch HTML HTTP 200 for `bC8fvcpocBU`; inline `ytInitialPlayerResponse` had OK playability, metadata, microformat and caption-track records. | `video()` normalizes public metadata and keeps the raw player/initial payloads. It does not request streams. |
|
|
14
|
+
| YM-02 | Direct watch HTML for `dQw4w9WgXc` contained ERROR playability with an unavailable reason; its oEmbed request returned 400. | Restricted/unavailable player states are preserved. No attempt was made to restore access. |
|
|
15
|
+
| YM-03 | Direct `/results?search_query=Google+for+Developers` returned HTTP 200 with `ytInitialData`, classic video/channel renderers, and an opaque continuation. | `search()` parses retained result renderers and anonymous client context. |
|
|
16
|
+
| YM-04 | POST `/youtubei/v1/search?prettyPrint=false` returned HTTP 200 using the discovered continuation and a minimal `context.client`; no fixed key was required. The SDK live continuation test also passed. | `continueSearch()` sends the opaque token and page-provided version/context. Version, language, region and optional visitor data are retained; unrelated client fingerprint fields are omitted. |
|
|
17
|
+
| YM-05 | Direct `/oembed?url=...&format=json` for `bC8fvcpocBU` returned HTTP 200. | `oembed()` returns the complete typed provider object. |
|
|
18
|
+
| YM-06 | A separate public `Google Developers playlist` query returned HTTP 200 with `lockupViewModel`, content type PLAYLIST, collection thumbnails and byline metadata. The legacy `playlistRenderer` was absent. | Current observed playlist lockups are normalized; unobserved legacy playlist renderers are not claimed. |
|
|
19
|
+
| YM-07 | An advertised `/api/timedtext` URL returned HTTP 200 with zero bytes, as did the browser's caption request. | Caption-track metadata is exposed; transcript content is unresolved. Empty content is not treated as proof that captions do not exist. |
|
|
20
|
+
| LM-01 | A Google Images file chooser uploaded a locally created 600x200 PNG with synthetic test text. `/v3/upload?ep=gsbubb...` returned 303 to a Google Search Lens session. | `createSearch()` reproduces multipart transport and returns the issued redirect without loading recognition results. |
|
|
21
|
+
| LM-02 | The resulting Google Search page displayed an unusual-traffic CAPTCHA. | OCR and visual-match schemas remain unverified. Collection stopped at the gate. |
|
|
22
|
+
| LM-03 | Shipped Google Images module UEShwc constructs `/v3/upload`, multipart `encoded_image`, optional `processed_image_dimensions`, file entry point `gsbubb`, URL entry point `gsbubu`, locale, timestamp and viewport parameters. URL images use GET navigation. | Source-derived request and navigation builders are implemented. The URL-image route was not separately exercised. |
|
|
23
|
+
|
|
24
|
+
The official public test video used for successful metadata is Google's own
|
|
25
|
+
[Introducing Google for Developers!](https://www.youtube.com/watch?v=bC8fvcpocBU).
|
|
26
|
+
No video content was downloaded. Fixture descriptions and metadata are retained
|
|
27
|
+
only as necessary for protocol tests.
|
|
28
|
+
|
|
29
|
+
## REA and artifact identity
|
|
30
|
+
|
|
31
|
+
REA analyzed the exact extracted `var ytInitialPlayerResponse = ...` bootstrap
|
|
32
|
+
statement from the successful watch capture as inert JavaScript. Evidence:
|
|
33
|
+
`ev_4c02a4dbd1187f08caba6500b96a4390b215548332b51c130d5ed6fbb7ff9517`.
|
|
34
|
+
The isolated artifact had three graph nodes and complete parsing of that
|
|
35
|
+
statement. This establishes source structure; successful direct HTTP captures
|
|
36
|
+
and the three live SDK tests establish the observed request behavior.
|
|
37
|
+
|
|
38
|
+
For Lens, the observed parent Images script SHA-256 is
|
|
39
|
+
`dc26401f442b86fe1bda52a406505c98e36c9da00fa22642b8dce1d30e2a0d0a`.
|
|
40
|
+
The isolated UEShwc module consists of its first 4,409 source bytes plus the
|
|
41
|
+
original wrapper's closing statement, so it can be parsed independently. REA
|
|
42
|
+
produced evidence
|
|
43
|
+
`ev_17fc2f463bcf07230fa3dfe55975fec04dabac969e31f4efc4fd8437f54063fa`,
|
|
44
|
+
with six graph nodes. It did not execute Google's code or establish that every
|
|
45
|
+
optional mode is available. An attempt to analyze the entire parent script
|
|
46
|
+
exceeded the tool transport limit; conclusions use the focused module instead.
|
|
47
|
+
|
|
48
|
+
REA target discovery evidence
|
|
49
|
+
`ev_2ae58e65ef2494e0cb89c4f859870bf38b4be9067ff20c81523c151252239c09`
|
|
50
|
+
identified the own-launched Google Images page. A passive navigation observation,
|
|
51
|
+
`ev_c6bfab5b5d7ccd686e75a9d28e13406addc88cf9952b3f1db2effd2088132b43`,
|
|
52
|
+
ended when that first browser was closed and did not capture the later upload.
|
|
53
|
+
It is not used as upload evidence. The controlled browser's saved network
|
|
54
|
+
records and the subsequent source inspection supply LM-01 through LM-03.
|
|
55
|
+
|
|
56
|
+
## Parsing and protocol scope
|
|
57
|
+
|
|
58
|
+
YouTube bootstrap extraction balances JSON object braces while respecting string
|
|
59
|
+
escapes and uses JSON.parse; no page JavaScript is evaluated by the SDK. Search
|
|
60
|
+
normalization is restricted to observed main-result and continuation containers,
|
|
61
|
+
with explicit advertising containers excluded. Unknown renderer/data variants
|
|
62
|
+
remain available in raw payloads. Display counts and relative dates remain text,
|
|
63
|
+
so localization is not mistaken for a precise numeric value.
|
|
64
|
+
|
|
65
|
+
The continuation body uses the discovered token and client name/version from
|
|
66
|
+
`ytcfg.set(...).INNERTUBE_CONTEXT.client`, plus available locale/region/visitor
|
|
67
|
+
fields. Its WEB header uses client number 1, as the captured page configuration
|
|
68
|
+
specified. It is an anonymous consumer protocol, not the documented YouTube
|
|
69
|
+
Data API. No hardcoded page API key or credential is shipped.
|
|
70
|
+
|
|
71
|
+
Lens request construction comes from the shipped upload module and the
|
|
72
|
+
successful browser upload. Its fixed viewport values are SDK choices for the
|
|
73
|
+
transport, rather than a claim about a caller's actual device. No image resize,
|
|
74
|
+
OCR geometry, visual-match, product-match, or AI overview schema is inferred
|
|
75
|
+
from the challenged results page.
|
|
76
|
+
|
|
77
|
+
## Coverage checklist
|
|
78
|
+
|
|
79
|
+
| Surface | Status |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| YouTube public watch metadata and playability | Observed and implemented. |
|
|
82
|
+
| YouTube search and anonymous continuation | Observed, implemented and live-tested. |
|
|
83
|
+
| YouTube video/channel search renderers and current playlist lockups | Observed and implemented. |
|
|
84
|
+
| YouTube oEmbed | Observed, implemented and live-tested. |
|
|
85
|
+
| YouTube caption track metadata | Observed and implemented. |
|
|
86
|
+
| YouTube transcript content | Unresolved: empty timed-text responses. |
|
|
87
|
+
| YouTube protected media, signature decoding, account-only operations | Outside this public metadata implementation. |
|
|
88
|
+
| Lens file upload and issued results redirect | Observed; transport implemented. |
|
|
89
|
+
| Lens URL-image navigation construction | Static evidence; builder implemented. |
|
|
90
|
+
| Lens OCR, visual matches, and result-page parsing | Unresolved behind the observed traffic challenge. |
|
|
91
|
+
|
|
92
|
+
[Google Lens image-search help](https://support.google.com/websearch/answer/1325808?hl=en)
|
|
93
|
+
describes public file and URL workflows. [YouTube embed help](https://support.google.com/youtube/answer/171780?hl=en)
|
|
94
|
+
describes consumer embedding. These sources describe product behavior; the
|
|
95
|
+
request and response contracts above come from the captured consumer surfaces.
|
|
96
|
+
|
|
97
|
+
## Verification
|
|
98
|
+
|
|
99
|
+
`npx vitest run tests/unit/youtube tests/unit/lens` verifies offline parser,
|
|
100
|
+
request-construction, raw-preservation and failure behavior. The opt-in command
|
|
101
|
+
`GMAPS_LIVE=1 npx vitest run tests/live/google-media.test.ts` passed watch metadata,
|
|
102
|
+
oEmbed, and initial search plus continuation. The Lens live upload was performed
|
|
103
|
+
once through the ordinary browser with the synthetic image and stopped at its
|
|
104
|
+
results challenge. Mocked redirect tests do not claim a successful recognition
|
|
105
|
+
response.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Google Search research ledger
|
|
2
|
+
|
|
3
|
+
Observed October 29, 2026. Scope: anonymous public Search HTML, autocomplete, organic links/snippets, related questions/searches, and actual Google AI Overviews. No signed-in account, proxy, CAPTCHA solution or alternate-IP mechanism was used.
|
|
4
|
+
|
|
5
|
+
## Findings
|
|
6
|
+
|
|
7
|
+
| Question | Observation | Status |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Can anonymous autocomplete return structured suggestions? | `suggestqueries.google.com/complete/search?client=firefox&q=typescript&hl=en` returned HTTP 200 and a JSON tuple containing the original query, ten suggestion strings, and subtype metadata. | Observed; implemented and live tested. |
|
|
10
|
+
| Does plain Node fetch return Search results? | `www.google.com/search?q=what+is+typescript&hl=en&gl=us` returned HTTP 200, a JavaScript retry/enable-JavaScript interstitial, no `h3` result titles and no recognized result container. | Observed; explicitly classified. |
|
|
11
|
+
| Does normal browser execution resolve that page? | Unmodified headless Chromium 156 executed the page and followed a 302 redirect to `/sorry/index`. The final HTTP 200 page reported unusual traffic and displayed reCAPTCHA, with no result titles. | Observed; explicitly classified. |
|
|
12
|
+
| Can organic titles, URLs and snippets be extracted from current Search markup? | No successful result page was obtained in this environment. A bounded parser handles linked `h3` titles under `#search`/`#rso`, common snippet containers, and basic link decoding. | Experimental structural implementation; current live markup unverified. |
|
|
13
|
+
| Can actual AI Overview text and sources be retrieved? | No overview was returned before the access challenge. The parser supports explicitly labeled semantic regions without generating any content. No private overview request format was established. | Unresolved; no claim of live retrieval or absence. |
|
|
14
|
+
| Can related questions be expanded or fetched separately? | The blocked result page exposed no usable question expansion flow. Only explicitly labeled supplied HTML is parsed. | Expansion protocol unresolved. |
|
|
15
|
+
|
|
16
|
+
## Runtime evidence
|
|
17
|
+
|
|
18
|
+
REA target discovery `ev_c930379ae4d43fe4ea4aeee9f3a4d6204fe81b600ac9ed7bde7b9c57a2afbf5a` observed a Chrome 156 page at Google's `/sorry/index` after the normal Search navigation.
|
|
19
|
+
|
|
20
|
+
REA bundle evidence `ev_e6d7545da32207ae31b9a9fae90991ad7f8d92dbe362c804c220390b2f2a0eba` observed and analyzed seven scripts from that denied page, with no parse failures. This establishes the captured denial page, not the missing Search/AI subsystem. The selected scope was `https://www.google.com` at loopback CDP endpoint `http://127.0.0.1:9341` with a 500 ms observation window.
|
|
21
|
+
|
|
22
|
+
REA's static bundle analysis does not execute JavaScript; browser navigation was performed separately. Its findings do not establish earlier network activity, server-side behavior, string-built endpoints, encrypted configuration, uncaptured origins, or code from an unavailable successful result page. No endpoint inference from the CAPTCHA scripts is used as a Search or AI Overview API.
|
|
23
|
+
|
|
24
|
+
## Fixtures and evidence quality
|
|
25
|
+
|
|
26
|
+
`tests/fixtures/google-search/provenance.json` records capture dates, original SHA-256 digests, transports and sanitization for the actual responses. The saved autocomplete tuple is unchanged. HTML fixtures remove scripts, frames, challenge/form values, event handlers, origin-trial data and tracking values; the network IP is redacted. The meaningful interstitial and unusual-traffic structures are preserved.
|
|
27
|
+
|
|
28
|
+
`structural-search.html` is synthetic. It tests safe handling of the parser's declared HTML contract, including snippets, a semantic overview region, related content and advertisement exclusions. It is deliberately separated from live evidence and does not establish Google's current positive markup. Unknown or incomplete HTML remains `unrecognized`, and an unrecognized overview remains `unverified`.
|
|
29
|
+
|
|
30
|
+
## Official access and pricing
|
|
31
|
+
|
|
32
|
+
Google's current [Custom Search JSON API overview](https://developers.google.com/custom-search/v1/overview) states that the API is closed to new customers and existing customers must transition by January 1, 2027. For existing customers until discontinuation it lists 100 free queries per day, then $5 per 1,000 requests up to 10,000 queries per day. It requires an API key and configured Programmable Search Engine. This implementation does not use that API.
|
|
33
|
+
|
|
34
|
+
Google's [AI features documentation](https://developers.google.com/search/docs/appearance/ai-features) explains that AI Overviews appear selectively and often do not trigger. An empty parser result therefore cannot establish whether an overview was generated for a query. Google's [Search help page](https://support.google.com/websearch/answer/14901683?co=GENIE.Platform%3DDesktop&hl=en) describes the Web filter as excluding AI Overviews, but this investigation did not verify that filter's request parameters or use it as an overview-retrieval mechanism.
|
|
35
|
+
|
|
36
|
+
No documented public method for retrieving Google.com's actual AI Overview text was established by this investigation. A generated response from a different model or product would not establish that result and is not substituted here. The remaining work requires an accessible successful Search response and observed loading/expansion behavior; the current implementation is not full Search or AI Overview protocol parity.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Google Search and autocomplete
|
|
2
|
+
|
|
3
|
+
The `googlemaps-kit/google-search` entry point provides anonymous autocomplete and a Search HTML request/parser. Autocomplete worked against Google's public endpoint during research on October 29, 2026. Search returned a JavaScript interstitial in Node and an unusual-traffic challenge in Chromium. Successful organic results, related questions and AI Overview extraction have **not** been verified against a live response.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { googleSearch } from 'googlemaps-kit/google-search';
|
|
7
|
+
|
|
8
|
+
const client = googleSearch({ language: 'en', country: 'us' });
|
|
9
|
+
const suggestions = await client.suggest('typescript');
|
|
10
|
+
console.log(suggestions.suggestions);
|
|
11
|
+
|
|
12
|
+
const response = await client.search('what is typescript');
|
|
13
|
+
console.log(response.status, response.organic, response.aiOverview);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
No API key or additional runtime dependency is required. Public availability does not imply a quota guarantee. The client makes one request per method call, does not retry automatically, and does not solve or bypass challenges.
|
|
17
|
+
|
|
18
|
+
## Response status
|
|
19
|
+
|
|
20
|
+
| `status` | Meaning |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `results` | Supported result links or an explicitly labeled overview region were extracted. HTML extraction remains experimental. |
|
|
23
|
+
| `empty` | A recognized Search container includes an explicit no-results message. |
|
|
24
|
+
| `blocked` | HTTP 403/429, a `/sorry/` destination, or a recognized unusual-traffic challenge. |
|
|
25
|
+
| `javascript-required` | An enable-JavaScript interstitial was returned without recognizable result links. |
|
|
26
|
+
| `consent-required` | The response is Google's consent page. |
|
|
27
|
+
| `unrecognized` | The parser cannot establish that the HTML is a supported result page. |
|
|
28
|
+
|
|
29
|
+
`aiOverview.status` is `present` only for an explicitly labeled `AI Overview` region, `blocked` when Search access is denied, and `unverified` otherwise. Missing or unfamiliar markup never becomes an absent overview. The client does not generate substitute text or call Gemini. `text` and `sources` are extracted only from the supplied region; hidden or deferred content is not retrieved.
|
|
30
|
+
|
|
31
|
+
## Methods and options
|
|
32
|
+
|
|
33
|
+
`client.suggest(query, { language?, country?, signal? })` calls `https://suggestqueries.google.com/complete/search?client=firefox`. It returns `{ query, suggestions, raw }`, preserving unknown tuple metadata. Its payload is independent of Search result pages.
|
|
34
|
+
|
|
35
|
+
`client.search(query, { language?, country?, start?, safe?, signal?, includeRawHtml? })` requests `https://www.google.com/search`. `start` must be a nonnegative integer; `safe` is `active` or `off`. It returns the query, final source URL, HTTP status, extraction status, organic links, related content, overview status and warnings. Raw HTML is retained only when requested. `Retry-After`, when present, is available as `retryAfterMs` and is not automatically acted on.
|
|
36
|
+
|
|
37
|
+
`googleSearch({ fetch?, language?, country?, timeoutMs? })` defaults to Node's `fetch`, language `en`, country `us`, and a 20-second deadline covering both response headers and body. Caller cancellation preserves its reason. Other failures throw `GoogleSearchError` with `kind` equal to `http`, `network`, `parse`, or `timeout`.
|
|
38
|
+
|
|
39
|
+
## Supplying HTML
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { parseGoogleSearchHtml } from 'googlemaps-kit/google-search';
|
|
43
|
+
|
|
44
|
+
const response = parseGoogleSearchHtml(savedHtml, {
|
|
45
|
+
sourceUrl: 'https://www.google.com/search?q=typescript&hl=en',
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The parser does not execute scripts. Its provisional structural contract recognizes `#search`/`#rso`, linked `h3` result titles, common snippet containers, and explicitly labeled regions for `AI Overview`, `People also ask`, and `Related searches`. Google may use other structures, localization, asynchronous content or experiments. Positive extraction tests use an explicitly synthetic fixture; they establish this parser contract rather than current Google markup. Real captured fixtures establish only autocomplete and the two access-challenge states.
|
|
50
|
+
|
|
51
|
+
Run offline coverage with `npx vitest run tests/unit/google-search`. Run the optional network probes with `GMAPS_LIVE=1 GOOGLE_SEARCH_LIVE=1 npx vitest run tests/live/google-search.test.ts`; the Search probe reports whether it reached results or a recognized challenge. A passing blocked probe does not establish working Search extraction.
|
|
52
|
+
|
|
53
|
+
See [the research ledger](./google-search-research.md) for observations, evidence and remaining gaps.
|
|
@@ -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
|
+
```
|