Apple Maps Business Listings Scraper
Pricing
from $1.54 / 1,000 business listing extracteds
Apple Maps Business Listings Scraper
Search Apple Maps by business category, keyword, location, coordinates, or place URL. Export stable place IDs, names, categories, addresses, phones, websites, coordinates, and source URLs for recurring lead and directory refreshes.
Pricing
from $1.54 / 1,000 business listing extracteds
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
23 days ago
Last modified
Categories
Share
Collect public Apple Maps business listings by category, keyword, city, address, or coordinates. The Actor exports stable place IDs, business names, categories, addresses, public phone numbers and websites, coordinates, and canonical Apple Maps URLs to a structured dataset.
Use it to build a local lead list, refresh a directory, verify place identities, or feed public maps data into a spreadsheet, database, CRM, or scheduled Apify workflow.
What does Apple Maps Business Listings Scraper do?
The Actor turns local search intent into reusable business records.
It supports three practical input routes:
- search one or more categories or keywords around a named location;
- center searches on exact latitude and longitude coordinates;
- resolve supplied
maps.apple.comsearch or place URLs.
Each run creates a fresh public Apple MapKit session, searches structured Apple Maps data, normalizes the fields, removes duplicate place IDs, and writes accepted records to the default dataset.
No Apple account is required. The Actor does not ask for private credentials and does not use a browser or a paid residential proxy by default.
Who is it for?
Local lead generation teams
Search categories such as dentists, gyms, cafes, agencies, or coworking spaces in a target market. Export public phone, website, and address fields when Apple Maps exposes them.
Directory and marketplace operators
Use stable placeId values to reconcile recurring runs and refresh business identity or location fields in an existing catalog.
Market researchers
Collect category presence and geographic coordinates for a bounded city or coordinate-centered sample.
Data engineers
Schedule runs, consume the dataset API, and load normalized records into a warehouse or enrichment pipeline.
Developers and AI agents
Call the Actor through the Apify API or MCP instead of implementing Apple MapKit session bootstrap and response normalization themselves.
Why use this maps scraper?
- Stable identity: every accepted row includes an Apple Maps MUID or result ID as
placeId. - Useful lead fields: names, categories, formatted addresses, phones, websites, and coordinates are normalized into predictable keys.
- Multiple searches per run: submit several categories for the same market.
- Named or exact geography: use a location string or latitude/longitude.
- Source traceability: keep the canonical
appleMapsUrl, originalsourceInput, search term, and collection timestamp. - Bounded collection: per-search and global limits control volume and cost.
- No silent challenge success: malformed input, unresolved locations, invalid structured responses, and exhausted upstream retries fail visibly.
This Actor focuses on reusable listing identity and contact/location fields. It does not claim to return ratings, reviews, photos, opening hours, or complete coverage when those fields are not present in the public search response.
What Apple Maps data can I extract?
| Field | Meaning |
|---|---|
placeId | Stable Apple Maps place identifier, normally the MUID |
appleMapsId | MapKit search result identifier |
name | Public business or place name |
category | Apple Maps point-of-interest category |
address | Combined formatted address |
addressLines | Source address split into lines |
city | Locality or city |
neighborhood | Source sub-locality, when available |
county | Source sub-administrative area, when available |
timezone | Source IANA timezone, when available |
timezoneSecondsFromGmt | Source UTC offset in seconds at collection time; not a permanent DST guarantee |
state | Administrative region name or code |
postalCode | Postal or ZIP code |
country, countryCode | Country fields from Apple Maps |
phone | Public telephone number when available |
website | Public business website when available |
latitude, longitude | Place coordinates in decimal degrees |
appleMapsUrl | Canonical public Apple Maps place URL |
searchTerm | Keyword or place name used for lookup |
requestedLocation | Original location text, when supplied |
sourceInput | Keyword or Apple Maps URL that produced the row |
scrapedAt | UTC collection timestamp |
Optional fields are omitted when Apple Maps does not provide them. Do not interpret a missing phone or website as proof that the business has none.
How to scrape Apple Maps business listings
- Open the Actor input page.
- Add one or more values to Business categories or keywords.
- Enter a city, neighborhood, postal code, or address in Location.
- Alternatively, provide exact Coordinates or one or more Apple Maps URLs.
- Select
countryCodeandlanguageappropriate for the market. - Set
maxResultsPerSearchandmaxItemsto bound the run. - Start the run.
- Open the Business listings dataset view.
- Export JSON, CSV, Excel, XML, or RSS, or read the dataset through the API.
The prefilled example searches for coffee shops in Austin, Texas and is suitable for a first test.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
searchTerms | string array | prefilled example | Business categories or keywords; up to 50 |
location | string | prefilled example | Fallback center for jobs without coordinates; not geocoded when unused |
coordinates | object | none | Exact latitude and longitude; overrides location, but not a URL's own center |
appleMapsUrls | string array | none | Public Apple Maps search or place URLs with q/query; up to 100 |
countryCode | string | US | Two-letter ISO country filter |
language | string | en-US | Language tag for source labels |
maxResultsPerSearch | integer | 50 | Unique listing limit for each keyword or URL; 1–200 |
maxItems | integer | 200 | Global result cap across the run; 1–1,000 |
maxRequestRetries | integer | 3 | Retry count for network failures, HTTP 429, and HTTP 5xx; 0–6 |
Provide at least one non-empty searchTerms or appleMapsUrls entry. Arrays must contain strings. Coordinates must stay within valid geographic ranges. All jobs are parsed and validated before the start charge or Apple lookup. Limits must be finite safe integers; direct API values are clamped to the documented ranges (zero is not unlimited). Each trimmed keyword is a separate ranked source search, not an exact-name filter.
Input examples
Search one category by city
{"searchTerms": ["coffee shops"],"location": "Austin, Texas","countryCode": "US","maxResultsPerSearch": 10,"maxItems": 10}
Search several categories around coordinates
{"searchTerms": ["dentists", "coworking spaces", "fitness studios"],"coordinates": {"latitude": 30.2672,"longitude": -97.7431},"countryCode": "US","maxResultsPerSearch": 10,"maxItems": 30}
Resolve an Apple Maps place URL
{"appleMapsUrls": ["https://maps.apple.com/place?q=Daydreamer%20Coffee&auid=1585039323930825247&ll=30.2592149,-97.7389039"],"countryCode": "US","maxResultsPerSearch": 1,"maxItems": 1}
Replay a centered Apple Maps search URL
{"appleMapsUrls": ["https://maps.apple.com/search?query=coffee+shops¢er=30.2672,-97.7431&span=0.1,0.1"],"countryCode": "US","maxResultsPerSearch": 10,"maxItems": 10}
Both ll and center accept latitude,longitude. ll takes precedence when both exist, and both are validated. URL coordinates override input coordinates; input coordinates override a fallback named location. span and zoom are not an exhaustive area/radius contract. Short links and ID-only URLs are not supported.
Output example
This shortened record comes from the current Austin coffee-shop workflow:
{"placeId": "1585039323930825247","appleMapsId": "I15FF30DE01EC121F","name": "Daydreamer Coffee","neighborhood": "Downtown","county": "Travis County","timezone": "America/Chicago","timezoneSecondsFromGmt": -18000,"address": "80 Rainey St, Austin, TX 78701, United States","city": "Austin","state": "TX","postalCode": "78701","countryCode": "US","phone": "+17404000238","website": "https://www.daydreamer.coffee/","latitude": 30.2592149,"longitude": -97.7389039,"appleMapsUrl": "https://maps.apple.com/place?q=Daydreamer%20Coffee&auid=1585039323930825247&ll=30.2592149,-97.7389039","searchTerm": "coffee shops","requestedLocation": "Austin, Texas","sourceInput": "coffee shops","scrapedAt": "2026-08-26T20:09:06.558Z"}
Public source values can change between runs. The schema remains stable while optional properties may be absent. The Actor does not use AI or generate inferred listing fields.
How location and coverage work
A named location is resolved through Apple Maps only if a job needs fallback geography. Keywords use input coordinates first, otherwise the named location. URLs use their own ll/center first, then input coordinates, then the named location. An unusable but unused location string does not cause a centered URL-only run to geocode or fail.
For limits above a single response, the Actor checks a bounded grid of nearby centers and deduplicates results by stable place ID. This improves useful local coverage, but it is not a guarantee that every business in a city or radius will be returned. Apple controls ranking, source availability, and response size.
Coordinate searches are useful when exact repeatability matters. Named locations are easier for operators and scheduled Tasks.
A countryCode limits results to one country. Choose the code that matches the search market.
How much does it cost to collect Apple Maps business listings?
The Actor uses pay-per-event pricing:
- one
startevent at $0.001 per run; - one
itemevent for each accepted business listing written to the dataset.
The active per-listing tiers are:
| Apify plan tier | Price per accepted listing |
|---|---|
| FREE | $0.002944 |
| BRONZE | $0.00256 |
| SILVER | $0.0019968 |
| GOLD | $0.001536 |
| PLATINUM | $0.001024 |
| DIAMOND | $0.0007168 |
At the BRONZE tier, a 10-row test costs up to $0.0266 ($0.001 start + 10 × $0.00256). A three-category refresh capped at 30 rows costs up to $0.0778. A 100-row run costs up to $0.257.
Your maximum is predictable from the selected result limits: one run start plus at most maxItems item events. Duplicate, rejected, empty, and failed records do not produce item events.
Set a platform maximum total charge if you need an additional hard billing guard. Higher Apify plans receive the lower per-item tier prices shown above.
Recurring lead and directory refresh workflow
- Create a Task with categories, geography, and stable limits.
- Run it once and store
placeIdas the source key in your system. - Schedule the Task daily, weekly, or monthly.
- Export or consume the latest default dataset.
- Join current rows to prior rows by
placeId. - Treat new IDs as newly observed listings and compare supported fields for changes.
The Actor emits current snapshots; it does not maintain historical state or send change alerts itself. Use Apify schedules, webhooks, dataset integrations, or your own warehouse logic for comparison and notification.
Integrations and exports
You can connect results to:
- Google Sheets or Microsoft Excel for review;
- Airtable or a business directory database;
- HubSpot, Salesforce, or another CRM after applying your own contact rules;
- Zapier or Make through Apify integrations and webhooks;
- Amazon S3, Google Cloud Storage, or a data warehouse;
- n8n, custom Node.js/Python jobs, or an AI agent through the API.
Every run uses the default dataset, so standard Apify dataset export endpoints work without Actor-specific parsing.
Run through the Apify API
Replace <APIFY_TOKEN> with your token.
cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~apple-maps-business-listings-scraper/runs?token=<APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"searchTerms":["dentists"],"location":"Austin, Texas","maxItems":20}'
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/apple-maps-business-listings-scraper').call({searchTerms: ['dentists'],location: 'Austin, Texas',countryCode: 'US',maxItems: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("automation-lab/apple-maps-business-listings-scraper").call(run_input={"searchTerms": ["dentists"],"location": "Austin, Texas","countryCode": "US","maxItems": 20,})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
Use with MCP and AI agents
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/apple-maps-business-listings-scraper"
Claude Desktop
Add this server to the mcpServers object in Claude Desktop's MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/apple-maps-business-listings-scraper"}}}
Cursor
Open Settings → Tools & MCP, add an HTTP MCP server, and use the same Actor-specific URL shown above.
VS Code
Add the same HTTP server URL through your MCP-compatible VS Code extension or workspace MCP configuration, then enable the Actor tool for the current chat.
Example prompts:
- “Find up to 20 dentists on Apple Maps near Austin, Texas and return place IDs, websites, phones, and addresses.”
- “Resolve this Apple Maps place URL and give me the stable place ID and coordinates.”
- “Run three local categories around latitude 30.2672, longitude -97.7431 and group the dataset by category.”
Follow one run through to bounded results
- Discover a scoped tool subset. Keep the Actor-specific URL above. This selection also adds
get-actor-run,get-dataset-items,get-key-value-store-record, andabort-actor-run; it does not expose only one tool. Use scopedtools/listto discover actual names and argument schemas, then enable only the Actor/run/data tools needed for your workflow. Discovery is read-only, not authorization to execute or abort a run. - Start once and retain metadata. After authorizing the invocation, save the returned run ID, status, dataset ID and key-value store ID. IDs are not listing rows. Where
call-actoris used,waitSecsis 0–45 seconds (default 30), not a completion guarantee. For a nonterminal run, pollget-actor-runfor that same run with backoff of 2, 4, 8 seconds, capped at 10 seconds, and a total 120-second deadline. These are example consumer choices, not Actor or Apify defaults. Set each client request timeout above the selected server wait plus transport margin, within the remaining deadline. On client timeout, recover/check the known run instead of starting another; if the run ID is unknown, disclose uncertainty and do not blindly rerun. At the deadline, stop polling and report pending with the run ID. Report failed, timed-out or aborted runs honestly; available rows are partial, not a successful full result. - Fetch rows within a total context budget. After success, call
get-dataset-itemsusing the returneddefaultDatasetId, explicitoffset: 0,limit: 20, and fieldsplaceId,name,phone,website,address,latitude,longitude,appleMapsUrl, adapting the argument representation to the discovered schema. Prefer untransformed JSON. Page by source offsets and pagination metadata, not transformed row counts (filtering/unwinding can change counts). Admit at most 100 rows or 64 KiB of serialized UTF-8 result content across all pages, whichever comes first. A host-side consumer must inspect/process pages before model injection and enforce the byte ceiling even for an oversized row/page: omit or summarize it with explicit disclosure. If your client cannot intercept oversized responses, do not promise a hard byte guarantee or request unbounded results. Stop at exhaustion or budget; report rows returned, continuation offset, and whether results are partial/truncated. Keep the complete JSON/CSV export in Apify storage or downstream processing outside model context. This consumer budget does not reduce the Actor's collection limits, output fields, or stored dataset. - Inspect diagnostics and qualify context claims. Retrieve
RUN_SUMMARYthroughget-key-value-store-recordusing the saved store ID to distinguish duplicates, missing exact places and partial failures. Disclose pending/failed/partial/truncated outcomes rather than treating storage IDs or a preview as complete results. Host-side discovery, caching and progressive tool loading depend on the client and negotiated capabilities;tools/listtransport bytes are not necessarily model-visible context. Prompt caching does not guarantee universal token savings, and no numeric savings are promised here.
Review generated inputs and public contact data before using them in downstream outreach.
Reliability, retries, and failure behavior
The Actor creates a fresh temporary public MapKit session for every run. It retries only transient network failures, rate limits, and upstream server errors with bounded exponential backoff.
The run fails instead of returning misleading empty success when:
- neither search terms nor Apple Maps URLs are supplied;
- coordinates or country codes are malformed;
- a named location cannot be resolved;
- the public session bootstrap no longer returns a token;
- the structured endpoint returns an unexpected shape;
- retries are exhausted.
Deterministic HTTP 4xx other than 429 are attempted once, not retried. Each request has a 30-second timeout. No hidden browser or paid proxy fallback is used.
A valid search with no matching points of interest completes with zero rows. Check run status, dataset item count and RUN_SUMMARY in automated workflows.
Machine-readable run summary
The Run summary output links to the RUN_SUMMARY JSON record in the run's default key-value store. It contains schema, run status, phase, saved (successfully stored rows), and bounded jobs in keyword-then-URL input order. Each job has a zero-based jobIndex, mode, status, unique matched, new, deduplicated counts, and requests (logical searches, excluding HTTP retries).
Statuses are completed, already_seen, exact_not_found, no_results, failed, or skipped_global_limit. Exact IDs already returned by an earlier job are matches, not missing places. An exact ID not returned by Apple search gives exact_not_found, without a fake listing or item charge. A job skipped by the global cap was not checked. A fatal upstream/storage error fails the run and preserves partial counts where storage remains available; jobs after the failing job are not attempted or recorded. Bootstrap/geocode failures are distinguished by the run phase. Diagnostics contain no queries, URLs, headers or raw response bodies and incur no item charges.
Private error diagnostics
Failed operations send sanitized diagnostic input, exceptions, and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed. Reports are retained for 30 days. Normal successful searches and legitimate empty results are not reported as errors.
Limits and responsible expectations
- Search results are ranked and selected by Apple; the Actor does not guarantee exhaustive city or radius coverage.
- Public phone and website fields are optional.
- The Actor does not fetch ratings, reviews, photos, amenities, or opening hours.
- URL resolution requires a URL with a usable
qorqueryvalue. Exact place matching additionally usesauidwhen present. - Apple may change public responses, categories, rankings, or session behavior.
maxResultsPerSearchis capped at 200 andmaxItemsat 1,000.- There is no automatic residential proxy fallback, avoiding hidden proxy transfer cost.
Start with a small limit, inspect the output, and then schedule or scale the workflow.
Is scraping Apple Maps legal?
This Actor collects publicly accessible business listing data. Whether a particular use is lawful depends on your jurisdiction, purpose, data handling, and contractual obligations.
Use the Actor responsibly:
- collect only data you have a legitimate reason to process;
- respect applicable laws, source terms, and database rights;
- avoid sensitive-person profiling or prohibited discrimination;
- follow marketing, privacy, and do-not-contact rules before outreach;
- secure exported datasets and delete them when no longer needed;
- do not use the Actor to overload or disrupt the source.
Listings and run summaries remain in your Apify run storage under your account's retention settings until expiry or deletion. Temporary MapKit tokens are kept only in run memory. Public business contacts may include personal data: limit collection to your legitimate purpose and protect exports. No AI provider receives input or listings. Our private sanitized error reports expire after 30 days; remove run datasets/KV records and downstream exports when no longer needed.
Apple Maps is named only to identify the data source. This independent Automation Lab Actor is not affiliated with or endorsed by Apple.
This documentation is not legal advice.
Troubleshooting
The run says I must provide a search term or URL
Add at least one non-empty value to searchTerms or appleMapsUrls. An empty array does not create a search.
My location cannot be resolved
Use a more specific city, region, postal code, or address, confirm countryCode, or provide exact coordinates.
A business has no phone or website
Those fields are optional and are emitted only when present in the public Apple Maps search response. Try the canonical appleMapsUrl to review the current source listing.
I received fewer rows than the limit
Limits are maximums, not guarantees. Ranking, source response size, deduplication, exact URL filtering, and naturally sparse categories can all reduce the final count.
Should I enable a proxy?
No proxy input is needed. The Actor uses the current direct public structured route and intentionally avoids an unmeasured paid fallback.
Frequently asked questions
Can I search multiple categories in one run?
Yes. Add up to 50 searchTerms. maxResultsPerSearch applies to each and maxItems caps the entire run.
Can I search by coordinates?
Yes. Supply both latitude and longitude in coordinates. They override location for keyword searches.
Can I scrape an Apple Maps URL?
Yes. Public search and place URLs on maps.apple.com are supported when they include q or query. Place URLs with auid are filtered to that requested place ID.
Does the Actor monitor changes?
It produces current snapshots suitable for scheduled comparison. It does not store history or send alerts by itself.
Are duplicate businesses removed?
Yes. Records are deduplicated by stable MUID/result ID across the whole run.
Does it require an Apple account?
No. It uses the anonymous public Apple Maps web and MapKit data flow.
Related Automation Lab Actors
- Bing Maps Places Scraper — collect a comparable local-place dataset from Bing Maps.
- Foursquare Locations Scraper — collect Foursquare location and venue records.
- Naver Map Local Business Scraper — target Naver Map business data for supported markets.
Choose one source when its place identity is your system of record, or run several source-specific Actors and reconcile records in your own pipeline.
Support
If a valid public workflow stops working, open an issue from the Actor page and include:
- a redacted copy of the input;
- run ID;
- expected result;
- observed error or missing field;
- whether the same query currently works on the public Apple Maps website.
Do not include private credentials, customer data, or unrelated personal information.