semust logo

API Platform

Business Data API

Google business listings — find businesses by category, name and location, read one business's full profile, and pull its reviews with ratings, dates and owner replies.

Search Google's business listings, millions of them in Turkey alone, by category, name and distance. Read a business's full profile: rating breakdown, opening hours, description and attributes. Pull its reviews with ratings, dates, authors and owner replies. One endpoint serves three reports, selected with the type parameter.

Reviews always run as a task

This endpoint runs every request as a task. search and profile usually answer within the default 60-second wait with a normal 200. reviews take one to three minutes to collect, so a reviews request almost always returns 202 with a task_id. Poll GET /v1/tasks/{task_id} until the result is ready; there is a loop below. Every response carries the task id in the X-Task-Id header. Retry safely with an Idempotency-Key header: never re-send a request that returned 202, because a second request is a second charge.

Authentication

HeaderTypeDescription
SEMUST-API-USERstringYour API user's username
SEMUST-API-PASSWORDstringYour API user's password
Accept-LanguagestringOptional. Send tr to receive error messages in Turkish

Create API credentials from the API Access page.

SEMUST-API-USER: your_username
SEMUST-API-PASSWORD: your_password
Content-Type: application/json

Report Types

typeReturnsPrice
search (default)Businesses matching categories, a name and/or a circle on the map, with rating, review count, contact details and address$0.0132 + $0.000396 per business returned
profileOne business's full profile: everything search returns plus description, opening hours, attributes and related businesses$0.00594
reviewsOne business's reviews: text, rating, date, author and owner reply$0.000825 per 10 reviews asked for

search returns place_id and cid for every business. Pass either one to profile or reviews to address that exact business. A name is searched for instead, and the best match is used.

{
  "type": "search",
  "categories": ["cafe"],
  "latitude": 40.9906,
  "longitude": 29.0270,
  "radius_km": 1,
  "limit": 20
}

Request Parameters

A parameter that does not apply to the chosen type is rejected rather than ignored, and a misspelled one is named in the error with a suggestion. A JSON null is treated as "not sent".

Body: search

categoriesstring[]

1–10 category ids, such as cafe, dentist or car_repair. An unknown id is rejected with a suggestion (cafee → cafe). GET /v1/business-data/categories?q=… searches the 5,316 ids.

namestring

Businesses whose name contains this text, case-insensitively, up to 200 characters. A Turkish I or ı matches both readings, so KADIKÖY also finds Kadıköy.

latitude, longitude, radius_kmnumber, number, integer

A circle on the map: centre in degrees, radius in whole kilometres, 1–500. Send all three or none.

countrystringdefault: TR

Two-letter country code. Without a location it defaults to TR. With a location there is no country filter unless you send one.

min_ratingnumber

Only businesses rated at least this, 1–5.

min_reviewsinteger

Only businesses with at least this many reviews.

claimedboolean

true: only businesses whose owner has claimed the listing. false: only unclaimed ones.

sortstringdefault: reviews

reviews (review count) or rating.

directionstringdefault: desc

desc or asc.

limitintegerdefault: 100

Businesses per page, 1–1000.

pageintegerdefault: 1

Page number. page × limit can be at most 20,000.

Send at least one of categories, name or a location. Filters alone are not a search.

Body: profile and reviews

place_idstring

The business's place id, from search (ChIJQ3x3p-e5yhQRCzOLzD3Pdkw).

cidstring

The business's numeric id, from search, as a string ("5509819058466009867").

namestring

The business name, searched for. Adding the city helps ("Galata Kulesi İstanbul").

countrystringdefault: TR

Two-letter country code: where name is searched for.

languagestring

The language of category names, and the language reviews are translated into. Defaults to tr for TR and en elsewhere.

sortstringdefault: relevant

reviews only: relevant, newest, highest_rating or lowest_rating.

limitintegerdefault: 10

reviews only. Reviews to fetch, 1–1000, rounded up to a multiple of 10 (25 becomes 30). You are billed for the rounded number, and you get up to that many.

Send exactly one of place_id, cid and name.

Body: every type

typestringdefault: search

search, profile or reviews.

idempotency_keystring

Optional, up to 128 characters. Repeating a request with the same key returns the same task: its 202 while it runs, its stored result once it finishes. It is charged once. The key is reserved until 72 hours after the task finishes. It does the same job as the Idempotency-Key header; if you send both, this field wins.

Query

waitintegerdefault: 60

Seconds to wait for the result, 0–80. If the request is still running after that, the response is 202 with a task_id. 0 answers 202 at once.

Headers

Idempotency-Keystring

Optional. Works like idempotency_key above; if you send both, the body field wins.

Two free lookups:

  • GET /v1/business-data/categories?q=… lists the category ids search accepts, largest first, filtered by a case-insensitive substring. Spaces match underscores.
  • GET /v1/business-data/markets lists every supported country and language.
curl -X POST https://data.semust.com/v1/business-data \
  -H "SEMUST-API-USER: your_username" \
  -H "SEMUST-API-PASSWORD: your_password" \
  -H "Content-Type: application/json" \
  -d '{"type": "search", "categories": ["cafe"], "latitude": 40.9906, "longitude": 29.0270, "radius_km": 1, "limit": 20}'

Response

search and reviews return rows in items; profile returns one data object. reviews also returns a business header: the business the reviews belong to, with its overall rating and review count.

Every documented key is on every row; a value the listing does not have is null. Address parts follow Google's own levels. In Turkey, city is the district (Kadıköy), region the province (İstanbul) and neighborhood the mahalle.

A search that matches nothing is a valid answer: items is empty and the request fee is billed. A business that does not exist is not: profile and reviews answer 404 BUSINESS_NOT_FOUND, and you are not charged.

The examples below are real responses, shortened. Reviewer names are replaced.

{
  "success": true,
  "type": "search",
  "country": "TR",
  "total": 450,
  "count": 20,
  "page": 1,
  "limit": 20,
  "sort": "reviews",
  "direction": "desc",
  "items": [
    {
      "name": "Asuman Moda",
      "category": "Chocolate shop",
      "categories": ["chocolate_shop", "cafe"],
      "place_id": "ChIJX5XeCGG4yhQRH7cWWfY90-Q",
      "cid": "16488590788999427871",
      "address": "Caferağa, Şair Nefi Sk. No:9/a, 34710 Kadıköy/İstanbul",
      "neighborhood": "Caferağa",
      "city": "Kadıköy",
      "region": "İstanbul",
      "postal_code": "34710",
      "country": "TR",
      "phone": "+902163450526",
      "website": "http://www.asuman.com/",
      "domain": "www.asuman.com",
      "latitude": 40.9837234,
      "longitude": 29.026517,
      "rating": 4.1,
      "reviews": 8907,
      "rating_distribution": { "1": 879, "2": 402, "3": 753, "4": 1511, "5": 5362 },
      "price_level": null,
      "claimed": true,
      "photos": 4219,
      "maps_url": "https://www.google.com/maps?cid=16488590788999427871&hl=en&gl=TR",
      "updated_at": "2026-09-21T08:36:30Z"
    }
  ],
  "cost": 0.02112,
  "cached": false,
  "request_id": "0b7e6f1a-3c2d-4e5f-9a8b-1c2d3e4f5a6b"
}

Response Fields Reference

Envelope

FieldTypeDescription
countrystringThe country searched. Absent on a search bounded only by a location
languagestringprofile and reviews: the language used
totalintegersearch: how many businesses match. Only the first 20,000 are reachable by paging
countintegerRows in items; on search, the businesses you are billed for
limit, page, sort, directionThe paging and order applied. On reviews, limit is the rounded number billed
businessobjectreviews only: name, place_id, cid, rating and reviews (the total review count)

Business (search row, profile → data)

FieldTypeDescription
namestringBusiness name
category, categoriesstring | null, string[]Primary category. On search, categories holds category ids you can pass back to categories. On profile it holds category names in language
place_id, cidstring | nullIdentifiers for profile and reviews
address, neighborhood, city, region, postal_code, countrystring | nullFull address and its parts
phone, website, domainstring | nullContact details as listed
latitude, longitudenumber | nullLocation
rating, reviewsnumber | null, integer | nullAverage rating (1–5) and number of reviews
rating_distributionobject | nullReview count per star, "1"–"5"
price_levelstring | nulle.g. inexpensive, moderate, expensive
claimedboolean | nullWhether the owner has claimed the listing
photosinteger | nullNumber of photos
maps_urlstring | nullGoogle Maps link to the business
updated_atstring | nullsearch: when the listing was last refreshed, ISO 8601 UTC. null on profile, which is read live

profile only

FieldTypeDescription
descriptionstring | nullThe business's own description
open_nowstring | nullStatus at the time of the request: open, closed, or another status such as temporarily_closed
hoursobject | nullWeekday (monday…sunday) → list of {open, close}, HH:MM local time. close 00:00 is midnight
attributesobjectavailable and unavailable amenity ids, such as has_wheelchair_accessible_entrance
topics{topic, mentions}[]Subjects reviewers mention most
people_also_search{name, place_id, cid, rating, reviews}[]Businesses people also look at

reviews row

FieldTypeDescription
review_idstring | nullStable review id
ratingnumber | nullStars, 1–5
textstring | nullReview text. When the review was translated into language, the original is in original_text. Otherwise original_text is null
original_languagestring | nullThe language the reviewer wrote in
published_atstring | nullISO 8601 UTC
urlstring | nullLink to the review
imagesintegerPhotos attached
authorobjectname, url, reviews and photos (the author's totals), and local_guide
owner_answerobject | nullThe owner's reply: text, published_at

Errors

Every error carries a stable code, a readable error, and retryable; where it helps also field, hint and allowed. Send Accept-Language: tr for Turkish messages. You are never charged for an error. The full list, shared with the other APIs, is on Error Codes. Specific to this endpoint:

StatusCodeMeaningWhat to do
202—Not an error: still running after wait seconds (usual for reviews)Poll GET /v1/tasks/{task_id}; see Tasks
400SEARCH_CRITERIA_REQUIREDA search with no categories, name or locationSend at least one
400UNKNOWN_CATEGORYA category id that does not exist; hint suggests the closestGET /v1/business-data/categories?q=…
400BUSINESS_REQUIREDprofile or reviews without place_id, cid or nameSend one
400PAGE_OUT_OF_RANGEpage × limit over 20,000Narrow the search
400INVALID_PARAMETERe.g. a location missing one of its three fields, a radius that is not a whole number from 1 to 500, two identifiers at once, or a cid sent as a number; field names itFix the field
400UNSUPPORTED_MARKETUnknown country or languageGET /v1/business-data/markets
404BUSINESS_NOT_FOUNDNo business matches the place_id, cid or name (not charged)Check it, add the city to the name, or use an id from search
{
  "error": "'cafee' is not a business category",
  "code": "UNKNOWN_CATEGORY",
  "field": "categories",
  "hint": "Did you mean 'cafe'? GET /v1/business-data/categories?q=… searches every category id",
  "retryable": false
}

Credits & Limits

RequestCost
search$0.0132 + $0.000396 per business returned ($0.0528 for 100)
profile$0.00594
reviews$0.000825 per 10 reviews asked for ($0.00825 for 100)

search is billed on the businesses it returns. A search for 100 that finds 3 costs $0.0132 + 3 × $0.000396. One that finds none still costs the $0.0132 request fee.

reviews is billed on the limit you ask for, rounded up to a multiple of 10, even when the business has fewer reviews. The review count isn't known until the reviews are collected. Size limit with the reviews count that search and profile return: asking for 100 reviews of a business that has 4 costs the 100.

Results are cached: 24 hours for search and profile, 6 hours for reviews. A cached answer is marked "cached": true and billed at the same price as a live one.

Per-minute and per-day limits are set on your account (429 RATE_LIMIT_EXCEEDED). At most 5 requests per API user run at the same time; more get 429 TOO_MANY_CONCURRENT_REQUESTS with Retry-After. A request that has returned 202 keeps its place until its task finishes. At most 100 tasks per API user can be unfinished at once (429 TOO_MANY_PENDING_TASKS). Polling has its own limit and does not count against any of these; see Tasks.

Last updated: 2026-11-07