> For the complete documentation index, see [llms.txt](https://docs.pullbay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pullbay.com/documentation/api-and-references/google-maps.md).

# Google Maps

The Pullbay Google Maps API provides programmatic access to place search, place details, and place reviews from Google Maps. Integrate location data, business listings, and customer review content into your applications, dashboards, and analytics pipelines without scraping or manual lookups.

**Base URL:** `https://dashboard.pullbay.com/api`

## Overview

The Google Maps service lets you:

* Search Google Maps for places by free-text query, optionally biased toward a geographic viewport
* Look up full details for a single place by its Google Maps feature ID (FID)
* Fetch reviews for a place using its Google Maps URL

All endpoints are read-only `GET` requests against public Google Maps data — you don't need a Google account or API key of your own.

## Common Use Cases

**Local SEO** — Pull a business's place details and review volume to track how it appears on Google Maps for a given category or area.

**Competitor Location Research** — Search a category in a target city or neighborhood to map out who's listed, where, and how they're rated.

**Review Monitoring for Multi-Location Businesses** — Fetch reviews per location on a schedule and route new ones into your own alerting or response workflow.

**Market Research** — Use Search Places across multiple queries or viewports to understand the density and distribution of a business category in a region.

**Due Diligence** — Look up a specific place by FID to confirm its current rating, review count, and contact details before including it in a report.

## Endpoints

| Endpoint                         | Description                                  | Pagination          |
| -------------------------------- | -------------------------------------------- | ------------------- |
| `GET /google-maps/place/search`  | Search Google Maps places by free-text query | Offset / `maxItems` |
| `GET /google-maps/place/{fid}`   | Get full details for a place by FID          | —                   |
| `GET /google-maps/place/reviews` | Get reviews for a place by Google Maps URL   | Cursor / `maxItems` |

***

### Search Places

Search Google Maps for places matching a free-text `query`. Optional geo filters (`latitude`, `longitude`, `zoom`) bias results toward a specific map viewport. Paginate with `offset`, or use `maxItems` for a one-shot bulk pull — the two are mutually exclusive.

**Request**

```bash
GET /google-maps/place/search
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter      | Type    | Required | Default | Description                                                                                               |
| -------------- | ------- | -------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `query`        | string  | Yes      | —       | Free-text search term, 1–200 characters (e.g. `pizza near soho new york`)                                 |
| `countryCode`  | string  | No       | —       | Country code, 2–5 characters. Not restricted to a published list — biases results toward a country/region |
| `languageCode` | string  | No       | —       | Language code for localized text, 2–10 characters. Not restricted to a published list                     |
| `latitude`     | string  | No       | —       | Latitude to center the search viewport, as a numeric string (pattern `^-?\d+(\.\d+)?$`)                   |
| `longitude`    | string  | No       | —       | Longitude to center the search viewport, as a numeric string (pattern `^-?\d+(\.\d+)?$`)                  |
| `zoom`         | string  | No       | —       | Map zoom level to use alongside `latitude`/`longitude`, as a numeric string (pattern `^\d+(\.\d+)?$`)     |
| `offset`       | string  | No       | —       | Numeric offset string to paginate results (pattern `^\d+$`). Mutually exclusive with `maxItems`           |
| `maxItems`     | integer | No       | —       | One-shot bulk pull, 1–500 results. Mutually exclusive with `offset`                                       |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/google-maps/place/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d query="pizza near soho new york" \
  -d countryCode=us \
  -d offset=0
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "url": "https://www.google.com/maps/place/data=!3m1!4b1!4m2!3m1!1s0x89c25985f7ec1beb:0x3c39f655da433d9d",
      "title": "Prince Street Pizza",
      "description": null,
      "address": "27 Prince St, New York, NY 10012",
      "neighborhood": "Manhattan",
      "street": "27 Prince St",
      "district": "New York",
      "postalCode": "10012",
      "city": "New York",
      "country": "United States",
      "location": { "lat": 40.7230777, "lng": -73.9945444 },
      "website": "https://locations.princestreetpizza.com/new-york",
      "phone": "(212) 966-4100",
      "price": "$10–20",
      "totalScore": 4.4,
      "placeId": "ChIJ6xvs94VZwokRnT1D2lX2OTw",
      "fid": "0x89c25985f7ec1beb:0x3c39f655da433d9d",
      "reviewsCount": 9039,
      "categories": ["Pizza restaurant"],
      "openingHours": [],
      "additionalInfo": {}
    }
  ],
  "pagination": { "page": 1, "hasNextPage": null, "cursor": null, "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                                                              | Type             | Description                                                                                                           |
| ------------------------------------------------------------------ | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
| `data`                                                             | array            | Array of [Place search result objects](#place-search-result-object)                                                   |
| `pagination.offset`                                                | string, nullable | Offset-style pagination cursor for this endpoint — increment by the number of items received to request the next page |
| `pagination.page` / `pagination.hasNextPage` / `pagination.cursor` | nullable         | Not the pagination mechanism used by this endpoint — see Pagination Notes below                                       |
| `pricing.creditsCharged`                                           | number           | Credits charged for this request                                                                                      |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

### Get Place

Returns full details for a single Google Maps place identified by its FID. This is a single-record lookup — the response is not paginated.

**Request**

```bash
GET /google-maps/place/{fid}
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter      | Type   | Required | Default | Description                                                                                                                                                                                 |
| -------------- | ------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fid`          | string | Yes      | —       | Path parameter. Google Maps feature ID, pattern `^0x[a-fA-F0-9]+:0x[a-fA-F0-9]+$` — two hex groups, each prefixed `0x`, separated by a colon (e.g. `0x47e671d877937b0f:0xb975fcfa192f84d4`) |
| `countryCode`  | string | No       | —       | Country code, 2–5 characters. Not restricted to a published list                                                                                                                            |
| `languageCode` | string | No       | —       | Language code for localized text, 2–10 characters. Not restricted to a published list                                                                                                       |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/google-maps/place/0x47e671d877937b0f:0xb975fcfa192f84d4" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d languageCode=en
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "url": "https://www.google.com/maps/preview/place/Louvre+Museum",
      "title": "Louvre Museum",
      "address": "Louvre Museum, 75001 Paris, France",
      "neighborhood": null,
      "street": null,
      "district": "Paris",
      "postalCode": "75001",
      "city": null,
      "location": { "lat": 40.7230777, "lng": -73.9945444 },
      "website": "https://www.louvre.fr/",
      "phone": "+33 1 40 20 53 17",
      "phoneUnformatted": "+33140205317",
      "plusCode": "V86Q+63 Paris, France",
      "price": null,
      "totalScore": 4.7,
      "placeId": "ChIJD3uTd9hx5kcR1IQvGfr8dbk",
      "cid": "-5082878453323168556",
      "fid": "0x47e671d877937b0f:0xb975fcfa192f84d4",
      "reviewsCount": 366153,
      "reviewsDistribution": {
        "oneStar": 5180,
        "twoStar": 3447,
        "threeStar": 13286,
        "fourStar": 52471,
        "fiveStar": 291769
      },
      "categories": ["Art museum", "Museum", "Tourist attraction"],
      "additionalInfo": {}
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                    | Type   | Description                                             |
| ------------------------ | ------ | ------------------------------------------------------- |
| `data`                   | array  | Array containing a single [Place object](#place-object) |
| `pricing.creditsCharged` | number | Credits charged for this request                        |

There is no `pagination` object in this response — `getGoogleMapsPlace` returns one place per request, not a list.

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

### Get Place Reviews

Returns reviews for a place identified by its full Google Maps URL (`placeUrl`) — not its FID. Paginate with `cursor`, or use `maxItems` for a one-shot bulk pull — the two are mutually exclusive.

**Request**

```bash
GET /google-maps/place/reviews
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Default | Description                                                                                                             |
| ---------- | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| `placeUrl` | string  | Yes      | —       | Full Google Maps place URL, 10–1000 characters. This is a different identifier than `fid` — see Finding Place IDs below |
| `maxItems` | integer | No       | —       | One-shot bulk pull, 1–500 results. Mutually exclusive with `cursor`                                                     |
| `cursor`   | string  | No       | —       | Opaque pagination cursor returned in the previous response's `pagination.cursor`. Mutually exclusive with `maxItems`    |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/google-maps/place/reviews" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d placeUrl="https://www.google.com/maps/place/data=!3m1!4b1!4m2!3m1!1s0x89c25985f7ec1beb:0x3c39f655da433d9d" \
  -d maxItems=20
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "id": "Ci9DQUlRQUNvZENodHljRjlvT25OdmExZHZVSEJPYjJkRGIxVXpiRFIzYXpWUmFFRRAB",
      "link": "https://www.google.com/maps/reviews/data=!4m8!14m7!1m6!2m5!1sCi9DQUlRQUNvZENodHljRjlvT25OdmExZHZVSEJPYjJkRGIxVXpiRFIzYXpWUmFFRRAB",
      "text": "Loved the experience",
      "stars": 5,
      "date": 1777380220000,
      "dateIso": "2026-04-28T12:43:40.000Z",
      "likes": null,
      "photos": [],
      "reviewer": {
        "name": "Jane Doe",
        "photo": "https://example.com/reviewer-photo.jpg",
        "url": "https://www.google.com/maps/contrib/000000000000000000000?hl=en-US",
        "totalReviews": 2,
        "totalPhotos": 7
      },
      "ownersResponse": {},
      "details": {
        "Visited on": "Weekend",
        "Wait time": "10–30 min",
        "Reservation recommended": true
      }
    }
  ],
  "pagination": { "page": null, "hasNextPage": null, "cursor": null, "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                                                              | Type             | Description                                                                                           |
| ------------------------------------------------------------------ | ---------------- | ----------------------------------------------------------------------------------------------------- |
| `data`                                                             | array            | Array of [Place review objects](#place-review-object)                                                 |
| `pagination.cursor`                                                | string, nullable | Cursor-style pagination token for this endpoint — pass it as `cursor` on the next request to continue |
| `pagination.page` / `pagination.hasNextPage` / `pagination.offset` | nullable         | Not the pagination mechanism used by this endpoint                                                    |
| `pricing.creditsCharged`                                           | number           | Credits charged for this request                                                                      |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

## Errors

All non-2xx responses share the same envelope:

```json
{
  "status": 400,
  "message": "Bad request",
  "success": false,
  "error": { "code": "BAD_REQUEST" }
}
```

| Status | Meaning                                  |
| ------ | ---------------------------------------- |
| `400`  | Bad request — missing/invalid parameters |
| `402`  | Insufficient credits                     |
| `404`  | Place or review set not found            |

All three endpoints can return `400`, `402`, and `404`.

## Object Schema

### Place search result object

| Field            | Type             | Description                                                                                            |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------ |
| `url`            | string           | Google Maps URL for the place                                                                          |
| `title`          | string           | Place name                                                                                             |
| `description`    | string, nullable | Short description, if available                                                                        |
| `address`        | string           | Full formatted address                                                                                 |
| `neighborhood`   | string, nullable | Neighborhood name                                                                                      |
| `street`         | string, nullable | Street address                                                                                         |
| `district`       | string, nullable | District or city-level area                                                                            |
| `postalCode`     | string, nullable | Postal code                                                                                            |
| `city`           | string, nullable | City name                                                                                              |
| `country`        | string, nullable | Country name                                                                                           |
| `location`       | object           | Latitude/longitude pair — see Location object                                                          |
| `website`        | string, nullable | Place's website URL                                                                                    |
| `phone`          | string, nullable | Formatted phone number                                                                                 |
| `price`          | string, nullable | Price range indicator (e.g. `$10–20`)                                                                  |
| `totalScore`     | number           | Average rating                                                                                         |
| `placeId`        | string           | Google Place ID                                                                                        |
| `fid`            | string           | Google Maps feature ID, of the form `0x...:0x...` — use this to fetch full place details via Get Place |
| `reviewsCount`   | integer          | Total number of reviews                                                                                |
| `categories`     | array            | Place category labels                                                                                  |
| `openingHours`   | array            | Opening hours per weekday                                                                              |
| `additionalInfo` | object           | Grouped feature flags (e.g. Service options, Accessibility, Offerings)                                 |

### Location object

| Field | Type   | Description |
| ----- | ------ | ----------- |
| `lat` | number | Latitude    |
| `lng` | number | Longitude   |

### Place object

| Field                 | Type             | Description                                                               |
| --------------------- | ---------------- | ------------------------------------------------------------------------- |
| `url`                 | string           | Google Maps URL for the place                                             |
| `title`               | string           | Place name                                                                |
| `address`             | string           | Full formatted address                                                    |
| `neighborhood`        | string, nullable | Neighborhood name                                                         |
| `street`              | string, nullable | Street address                                                            |
| `district`            | string, nullable | District or city-level area                                               |
| `postalCode`          | string, nullable | Postal code                                                               |
| `city`                | string, nullable | City name                                                                 |
| `location`            | object           | Latitude/longitude pair — see Location object                             |
| `website`             | string, nullable | Place's website URL                                                       |
| `phone`               | string, nullable | Formatted phone number                                                    |
| `phoneUnformatted`    | string, nullable | Phone number without formatting                                           |
| `plusCode`            | string, nullable | Google Plus Code                                                          |
| `price`               | string, nullable | Price range indicator                                                     |
| `totalScore`          | number           | Average rating                                                            |
| `placeId`             | string           | Google Place ID                                                           |
| `cid`                 | string           | Google Maps client ID                                                     |
| `fid`                 | string           | Google Maps feature ID, of the form `0x...:0x...`                         |
| `reviewsCount`        | integer          | Total number of reviews                                                   |
| `reviewsDistribution` | object           | Review count broken down by star rating — see Reviews distribution object |
| `categories`          | array            | Place category labels                                                     |
| `additionalInfo`      | object           | Grouped feature flags (e.g. Service options, Accessibility, Amenities)    |

### Reviews distribution object

| Field       | Type    | Description             |
| ----------- | ------- | ----------------------- |
| `oneStar`   | integer | Count of 1-star reviews |
| `twoStar`   | integer | Count of 2-star reviews |
| `threeStar` | integer | Count of 3-star reviews |
| `fourStar`  | integer | Count of 4-star reviews |
| `fiveStar`  | integer | Count of 5-star reviews |

### Place review object

| Field            | Type               | Description                                                   |
| ---------------- | ------------------ | ------------------------------------------------------------- |
| `id`             | string             | Review ID                                                     |
| `link`           | string             | Permalink to the review                                       |
| `text`           | string             | Review body                                                   |
| `stars`          | integer            | Rating, 1–5                                                   |
| `date`           | integer            | Posted timestamp, Unix milliseconds                           |
| `dateIso`        | string (date-time) | Posted timestamp, ISO 8601                                    |
| `likes`          | integer, nullable  | Number of likes on the review                                 |
| `photos`         | array              | Photo URLs attached to the review                             |
| `reviewer`       | object             | Reviewer who left the review — see Reviewer object            |
| `ownersResponse` | object             | Owner's response to the review (empty object when none)       |
| `details`        | object             | Free-form key/value metadata (e.g. `Visited on`, `Wait time`) |

### Reviewer object

| Field          | Type    | Description                                |
| -------------- | ------- | ------------------------------------------ |
| `name`         | string  | Reviewer's display name                    |
| `photo`        | string  | Reviewer's profile photo URL               |
| `url`          | string  | Link to the reviewer's Google Maps profile |
| `totalReviews` | integer | Total reviews the reviewer has written     |
| `totalPhotos`  | integer | Total photos the reviewer has uploaded     |

## Finding Place IDs

Search Places, Get Place, and Get Place Reviews each expect a different identifier — they are **not** interchangeable:

* **FID**: the feature ID returned as `fid` on both [Place search result objects](#place-search-result-object) and [Place objects](#place-object), of the form `0x47e671d877937b0f:0xb975fcfa192f84d4` (two `0x`-prefixed hex groups separated by a colon). Run Search Places first to discover a place's `fid`, then pass it as the path parameter to Get Place (`/google-maps/place/{fid}`) for full details.
* **Place URL**: the full `google.com/maps/place/...` URL for a place, returned as `url` on both search and detail responses. Pass this — not the `fid` — as `placeUrl` to Get Place Reviews (`/google-maps/place/reviews`). An `fid` cannot be substituted for `placeUrl`; the reviews endpoint requires the full URL string.

In short: get the `fid` from a search result to look up place details, but get the `url` from that same search result to look up reviews.

## Python Example: Searching, Then Fetching Reviews

This example searches for places matching a query, then uses the `url` from the first result to fetch its reviews — illustrating why `fid` and `placeUrl` are not interchangeable:

```python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://dashboard.pullbay.com/api"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def search_places(query, country_code="us", max_items=10):
    resp = requests.get(
        f"{BASE_URL}/google-maps/place/search",
        headers=HEADERS,
        params={"query": query, "countryCode": country_code, "maxItems": max_items},
    )
    resp.raise_for_status()
    return resp.json()["data"]

def get_reviews_for_place(place_url, max_items=20):
    resp = requests.get(
        f"{BASE_URL}/google-maps/place/reviews",
        headers=HEADERS,
        params={"placeUrl": place_url, "maxItems": max_items},
    )
    resp.raise_for_status()
    return resp.json()["data"]

places = search_places("pizza near soho new york")
first_place = places[0]

# Note: first_place["fid"] would be used with /google-maps/place/{fid} to get
# full place details. Reviews require the full URL instead:
reviews = get_reviews_for_place(first_place["url"])
print(f"Fetched {len(reviews)} reviews for {first_place['title']}")
```

Each request is billed independently, with the charged amount reported in that response's `pricing.creditsCharged` — there's no separate "fetch everything in one call" endpoint.

## FAQ

<details>

<summary>What's the difference between <code>fid</code> and <code>placeUrl</code>?</summary>

They're different identifiers for different endpoints. `fid` is Google's feature-ID format (`0x...:0x...`) used to fetch full place details from Get Place. `placeUrl` is the full `google.com/maps/place/...` URL used to fetch reviews from Get Place Reviews. Both are returned alongside each other on search and detail responses, but one cannot be substituted for the other.

</details>

<details>

<summary>How do I paginate through search results?</summary>

Use the `offset` parameter (a numeric string) and increment it by the number of items received in each response to request the next page. Alternatively, use `maxItems` for a one-shot bulk pull instead of paging — `offset` and `maxItems` are mutually exclusive.

</details>

<details>

<summary>How do I paginate through reviews?</summary>

Use the `cursor` returned in the previous response's `pagination.cursor` field to request the next page. Alternatively, use `maxItems` for a one-shot bulk pull — `cursor` and `maxItems` are mutually exclusive.

</details>

<details>

<summary>Why doesn't Get Place have pagination?</summary>

It's a single-record lookup — you pass one `fid` and get back one place. There's no list to page through, so the response has no `pagination` object.

</details>

<details>

<summary>Are <code>countryCode</code> and <code>languageCode</code> restricted to specific values?</summary>

No. Both are length-constrained strings (`countryCode` 2–5 characters, `languageCode` 2–10 characters) but are not validated against a published enum or fixed list in the API spec.

</details>

<details>

<summary>What's the credit cost per request?</summary>

It's dynamic — every response includes `pricing.creditsCharged` with the exact amount for that call. There's no fixed published rate per endpoint or per result.

</details>

## Next Steps

* [**API Integration Guide**](broken://pages/68e75ab1a73d266350bd68301be87ff97cad563e) — integrate the Pullbay API into your backend application.
* [**n8n Integration Guide**](broken://pages/4308164455b56bbc694cf74c9768ea689c2fe719) — set up automated workflows using n8n with no coding required.
* [**Services Overview**](broken://pages/0d55376cbcca70097a683a71a593d3077825dbf1) — explore all available Pullbay services.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pullbay.com/documentation/api-and-references/google-maps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
