← Back to Blog

Find what’s nearby — the ArcGIS Places service, from search to place details

Find what's nearby — the ArcGIS Places service, from search to place details

“Show me the coffee shops within a ten-minute walk” is one of the most common feature requests in any map-facing application — and one of the easiest to get wrong. Scrape a POI dataset and it goes stale; bolt on a third-party places API and you are juggling a second vendor, a second billing model, and a second set of terms. If you are already building on the Esri stack, the ArcGIS Places service answers the question natively: a hosted location service that searches businesses and geographic places worldwide, filters them by category and text, and returns per-place detail down to phone, website, and social handles.

The service is straightforward to call, but its billing architecture rewards developers who understand it — search requests and attribute requests are priced separately, and attribute fields are grouped into price tiers you opt into field-by-field. Get the pattern right and a places feature costs pennies; request all fields on every click and you are paying for data you never render. Here is how the service is put together, the working code, and the cost-control patterns we use in client apps.

What the Places service is — and where it runs

The Places service is one of the ArcGIS Location Services, alongside basemap styles, geocoding, routing, GeoEnrichment, and elevation. It lives at a single REST endpoint:

https://places-api.arcgis.com/arcgis/rest/services/places-service/v1

Every request authenticates with an access token — an API key credential or OAuth 2.0 token — that carries the places service privilege. Results include category metadata and icon resources so you can style what comes back without shipping your own symbol set.

Account check before you design around it: per Esri’s service documentation, the Places service is supported for ArcGIS Location Platform accounts only — the pricing table lists ArcGIS Online as “not supported,” and ArcGIS Enterprise is not supported either. If your organization authenticates everything through an ArcGIS Online org account, plan on minting the places token from a Location Platform account. That single line in the docs has rerouted more than one architecture diagram.

Five requests, one mental model

The whole service surface is five requests. Two find places, one enriches them, and two navigate the category tree:

RequestWhat it doesPrice category
/places/near-pointNearby search: places within a radius of a pointSearch
/places/within-extentBounding-box search: places inside an extentSearch
/places/{placeId}Place details: attributes for one place, field by fieldAttribute groups
/categoriesList or filter the category vocabularyFree
/categories/{categoryId}Details for one categoryFree

The intended flow: a search returns lightweight results — placeId, name, categories, location, and distance — and the placeId is your ticket to the details endpoint when, and only when, a user actually asks for more.

Nearby search: radius, categories, text

A nearby search takes an x/y in WGS84 decimal degrees plus a radius in meters. The default radius is 1,000 m and the maximum is 10,000 m. Esri’s own best-practice note says it plainly: always refine with categoryIds and/or searchText rather than pulling everything in range.

In the ArcGIS Maps SDK for JavaScript, the places module wraps the request in one call:

import * as places from "@arcgis/core/rest/places.js";

// coffee within a 10-minute walk of downtown Ann Arbor
const results = await places.queryPlacesNearPoint({
  point: { x: -83.7430, y: 42.2808 },
  radius: 800,                                // meters; default 1000, max 10000
  categoryIds: ["4bf58dd8d48988d16d941735"],  // Cafe
  searchText: "coffee"
});

for (const place of results.results) {
  console.log(place.name, place.distance, place.placeId);
}

Each page returns at most 20 places. If more match, the response carries paging links — in REST you follow pagination.nextUrl (re-attaching your token); in the JS SDK you call nextPage() on the response while nextPage is valid. Paging tops out at 200 places per search. If you are hitting that ceiling, Esri’s guidance is to shrink the radius or tighten the category filter — a places UI that needs more than 200 pins probably needs a better question, not more results.

Billing detail worth knowing: search requests are charged per request — including each paging request — but only when results are returned. An empty search costs nothing. That makes speculative searches (say, firing a search on every map click) cheaper than you might fear in sparse areas, and more expensive than you planned in dense ones. Debounce accordingly.

Place details: pay only for the fields you name

The details endpoint is where the design gets interesting. You pass a placeId and a requestedFields array naming exactly the attributes you want back:

const details = await places.fetchPlace({
  placeId: "bd5f5dfa788b7c5f59f3bfe2cc3d9c60",
  requestedFields: [
    "name",
    "address:streetAddress",
    "contactInfo:telephone",
    "contactInfo:website"
  ]
});

Fields are organized into four price groups, and you are billed once per group touched, no matter how many fields you request from that group:

Price groupExample fieldsLocation Platform price
Placename, categories100 free, then $0.05 / 1,000 places
Locationlocation100 free, then $0.35 / 1,000 places
Addressaddress:streetAddress, address:locality, address:postcode100 free, then $0.10 / 1,000 places
DetailscontactInfo:*, socialMedia:*100 free, then $0.13 / 1,000 places

Searches themselves are priced separately: 500 free per month, then $8.00 per 1,000 on Location Platform. Category requests are free. Two more billing rules matter in practice: you are only charged for attributes that come back with valid values (nulls are free), and requesting two fields from two different groups bills both groups. The anti-pattern is requestedFields: "all" — the docs support it, and the docs also warn against it, because you are charged for every group with data even if your UI shows two lines.

Data honesty note: Esri documents that, due to limitations in the current underlying data source, some documented fields presently return null — including hours:*, rating:*, description, chains, and the additionalLocations group. Nulls are not billed, but design your details panel around the fields that reliably populate today: name, categories, location, address, phone, website, and social handles. Check the service’s release notes before building UI on the currently-null fields.

Patterns that keep a places feature premium — and cheap

Where this lands in a real app

We reach for the Places service when an application needs context around a location the user already cares about: amenities near a property in a parcel explorer, services around a proposed site in a suitability tool, points of interest along a route. It replaces a third-party POI dependency with a service that speaks the same authentication, the same terms, and the same SDK as the rest of the stack — one vendor, one token store, one invoice. And because the billing is per-use with a free tier, a places feature can ship in a prototype for $0 and scale linearly with real usage.

References

Want a places feature that feels native to your app?

We build branded, production-grade ArcGIS applications on Location Platform services — places, geocoding, routing — with the token hygiene and cost controls already wired in.

Book a free intro call