ChatGPT Scraper API: Extract Structured Map & Local Business Data
Web Data Collection Specialist
TL;DR:
- The ChatGPT Scraper (
scraper.chatgpt) now returns a structuredmapobject when a ChatGPT answer includes local businesses. - One
POSTto/api/v2/scraper/executewith a local-intent prompt returns ranked places with name, coordinates, address, phone, website, hours, rating, review count, price level, and the listing provider. - No more parsing prose: the places ChatGPT names in a "best coffee near…" answer come back as a clean array you can sort, filter, and store.
- Fields are nullable and provider-sourced: ratings, hours, and distance can be missing per entity, so parse defensively.
- Start free. New Scrapeless accounts include free Scraper API credits — sign up at app.scrapeless.com.
When you ask ChatGPT a local question — "best rated coffee shops near Times Square" — the answer names real places, and until recently that data was locked inside the prose. The Scrapeless Scraping API now surfaces it as a dedicated map object: a ranked list of businesses with their full profile, ready to rank or monitor. This guide shows how to request it, what the object contains, and where the fields need care. Every request and field below was captured from a live run of the actor.
What You Can Do With ChatGPT Map Data
The actor takes a local-intent prompt and returns the businesses ChatGPT surfaces as structured entities. Practically, that lets you:
- Track local-pack visibility — see which businesses ChatGPT names for a "best X near Y" query, in what order, with their rating and review count.
- Build location datasets — pull name, coordinates, address, phone, and website for the places in an answer, the same profile fields a places API exposes, without scraping a maps UI.
- Monitor a brand or competitor — check whether a specific business appears in ChatGPT's local recommendations over time.
- Feed downstream systems — pipe the ranked entities into dashboards, maps, or alerts as clean JSON.
Why the Scrapeless ChatGPT Actor
ChatGPT's answers are generated behind an interface, not served as a structured feed. The Scrapeless actor runs the query and returns a developer-friendly envelope, so your code reads fields instead of regex-parsing an answer, driving a browser, or maintaining anti-blocking infrastructure. The map object is part of the same response you already get from the ChatGPT actor, alongside the answer text, search results, and products.
Endpoint and Parameters
The actor runs on the synchronous Scraper API endpoint. Authenticate with your token in the x-api-token header.
- Endpoint:
POST https://api.scrapeless.com/api/v2/scraper/execute - Actor:
scraper.chatgpt
| Input field | Type | Required | Description |
|---|---|---|---|
prompt |
string | yes | The question to send to ChatGPT. Use local intent (e.g. "best coffee near…") to populate map. |
country |
string | yes | Target country code, e.g. US. |
web_search |
bool | no | Enable web-search enrichment; recommended for local queries. |
shopping |
bool | no | Fetch product data into products (billed at a higher rate). |
The map object appears in the task_result when the answer contains local businesses; a non-local prompt returns an empty map.
Authenticated Request
A minimal request looks like this (illustrative — replace the token):
bash
curl 'https://api.scrapeless.com/api/v2/scraper/execute' \
--header 'Content-Type: application/json' \
--header 'x-api-token: YOUR_API_TOKEN' \
--data '{
"actor": "scraper.chatgpt",
"input": {
"prompt": "best rated coffee shops near Times Square New York",
"country": "US",
"web_search": true
}
}'
Python Integration
This example reads the token from the SCRAPELESS_API_KEY environment variable, sends a local query, and prints the ranked places from the map object. It uses only the Python standard library.
python
import json
import os
import urllib.request
API_URL = "https://api.scrapeless.com/api/v2/scraper/execute"
API_TOKEN = os.environ["SCRAPELESS_API_KEY"]
payload = {
"actor": "scraper.chatgpt",
"input": {
"prompt": "best rated coffee shops near Times Square New York",
"country": "US",
"web_search": True,
},
}
request = urllib.request.Request(
API_URL,
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json", "x-api-token": API_TOKEN},
method="POST",
)
with urllib.request.urlopen(request, timeout=180) as response:
data = json.loads(response.read().decode("utf-8"))
result = data.get("task_result", {})
entities = (result.get("map") or {}).get("entities") or []
print("status:", data.get("status"))
print("map entities:", len(entities))
for place in entities[:5]:
inner = place.get("entity", {})
print("-", place.get("name"))
print(" rating:", inner.get("rating"), "| reviews:", inner.get("review_count"), "| price:", inner.get("price_str"))
print(" address:", inner.get("address"))
The Map Object
The map object lives in task_result and holds a ranked entities list plus an unranked raw_search_entities list. The fields below are the ones you will use most; values are an illustrative sample from a live run, trimmed for length.
json
// Illustrative sample from a live scraper.chatgpt run — field names are real, values trimmed.
{
"status": "success",
"task_result": {
"map": {
"entities": [
{
"name": "Frisson Espresso",
"category": "coffee_shop",
"latitude": 40.760837,
"longitude": -73.9889995,
"entity": {
"address": "326 W 47th St, New York, NY 10036, United States",
"phone": "+1 646-850-3928",
"website_url": "<business website>",
"hours": [{ "day": 5, "start": "0700", "end": "1800" }],
"is_open": false,
"categories": ["Coffee shop", "Cafe", "Espresso bar"],
"rating": 4.6,
"review_count": 1006,
"price_str": "$",
"provider": "yelp-feed",
"provider_url": "<provider listing URL>",
"distance_meters": null
}
}
],
"raw_search_entities": []
}
}
}
| Field | Type | Description |
|---|---|---|
entities |
array | Ranked places ChatGPT surfaced for the query. |
entities[].name |
string | Business name. |
entities[].latitude / longitude |
number | Coordinates for the map pin. |
entities[].category |
string | Entity type, e.g. coffee_shop. |
entities[].entity.address |
string | Full street address. |
entities[].entity.phone |
string | Phone number. |
entities[].entity.website_url |
string | Official website. |
entities[].entity.hours |
array | Opening hours by day. |
entities[].entity.is_open |
bool | Whether it is open now. |
entities[].entity.categories |
array | Human-readable category labels. |
entities[].entity.rating |
number | Average rating. |
entities[].entity.review_count |
number | Number of reviews. |
entities[].entity.price_str |
string | Price level, e.g. $. |
entities[].entity.provider |
string | Listing source, e.g. yelp-feed. |
entities[].entity.provider_url |
string | The provider's listing page. |
entities[].entity.distance_meters |
number | Distance from the searched location; may be null. |
raw_search_entities |
array | Unranked candidate entities. |
A live query for coffee near Times Square returned eight ranked places; the top result, Frisson Espresso, came back with a 4.6 rating over 1,006 reviews, a $ price level, full opening hours, and its listing provider attached.
Common Data-Shape Problems
mapis empty for non-local prompts. The object only fills when the answer contains businesses. If you get an emptymap, the query had no local intent — add a place to the prompt and enableweb_search.- The place profile is nested one level down. Ranking fields (
name,latitude,longitude,category) sit on the entity, but contact and profile fields live underentity.*. Readplace["entity"]["rating"], notplace["rating"]. - Fields are provider-sourced and nullable.
distance_meters,hours, and evenratingcan be null for a given entity depending on the provider, so guard before using them. - Use
raw_search_entitiesfor recall. The rankedentitieslist is what ChatGPT surfaced;raw_search_entitiesholds additional candidates when you need broader coverage.
Companion Actors
The map object is one part of the ChatGPT response, which also carries the answer text, search_result, and products. The same request shape covers the other answer engines — swap scraper.chatgpt for scraper.gemini, scraper.perplexity, and the rest. Scrapeless publishes an open-source ChatGPT scraper example repository with runnable code, and for the full response envelope see the ChatGPT Scraper API guide.
Conclusion
The ChatGPT Scraper's map object turns a conversational local recommendation into structured data: send a local-intent prompt, read back a ranked list of businesses with coordinates, contact details, hours, rating, and provider. Remember that the profile fields are nested under entity, that some fields are nullable, and that a non-local prompt returns an empty map. The underlying place data is sourced from providers such as Yelp, and the surrounding answer structure is documented in the ChatGPT actor reference.
Ready to capture ChatGPT's local data? Start free from the Scrapeless dashboard, see where the actor fits on the Scraping API product page, or compare plans on Scrapeless pricing.
FAQ
Q: What is the ChatGPT map object?
A: It is a structured field in the scraper.chatgpt response that lists the local businesses ChatGPT surfaces for a query — each with name, coordinates, address, phone, website, hours, rating, review count, price level, and the listing provider.
Q: How do I make the map object populate?
A: Send a prompt with local intent (a "best X near Y" style question) and enable web_search. A non-local prompt returns an empty map.
Q: Which endpoint and parameters does it use?
A: POST https://api.scrapeless.com/api/v2/scraper/execute with actor set to scraper.chatgpt and an input object containing prompt, country, and optionally web_search. Authenticate with your token in x-api-token.
Q: Where are the rating and address in the response?
A: Ranking fields like name and coordinates are on the entity, but contact and profile fields — address, phone, rating, review_count, hours — live under entity.*. Read place["entity"]["rating"].
Q: Are the fields always present?
A: No. Values are provider-sourced, so distance_meters, hours, and rating can be null for a given entity. Guard for missing values before using them.
Q: Can I use the same code for other AI assistants?
A: Yes. The ChatGPT actor shares the LLM Chat Scraper request shape, so swapping scraper.chatgpt for scraper.gemini or scraper.perplexity reuses the same integration.
At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.



