Scrape Apple Maps search results with SerpApi's Apple Maps API. Search places by keyword and area, and get each place's MUID, name, coordinates, address, phone, website, ratings, reviews, opening hours, amenities, photos, and the guides that feature it.
Search Apple Maps with a simple GET request:
https://serpapi.com/search?engine=apple_maps&query=coffee&location=Austin,+Texas,+United+States&api_key=SERPAPI_API_KEY
queryis the search query: anything you'd use in an Apple Maps search, such as a category, a business name, or an address.locationis the area to search in, e.g.,Austin, Texas, United States. Usecenterwithlatitude,longitudecoordinates instead for a precise point. One of them is required.api_keyis your SerpApi API key. ReplaceSERPAPI_API_KEYwith it.sortorders the places bydistanceorratingsinstead of the best match.togglesandmulti_select_optionsfilter the places with the keys inrefinementfrom a previous response, e.g.,OPEN_NOW.localesets the language and region of the results, e.g.,en-USorfr-FR.
Register at SerpApi to get your API key, and keep it private.
Try the request live in the SerpApi Playground.
The code examples read your API key from the SERPAPI_API_KEY environment variable:
export SERPAPI_API_KEY="SERPAPI_API_KEY"Each example searches Apple Maps for coffee in Austin, Texas, and prints the position, title, and address of each place.
Send the request with curl, which prints the full JSON response:
curl --get https://serpapi.com/search \
--data-urlencode engine="apple_maps" \
--data-urlencode query="coffee" \
--data-urlencode location="Austin, Texas, United States" \
--data-urlencode api_key="$SERPAPI_API_KEY"Install the SerpApi JavaScript library and set your project to use ES modules:
npm install serpapi
npm pkg set type=moduleCreate an index.js file:
import { getJson } from "serpapi";
const results = await getJson({
engine: "apple_maps",
api_key: process.env.SERPAPI_API_KEY,
query: "coffee",
location: "Austin, Texas, United States",
});
for (const place of results.local_results ?? []) {
console.log(place.position, place.title, place.address);
}Run it with node index.js.
Install the SerpApi Python library:
pip install serpapiCreate a main.py file:
import os
import serpapi
client = serpapi.Client(api_key=os.getenv("SERPAPI_API_KEY"))
results = client.search({
"engine": "apple_maps",
"query": "coffee",
"location": "Austin, Texas, United States",
})
for place in results.get("local_results", []):
print(place["position"], place["title"], place["address"])Run it with python main.py.
Install the SerpApi Ruby library:
gem install serpapiCreate a main.rb file:
require "serpapi"
client = SerpApi::Client.new(engine: "apple_maps", api_key: ENV.fetch("SERPAPI_API_KEY"))
results = client.search(query: "coffee", location: "Austin, Texas, United States")
results.fetch(:local_results, []).each do |place|
puts "#{place[:position]} #{place[:title]} #{place[:address]}"
end
client.closeRun it with ruby main.rb.
Install the SerpApi PHP library:
composer require serpapi/serpapi-phpCreate an index.php file:
<?php
require 'vendor/autoload.php';
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_API_KEY'), 'apple_maps');
$results = $client->search([
'query' => 'coffee',
'location' => 'Austin, Texas, United States',
]);
foreach ($results->local_results ?? [] as $place) {
echo $place->position . ' ' . $place->title . ' ' . $place->address . PHP_EOL;
}Run it with php index.php.
Create a Go module and install the SerpApi Go library:
go mod init example.com/maps
go get github.com/serpapi/serpapi-golangCreate a main.go file:
package main
import (
"fmt"
"os"
"github.com/serpapi/serpapi-golang"
)
func main() {
setting := serpapi.NewSerpApiClientSetting(os.Getenv("SERPAPI_API_KEY"))
setting.Engine = "apple_maps"
client := serpapi.NewClient(setting)
results, err := client.Search(map[string]string{
"query": "coffee",
"location": "Austin, Texas, United States",
})
if err != nil {
panic(err)
}
localResults, _ := results["local_results"].([]interface{})
for _, item := range localResults {
place := item.(map[string]interface{})
fmt.Println(place["position"], place["title"], place["address"])
}
}Run it with go run ..
Create a Cargo project and add the SerpApi Rust library and Tokio:
cargo new maps && cd maps
cargo add serpapi tokio --features tokio/fullReplace src/main.rs with:
use serpapi::serpapi::Client;
use std::collections::HashMap;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut default = HashMap::new();
default.insert("api_key".to_string(), env::var("SERPAPI_API_KEY")?);
default.insert("engine".to_string(), "apple_maps".to_string());
let client = Client::new(default)?;
let mut parameter = HashMap::new();
parameter.insert("query".to_string(), "coffee".to_string());
parameter.insert("location".to_string(), "Austin, Texas, United States".to_string());
let results = client.search(parameter).await?;
if let Some(local_results) = results["local_results"].as_array() {
for place in local_results {
println!(
"{} {} {}",
place["position"],
place["title"].as_str().unwrap_or_default(),
place["address"].as_str().unwrap_or_default()
);
}
}
Ok(())
}Run it with cargo run.
Official libraries are also available for Java, .NET, Swift, and C++. See SerpApi integrations for setup guides, or use a simple GET request from any programming language.
Failed requests return an HTTP error status and a JSON body with an error message. The most common are 401 for an invalid API key, 400 for a missing required parameter such as query, and 429 when you exceed your hourly throughput limit or run out of searches. See API status and error codes for the full list.
Choose structured JSON for applications or Markdown for LLMs and AI agents:
- JSON is the default output and is useful when you need individual result fields.
- Add
output=mdto receive Markdown instead, which is more token-efficient.
Markdown is plain text, not JSON: YAML front matter with the search metadata, followed by tables of the places. Read the response body as text instead of parsing it.
| Client | Markdown request |
|---|---|
| curl | --data-urlencode output="md" |
| Python | client.search({..., "output": "md"}) |
| PHP | $client->md([...]) |
| Rust | client.md(parameter).await? |
If your SDK doesn't have a Markdown helper yet, send a plain HTTP request with output=md and read the body as text. Learn more about Markdown output.
See the Apple Maps API documentation for more details.
| Name | Description | Requirement |
|---|---|---|
| Search query | ||
query |
The search query: anything you'd use in a regular Apple Maps search (e.g., coffee). |
Required |
| Geographic location | ||
center |
The center of the area to search, as latitude,longitude (e.g., 30.324639,-97.7304611 for Austin, Texas). Either center or location is required, and they can't be used together. |
Optional |
span |
The width and height of the area to search, as latitudeDelta,longitudeDelta (e.g., 0.05,0.05). Smaller values search a smaller area. |
Optional |
location |
The location to search from (e.g., Austin, Texas, United States). Either center or location is required, and they can't be used together. |
Optional |
| Refinement parameters | ||
sort |
The order of the places: default for the best match (default), distance from the center or location, or ratings. |
Optional |
toggles |
Comma-separated toggle keys to filter the places by (e.g., OPEN_NOW). The available toggles are in refinement.toggles of the response. |
Optional |
multi_select_options |
Comma-separated option keys to filter the places by, such as chains, prices, or amenities. The available options are in refinement.multi_select of the response. |
Optional |
open_at |
Only return places open at this time, as a Unix timestamp in the next 24 hours (e.g., 1793819769). |
Optional |
| Localization | ||
locale |
The language and region of the results, as <LANGUAGE>-<REGION> (e.g., en-US, fr-FR). Defaults to en-US. See Apple Maps locales for supported locales. |
Optional |
| SerpApi parameters | ||
engine |
Set to apple_maps. |
Required |
api_key |
Your private SerpApi API key. | Required |
no_cache |
Set to true to request fresh results instead of using the one-hour cache. Can't be combined with async. |
Optional |
async |
Set to true for later retrieval through the Searches Archive API. Can't be combined with no_cache or used with Ludicrous Speed enabled. |
Optional |
zero_trace |
Enterprise only. Set to true to skip storing search parameters, files, and metadata on SerpApi servers. |
Optional |
output |
Set to json (default), html for the raw HTML retrieved, or md for Markdown. |
Optional |
json_restrictor |
Limit the JSON response to the fields you need. See the JSON Restrictor documentation. | Optional |
Each item in local_results is a place, and each item in guide_results is a guide of places, such as The Best Coffee Shops In Austin. When the query matches a single place, it's returned in place_results instead. The field guides below describe the possible fields and their types; they aren't literal API responses.
Some fields appear only when Apple Maps shows them:
| Place | Fields |
|---|---|
| A place with reviews from Yelp or Tripadvisor | user_reviews with the most relevant reviews, plus SerpApi links to the place and its reviews with the matching API |
| A place with a price level | price, e.g., $$, price_score, and max_price_score |
| A place with online ordering | actions, e.g., Order or Menu, and order_online |
| A place described by a publisher | text, e.g., a review from The Infatuation |
| A place featured in guides | collection with the guides |
| A place inside a larger place | contained_place and located_in, e.g., Downtown, Austin |
Each place has a muid and a serpapi_link to its details with the Apple Maps Places API.
Each place in local_results can include these fields:
{
"local_results": [
{
"position": "Integer - Position of the place in the local results",
"position_in_page": "Integer - Position of the place on the page, counting guides",
"muid": "String - Apple Maps ID of the place",
"provider_id": "Integer - ID of the data provider",
"link": "String - Link to the place on Apple Maps",
"serpapi_link": "String - SerpApi link to the details of the place",
"title": "String - Name of the place",
"gps_coordinates": {
"latitude": "Float - Latitude of the place",
"longitude": "Float - Longitude of the place"
},
"rating": "Float - Rating of the place, e.g., 4.46 out of 5, or 91 out of 100 for Apple ratings",
"max_rating": "Integer - Maximum rating: 5, or 100 for Apple ratings",
"reviews": "Integer - Number of reviews",
"ratings": {
"attribution": {
"name": "String - Source of the ratings, e.g., Apple, Yelp, or Foursquare",
"link": "String - Link to the place on the source"
},
"values": [
{
"type": "String - Type of rating: USER_RATING, APPLE_RATING, or PRICE_RANGE",
"category": "String - What Apple Maps users rated, e.g., Food & Drink",
"rating": "Float - Rating, e.g., 4.46, or a percentage for Apple ratings",
"max_rating": "Integer - Maximum rating, e.g., 5, or 100 for Apple ratings",
"reviews": "Integer - Number of reviews or ratings"
}
]
},
"address": "String - Full address of the place",
"structured_address": {
"short": "String - Short address, e.g., 401 Congress Ave, Austin",
"formatted_lines": "Array[String] - Lines of the address",
"city_and_above": "String - City, state, and country, e.g., Austin, TX United States",
"country": "String - Country, e.g., United States",
"country_code": "String - Two-letter country code, e.g., US",
"administrative_area": "String - State or region, e.g., Texas",
"sub_administrative_area": "String - County, e.g., Travis",
"locality": "String - City, e.g., Austin",
"post_code": "String - Postal code, e.g., 78701",
"sub_locality": "String - Neighborhood, e.g., Congress Ave District",
"thoroughfare": "String - Street, e.g., Congress Ave",
"full_thoroughfare": "String - Street and number, e.g., 401 Congress Ave",
"dependent_locality": "Array[String] - Areas the place is in, e.g., Downtown"
},
"phone": "String - Phone number, e.g., +15123946051",
"phone_formatted": "String - Formatted phone number, e.g., +1 (512) 394-6051",
"website": "String - Website of the place",
"about": "String - Description of the place by the business",
"unclaimed_listing": "Boolean - Whether the business hasn't claimed the place on Apple Business Connect",
"claim_listing_link": "String - Link to claim the place",
"amenities": [
{
"name": "String - Amenity, e.g., Accepts Apple Pay",
"id": "String - ID of the amenity, e.g., crossbusiness.payments.applepay"
}
],
"timezone": "String - Time zone of the place, e.g., America/Chicago",
"open_state": "String - Whether the place is open now, e.g., Open till 7 PM",
"weekly_hours": {
"monday": "Array[String] - Opening hours on Monday, e.g., 06:30 - 19:00"
},
"images": [
{
"thumbnail": "String - Link to the photo",
"title": "String - Caption of the photo",
"category_id": "String - ID of the photo category, e.g., foodanddrink",
"category_name": "String - Name of the photo category, e.g., Food & Drink",
"attribution": {
"name": "String - Source of the photo, e.g., Foursquare",
"link": "String - Link to the photo on the source"
}
}
],
"contained_place": {
"type": "String - Type of the place, e.g., Coffee Shop",
"name": "String - Name of the larger place, e.g., Downtown, Austin",
"muid": "String - Apple Maps ID of the larger place",
"link": "String - Link to the larger place on Apple Maps",
"serpapi_link": "String - SerpApi link to the details of the larger place"
},
"located_in": "String - Name of the larger place",
"actions": [
{
"title": "String - Action, e.g., Order or Menu",
"links": "Array[String] - Links to take the action"
}
],
"order_online": "String - Link to order online",
"text": {
"title": "String - Source of the description, e.g., The Infatuation",
"value": "String - Description of the place",
"attribution_url": "String - Link to the description on the source"
},
"user_reviews": {
"attribution": {
"name": "String - Source of the reviews, e.g., Yelp",
"link": "String - Link to the place on the source",
"serpapi_yelp_place_link": "String - SerpApi link to the place with the Yelp Place API",
"serpapi_yelp_reviews_link": "String - SerpApi link to the reviews with the Yelp Reviews API"
},
"most_relevant": [
{
"username": "String - Name of the reviewer",
"rating": "Integer - Rating of the review",
"max_rating": "Integer - Maximum rating, e.g., 5",
"user_thumbnail": "String - Link to the photo of the reviewer",
"description": "String - Text of the review",
"link": "String - Link to the review",
"date": "String - Date of the review, e.g., 2026-09-01 14:24:58 +0000",
"id": "String - ID of the review"
}
]
},
"price": "String - Price level, e.g., $$",
"price_score": "Integer - Price level as a number, e.g., 2",
"max_price_score": "Integer - Maximum price level, e.g., 4",
"types": "Array[String] - Types of the place, e.g., Dining, Coffee Shop, Cafe",
"type_ids": "Array[String] - IDs of the types, e.g., dining, coffee_shop, cafe",
"type": "String - Main type of the place, e.g., Coffee Shop",
"type_id": "String - ID of the main type, e.g., coffee_shop",
"collection": "Array[Object] - Guides featuring the place, with the same fields as guide_results",
"attribution": {
"name": "String - Main data provider of the place, e.g., Foursquare or Yelp",
"link": "String - Link to the place on the provider",
"serpapi_yelp_place_link": "String - SerpApi link to the place with the Yelp Place API, if the provider is Yelp"
}
}
]
}weekly_hours has a key for each day of the week, from monday to sunday.
Each guide in guide_results can include these fields:
{
"guide_results": [
{
"position": "Integer - Position of the guide in the guide results",
"position_in_page": "Integer - Position of the guide on the page, counting places",
"muid": "String - Apple Maps ID of the guide",
"title": "String - Title of the guide, e.g., The Best Coffee Shops In Austin",
"description": "String - Description of the guide",
"link": "String - Link to the guide on the publisher's website",
"apple_maps_link": "String - Link to the guide on Apple Maps",
"item_count": "Integer - Number of places in the guide",
"publisher": {
"name": "String - Name of the publisher, e.g., The Infatuation",
"subtitle": "String - Tagline of the publisher",
"link": "String - Website of the publisher"
},
"photos": [
{
"link": "String - Link to the cover photo",
"width": "Integer - Width in pixels",
"height": "Integer - Height in pixels"
}
],
"items": [
{
"muid": "String - Apple Maps ID of a place in the guide",
"link": "String - Link to the place on Apple Maps",
"serpapi_link": "String - SerpApi link to the details of the place"
}
]
}
]
}refinement lists the filters available for the search. Pass the key values to toggles or multi_select_options:
{
"refinement": {
"toggles": {
"open_now": {
"display_name": "String - Name of the filter, e.g., Open Now",
"key": "String - Value for the toggles parameter, e.g., OPEN_NOW"
}
},
"multi_select": {
"price": {
"display_name": "String - Name of the filter, e.g., All Prices",
"options": [
{
"display_name": "String - Name of the option, e.g., $",
"key": "String - Value for the multi_select_options parameter"
}
]
}
},
"sort": "String - Sort order applied to the search: default, distance, or ratings"
}
}The available filters depend on the search, e.g., Open Now, Top Rated, and Free Wi-Fi toggles, or chain, price, and amenity options for coffee shops.
Give AI agents and assistants an Apple Maps search tool with the hosted SerpApi MCP server at https://mcp.serpapi.com/mcp.
Claude Code:
claude mcp add --transport http serpapi https://mcp.serpapi.com/mcp --header "Authorization: Bearer $SERPAPI_API_KEY"Codex, which reads the key from SERPAPI_API_KEY:
codex mcp add serpapi --url https://mcp.serpapi.com/mcp --bearer-token-env-var SERPAPI_API_KEYOther MCP clients:
{
"mcpServers": {
"serpapi": {
"type": "http",
"url": "https://mcp.serpapi.com/SERPAPI_API_KEY/mcp"
}
}
}The server's engine catalog includes the apple_maps engine, and its serpapi://engines/apple_maps resource describes the parameters. Ask your agent to search Apple Maps with the apple_maps engine. The resulting tool call looks like this:
{
"name": "search",
"arguments": {
"params": {
"engine": "apple_maps",
"query": "coffee",
"location": "Austin, Texas, United States"
}
}
}See the MCP integration guide for more clients and self-hosting.
Search Apple Maps from your terminal or from AI agent workflows with the SerpApi CLI:
brew tap serpapi/homebrew-tap
brew install serpapi-cliThe CLI picks up SERPAPI_API_KEY from your environment. You can also run serpapi login to save a key.
serpapi search engine=apple_maps query=coffee location="Austin, Texas, United States"
serpapi search engine=apple_maps query=coffee location="Austin, Texas, United States" --fields "local_results[].{title, address, rating}"
serpapi search engine=apple_maps query=coffee location="Austin, Texas, United States" output=mdUse SerpApi APIs without writing code:
- Build lead lists of local businesses with phone numbers, websites, and addresses.
- Monitor how your business and its competitors appear on Apple Maps, including ratings and opening hours.
- Find places that haven't been claimed on Apple Business Connect.
- Compare Apple Maps and Google Maps results for the same search.
- Discover popular places from guides by publishers like The Infatuation.
- Give AI agents and RAG pipelines a local search tool.
- Apple Maps Places Scraper: details of places by their MUID
- Google Maps Scraper: places on Google Maps
- Google Local Scraper: local results from Google Search
Feel free to reach out at contact@serpapi.com.
