Query your Storepoint location data to build custom experiences: bespoke store locator UIs, mobile apps, kiosks, or any integration. Your team manages locations in the dashboard while developers query the data via this API.
Storepoint's store locator app for websites works beautifully out of the box with no code required. This API is for developers who want to build custom location experiences in addition to, or instead of, the standard locator.
This API queries the locations you've published in your Storepoint locator. It uses your public locator token and can safely be called from frontend code. For managing locations programmatically (create, update, delete), use the Location Management API with a private API key instead.
This API gives developers direct access to the location data managed in Storepoint. Use it to build custom location experiences while your team continues managing locations via the dashboard, imports, Google Sheets sync, or the Location Management API.
Already have locations in Storepoint? Here's how to query them:
const LOCATOR_TOKEN = 'your_locator_token'; // Find this in your Storepoint dashboard
fetch(`https://api.storepoint.co/public/v1/${LOCATOR_TOKEN}/locations?lat=40.7128&lng=-74.0060&radius=25`)
.then(response => response.json())
.then(data => {
data.data.locations.forEach(location => {
console.log(location.name, location.distance.value + ' miles');
});
});
Your locator token is in your Storepoint dashboard under Developer Tools. It's the same token used in your locator embed code.
Storepoint is the easiest way to add a store locator to your website. Start a free trial to add your locations, then use this API to query them in your custom frontend.
The Location Query API uses your public locator token in the URL path. No API key header is required.
https://api.storepoint.co/public/v1/{locator_token}/
This API only accesses the locations you've published in your Storepoint locator, the same locations visible in your embedded locator. Since it's read-only and only returns your published locations, the locator token can safely be used in frontend code.
Never use your private API key in frontend code. The private key is for server-side use only with the Location Management API. If you accidentally expose it, rotate it immediately in your Storepoint dashboard.
| Endpoint | Description |
|---|---|
GET /locations |
Query locations with filtering, sorting, and pagination |
GET /locations/{id} |
Get a single location by its public ID |
GET /filters |
Get filter/tag configuration for building filter UIs |
Retrieve locations with optional geographic filtering, tag filtering, and sorting.
GET /locations
lat
number
required*
Latitude of search center point (-90 to 90)
lng
number
required*
Longitude of search center point (-180 to 180)
radius
number
optional
Search radius. Default: your locator's configured radius, or 25 if not set.
unit
string
optional
miles or km. Default: miles
limit
number
optional
Maximum results to return. Default: 20, Maximum: 500
offset
number
optional
Number of results to skip for pagination. Default: 0
tags
array
optional
Filter by tags. Example: ?tags[]=retail&tags[]=flagship
tagLogic
string
optional
any, all, or match. See Filtering by Tags. Default: any
search
string
optional
Keyword search across name, address, description, and tags
sort
string
optional
distance, name, or priority. See Sorting. Default: distance
all
boolean
optional
Set to true to return all locations without requiring lat/lng. Useful for pre-loading or static maps.
* lat and lng are required unless all=true
GET /locations?lat=40.7128&lng=-74.0060&radius=25&unit=miles&limit=10
Retrieve a specific location by its public ID.
GET /locations/{id}
The id is the location's public ID (format: loc_ followed by alphanumeric characters), returned in query results.
Retrieve your filter/tag configuration to build custom filter UIs. Call this endpoint before loading locations to render your filter dropdowns or checkboxes.
GET /filters
{
"success": true,
"data": {
"filters": [
{
"id": "_default",
"name": "Categories",
"label": "Filter by Category",
"singleSelect": false,
"inline": false,
"hidden": false,
"hideInLocationDetails": false,
"tags": [
{ "value": "retail", "label": "Retail", "color": "#3B82F6" },
{ "value": "wholesale", "label": "Wholesale" }
]
},
{
"id": "features",
"name": "Features",
"label": "Filter by Features",
"singleSelect": false,
"inline": true,
"hidden": false,
"hideInLocationDetails": false,
"tags": [
{ "value": "parking", "label": "Free Parking", "color": "#10B981" },
{ "value": "accessible", "label": "Wheelchair Accessible" }
]
}
]
}
}
id - Group identifier (used with tagLogic=match for AND across groups)singleSelect - If true, only one tag can be selected at a time in this groupinline - Suggested display style: inline buttons vs dropdownhidden - If true, this filter is hidden in the standard locator (you may still want to show it)tags[].value - The tag value to use in ?tags[]= parametertags[].label - Display label for the tagtags[].color - Optional hex color for stylingtags[].image - Optional image URL for the tagAll responses follow a consistent structure:
{
"success": true,
"data": {
"locations": [
{
"id": "loc_abc123def456",
"name": "Downtown Flagship Store",
"coordinates": {
"lat": 40.7128,
"lng": -74.0060
},
"address": {
"street": "123 Main Street",
"city": "New York",
"state": "NY",
"postalCode": "10001",
"country": "USA",
"formatted": "123 Main Street, New York, NY 10001"
},
"contact": {
"phone": "+1 212-555-1234",
"email": "[email protected]",
"website": "https://example.com"
},
"social": {
"instagram": "storename",
"facebook": "storename",
"twitter": "storename"
},
"hours": {
"monday": "9:00am - 6:00pm",
"tuesday": "9:00am - 6:00pm",
"wednesday": "9:00am - 6:00pm",
"thursday": "9:00am - 8:00pm",
"friday": "9:00am - 8:00pm",
"saturday": "10:00am - 6:00pm",
"sunday": "Closed"
},
"tags": {
"_default": {
"name": "Categories",
"items": [
{ "value": "retail", "label": "Retail", "color": "#3B82F6" },
{ "value": "flagship", "label": "Flagship" }
]
},
"features": {
"name": "Features",
"items": [
{ "value": "parking", "label": "Free Parking", "color": "#10B981" }
]
}
},
"customFields": [
{
"token": "abc123",
"key": "book_appointment",
"name": "Book Appointment",
"type": "button",
"value": "https://booking.example.com",
"label": "Book Now",
"color": "#FF5733"
}
],
"image": "https://cdn.example.com/store.jpg",
"description": "Our flagship downtown location.",
"distance": {
"value": 2.5,
"unit": "miles"
}
}
],
"pagination": {
"offset": 0,
"limit": 20,
"total": 150,
"hasMore": true
}
},
"meta": {
"query": {
"center": { "lat": 40.7128, "lng": -74.0060 },
"radius": 25,
"unit": "miles"
}
}
}
id - Unique public location IDcoordinates - Latitude and longitudeaddress - Structured address with parsed components and formatted stringcontact - Phone, email, and websitesocial - Social media handleshours - Operating hours by day (raw text as configured)tags - Tags organized by group, each with display metadatacustomFields - Ordered array of custom fields with full metadata (type, label, color, icon)distance - Distance from search point (only present for radius queries)Filter locations by tags using the tags[] parameter. Control matching logic with tagLogic:
tagLogic=any (default)
Location matches if it has ANY of the specified tags (OR logic)
Example: ?tags[]=retail&tags[]=wholesale returns locations with retail OR wholesale
tagLogic=all
Location must have ALL specified tags (AND logic)
Example: ?tags[]=retail&tags[]=parking&tagLogic=all returns locations with both retail AND parking
tagLogic=match
AND across filter groups, OR within groups. This matches how multi-select filter UIs typically work.
Example: If "retail" and "wholesale" are in the Categories group, and "parking" is in Features, selecting retail + parking returns locations with (retail OR wholesale from Categories) AND (parking from Features)
Control result order with the sort parameter:
distance (default for radius queries) - Closest locations firstname (default for all=true) - Alphabetical by namepriority - Apply your configured priority sorting rulesIf you've configured priority rules in your Storepoint dashboard (e.g., "show flagship stores first within 10 miles"), use sort=priority to apply them. This is useful for promoting certain location types in search results.
Use limit and offset for pagination:
# First page (results 1-20)
GET /locations?lat=40.7&lng=-74.0&limit=20&offset=0
# Second page (results 21-40)
GET /locations?lat=40.7&lng=-74.0&limit=20&offset=20
The response includes pagination metadata with convenient next/prev URLs:
{
"pagination": {
"offset": 20,
"limit": 20,
"total": 150,
"hasMore": true,
"next": "https://api.storepoint.co/public/v1/abc123/locations?lat=40.7&lng=-74.0&limit=20&offset=40",
"prev": "https://api.storepoint.co/public/v1/abc123/locations?lat=40.7&lng=-74.0&limit=20"
}
}
offset - Current offset positionlimit - Number of results per pagetotal - Total number of matching locationshasMore - Whether more results exist beyond this pagenext - Full URL to fetch the next page (only present if hasMore is true)prev - Full URL to fetch the previous page (only present if not on first page)Errors return a consistent structure with helpful messages:
{
"success": false,
"error": {
"code": "MISSING_COORDINATES",
"message": "Either provide lat and lng parameters for radius search, or set all=true to retrieve all locations",
"docs": "https://storepoint.co/developers/location-query-api#query-locations"
}
}
INVALID_TOKEN (404) - Locator token not found or inactiveMISSING_COORDINATES (400) - lat/lng required unless all=trueINVALID_COORDINATES (400) - lat/lng out of valid rangeINVALID_PARAMETER (400) - Parameter validation failedLOCATION_NOT_FOUND (404) - Location ID not foundSECRET_KEY_EXPOSED (400) - Private API key used in public endpoint (rotate your key!)const LOCATOR_TOKEN = 'your_locator_token';
const BASE_URL = `https://api.storepoint.co/public/v1/${LOCATOR_TOKEN}`;
// Query locations near a point
async function findNearbyLocations(lat, lng, radius = 25) {
const response = await fetch(
`${BASE_URL}/locations?lat=${lat}&lng=${lng}&radius=${radius}`
);
const data = await response.json();
if (data.success) {
return data.data.locations;
} else {
throw new Error(data.error.message);
}
}
// Get filter configuration for UI
async function getFilters() {
const response = await fetch(`${BASE_URL}/filters`);
const data = await response.json();
return data.data.filters;
}
// Usage
const locations = await findNearbyLocations(40.7128, -74.0060, 25);
locations.forEach(loc => {
console.log(`${loc.name} - ${loc.distance.value} ${loc.distance.unit}`);
});
import requests
LOCATOR_TOKEN = 'your_locator_token'
BASE_URL = f'https://api.storepoint.co/public/v1/{LOCATOR_TOKEN}'
def find_nearby_locations(lat, lng, radius=25):
response = requests.get(
f'{BASE_URL}/locations',
params={'lat': lat, 'lng': lng, 'radius': radius}
)
data = response.json()
if data['success']:
return data['data']['locations']
else:
raise Exception(data['error']['message'])
# Usage
locations = find_nearby_locations(40.7128, -74.0060, 25)
for loc in locations:
print(f"{loc['name']} - {loc['distance']['value']} {loc['distance']['unit']}")
# Query locations
curl "https://api.storepoint.co/public/v1/YOUR_LOCATOR_TOKEN/locations?lat=40.7128&lng=-74.0060&radius=25"
# Get all locations
curl "https://api.storepoint.co/public/v1/YOUR_LOCATOR_TOKEN/locations?all=true"
# Get filters
curl "https://api.storepoint.co/public/v1/YOUR_LOCATOR_TOKEN/filters"
The API has generous rate limits designed for production use:
If you need higher limits for a specific use case, contact us.
Storepoint is designed to be flexible. You can use our platform in whatever way works best for your team:
Use the Storepoint locator app out of the box. Manage locations via the dashboard, spreadsheet imports, or third-party syncs. Your team can do everything without developer involvement.
Use our locator app for the UI, but extend its behavior with the Widget JavaScript API. Track analytics events, trigger custom actions, or integrate with your site's functionality.
Build your own UI with this Query API. Your team manages locations in Storepoint's dashboard, your developers query the data to power a completely custom frontend experience.
Use the Location Management API to sync locations from your systems, and this Query API to power your custom frontend. Full automation, full control.