serpix

google-places-api

Google Places API

Google's local business results as JSON, searched from the city you name. Twenty places a page, each with its rating, category, address, coordinates and Google's own place id.

Endpoint

One credit per request. A page carries twenty places, the same twenty Google ranks for that query in that city.

GET/v1/places
bash
curl -G "https://api.serpix.io/v1/places" \
  --data-urlencode "q=personal injury lawyer" \
  --data-urlencode "location=New York, New York, United States" \
  -H "Authorization: Bearer $SERPIX_API_KEY"

The same parameters are accepted as a JSON body on POST /v1/places:

post variant
curl -X POST "https://api.serpix.io/v1/places" \
  -H "Authorization: Bearer $SERPIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "personal injury lawyer", "location": "New York"}'

Parameters

A local query answered from the wrong city is worse than no answer, so the origin is the parameter that matters here. Give location a city name and Serpix resolves it against Google's own geotarget list, echoing the canonical match back as location_used. A name that cannot be resolved fails the request instead of quietly searching somewhere else, and costs nothing.

Query and localization
fieldtypedescription
qrequiredstringThe search query.
glstringCountry, as a two-letter code. Defaults to the country of location when you set one, else us.
hlstringLanguage of the results page, two-letter code.

Search origin

A place name covers most work; coordinates are there for when a city is too coarse, and Google measures distance from them. They are two ways to write one thing, so a request carries one or the other.

Search origin
fieldtypedescription
locationstringCity to search from, such as New York, New York, United States. Cannot be combined with lat/lon.
latnumberLatitude of a precise origin, for when a city is too coarse. Send with lon.
lonnumberLongitude of a precise origin. Send with lat.

Results

Results
fieldtypedescription
devicedesktop | mobile | tabletResults as Google serves them to a desktop browser or a phone.
pageinteger1-based page. Each page is a fresh twenty places. One credit per page.
autocorrectbooleanSet false to search the query exactly as typed, excluding results Google returns for its spell-corrected guess.

Rejected parameters

Unknown parameters are never silently ignored. A request carrying one is rejected with 422 before any search runs, so a typo can't bill you for results you didn't ask for. Common parameters from raw Google URLs and other SERP APIs get a pointed message naming the equivalent here:

Rejected aliases
fieldtypedescription
uule422Use location with a city name, or lat/lon. The geo encoding is handled for you.
num422Google serves twenty places a page. Paginate with page.
start422Use page, a 1-based page number, instead of a result offset.
ludocid422Single-place lookup by CID is not wired yet. Search by q; every result carries its own place_id.
lsig422Not supported.
tbs / lr422Not supported on this vertical.
google_domain422Not supported on this vertical.
nfpr422Use autocorrect.
udm / tbm422Not needed. This endpoint is the local vertical, which is where Google now sends the legacy tbm=lcl itself.
engine422Not needed. This endpoint is Google Places.
api_key422Authenticate with the Authorization header, never the query string.
422 · rejected parameter
HTTP/2 422
content-type: application/json

{
  "detail": [
    {
      "type": "value_error",
      "loc": ["query"],
      "msg": "Value error, `uule` is not supported: use `location` with a city name, or `lat`/`lon` — the uule encoding is handled for you",
      "input": { "q": "plumber", "uule": "w+CAIQICIfTmV3...", ... }
    }
  ]
}

Response

A search returns one JSON object: two envelope objects that are always present (search_metadata, search_parameters) and the ranking as place_results. A field that wasn't served is omitted entirely, never null, never [], so a presence check is all you need before reading one.

200 · trimmed
{
  "search_metadata": {
    "id": "srx_t9z8wvsWh1PbBHOd",
    "status": "success",
    "created_at": "2026-07-28T18:19:33Z",
    "took_ms": 1391,
    "parser_version": "2026.07.1",
    "google_url": "https://www.google.com/search?q=personal+injury+lawyer&udm=1&hl=en&gl=us&uule=w+CAIQICIfTmV3...",
    "html_url": "https://api.serpix.io/searches/srx_t9z8wvsWh1PbBHOd/ACWNx0EG7LL4-Xzw.html",
    "json_url": "https://api.serpix.io/searches/srx_t9z8wvsWh1PbBHOd/ACWNx0EG7LL4-Xzw.json"
  },
  "search_parameters": {
    "q": "personal injury lawyer",
    "gl": "us",
    "hl": "en",
    "device": "desktop",
    "page": 1,
    "location_used": "New York,New York,United States"
  },
  "place_results": [
    {
      "position": 1,
      "title": "NYC Injury Attorneys P.C.",
      "rating": 4.9,
      "reviews": 88,
      "type": "Personal injury attorney",
      "years_in_business": "5+ years in business",
      "address": "New York, NY",
      "phone": "(646) 452-3663",
      "hours": "Open 24 hours",
      "description": "\"Their expertise and knowledge of personal injury law are unparalleled.\"",
      "place_id": "7374717274750031334",
      "provider_id": "/g/11q7b8804c",
      "gps_coordinates": { "latitude": 40.711964, "longitude": -74.00853 },
      "link": "https://nyc-injury-attorneys.com/"
    },
    ...
  ],
  "pagination": {
    "current": 1,
    "next": "https://www.google.com/search?q=personal+injury+lawyer&udm=1&hl=en&gl=us&start=20&..."
  }
}

Every response also reports its cost in the X-Serpix-Credits-Charged and X-Serpix-Credits-Remaining headers.

search_metadata

search_metadata fields
fieldtypedescription
idstringUnique id of this search, srx_ prefixed.
statusstringsuccess on every 200.
created_atstringWhen the search ran, ISO 8601 UTC.
took_msintegerEnd-to-end time to serve this response, in milliseconds.
parser_versionstringDated version of the places parser that produced this response, so any response can be tied to the parsing behaviour that made it. Each vertical carries its own.
google_urlstringThe exact Google URL fetched.
html_urlstringArchived copy of the results page exactly as served. Included when available.
json_urlstringArchived copy of this JSON response. Included when available.

search_parameters

The parameters the search actually ran with, defaults filled in.

search_parameters fields
fieldtypedescription
qstringThe query as received.
glstringCountry the search ran from.
hlstringLanguage used.
devicestringDevice profile used.
pageintegerPage served.
location_usedstringThe canonical geotarget your location resolved to. Present when sent.
latnumberLatitude the search ran from. Present when sent.
lonnumberLongitude the search ran from. Present when sent.

place_results

place_results entry fields
fieldtypedescription
positionintegerRank on the page, starting at 1. Sponsored cards are not counted here.
titlestringThe business name.
ratingnumberStar rating out of five.
reviewsintegerNumber of Google reviews behind that rating, as a number: 1.2K comes back as 1200.
pricestringPrice band as displayed, either a range like $1–10 or a symbol run.
typestringBusiness category Google prints, such as Coffee shop.
years_in_businessstringTenure chip on trade listings, as displayed (3+ years in business).
addressstringStreet address, or the service area on trades that list one.
phonestringPhone number as displayed.
hoursstringOpening state as displayed, such as Open · Closes 8 PM.
descriptionstringThe review quote Google surfaces on the card, quotes kept.
place_idstringGoogle's CID for the business, stable across searches and the field to key your own records on.
provider_idstringGoogle's knowledge-graph id for the same business.
gps_coordinatesobjectLatitude and longitude of the listing.
thumbnailstringPlace photo, when the card shows one.
linkstringThe business's own website. Never a Google viewer or maps link, so it is safe to follow.

Which fields a card carries follows the query rather than the parser: cafés print a price band and a photo, trades print a phone number, opening hours and a website.

pagination

Ask for the next page with page. pagination.next is read off Google's own forward control, so its absence is how you know you have reached the last page.

pagination fields
fieldtypedescription
currentintegerThe page this response is.
nextstringGoogle URL for the next page. Absent on the last one.

Errors

A rejected request answers with detail, naming the parameter and what to send in its place. A search that could not be completed answers with error and a search_id you can quote. No error is ever charged.

Status codes
fieldtypedescription
401unauthorizedMissing, malformed, or revoked key. See Authentication.
402payment requiredThe balance can't cover a search. See Credits & billing.
422invalid requestUnknown or invalid parameter, or a location that could not be resolved. The detail says what to fix, with close matches for a near-miss city.
502search_failedThe search could not be completed. Retry it; you were not charged.
503search_unavailableGoogle did not serve a usable results page. Retry it; you were not charged.
502 · search failed
HTTP/2 502
content-type: application/json
x-serpix-credits-charged: 0

{ "error": { "code": "search_failed", "search_id": "srx_kq3v9tR2xLw8mA1c" } }