This guide will help you create a local shopping experience for website users of your product detail pages (PDPs)
Getting Started
Choosing The Right Endpoints. When Should We Use Which Endpoint?
The following table will help you understand how to incorporate Locally into your own applications. The scenarios described match commonly used patterns on ecommerce web sites and have been heavily battle-tested in production environments.
On your Product Display Pages (PDPs), you will encounter one or more of the following challenges:
You Have This: | But You Need This: | Use This Endpoint! |
---|---|---|
A style number or variant grouping ID for a product | All of the stores AND all of the variants that are available locally | product/locate |
A single UPC variant of a product | All of the stores AND all of the variants of the product that are available locally | product/locate |
A set of UPCs representing a color-way, or a size, or a single dimension of a product | All of the stores AND all of the variants in your UPC set that are available locally | product/locate |
A single UPC variant of a product | All of the stores where this specific UPC is available along with stocking and paths to purchase information | conversion/store_data |
A style number or variant grouping ID for a product AND a store | All of the variants that are available at this store | conversion/store_data |
Example scenarios
I want to see all stores that carry a specific UPC in a region first and then filter stores by a specific UPC.
⭐ Recommended! Sites using this approach have the highest sales conversion rate.
- Use
product/locate
with your product's style number and shopper's location. The response will contain a list of carried UPCs at all stores in the shopper's region. - Allow the shopper to select a UPC variant.
- Use
conversion/store_data
with the shopper's selected UPC and location. The response will contain a list of stores in the shopper's region that carry the desired UPC.
I want to see all carried UPCs for a specific product in a region first and then filter UPCs by a specific store.
- Use
product/locate
with your product's style number and shopper's location. The response will contain a list of carried UPCs at all stores in the shopper's region. - Allow the shopper to select a store from the list.
- Next, query
conversion/store_data
with the shopper's chosen store and the product style number. - Finally, present a list of available UPCs at the shopper's chosen store.
I want to show availability at a single, pre-selected store. I want to see carried UPCs for a specific product at that store.
- First, query
conversion/store_data
with the store ID and the product style number. - Then, present a list of available UPCs at the shopper's chosen store.
Locating All Nearby Product Variants
When you need to find all of the stores and all in-stock variants for a product in a geographic region.
GET https://www.locally.com/headless/api/1.0/product/locate
API REFERENCE: https://api.locally.com/reference/headlessapicontrollerproduct_locate
Request:
curl --request GET \
--url 'https://www.locally.com/headless/api/1.0/product/locate?company_id={{COMPANY_ID}}&map_center_lat={{MAP_CENTER_LAT}}&map_center_lng={{MAP_CENTER_LNG}}&style={{STYLE}}' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
Response:
{
"success": true,
"data": {
"product": {
...
},
"all_upcs_carried": [
"000000000001",
"000000000002",
"000000000003"
],
"markers": [
{
"id": 37175,
"name": "ACME Outfitters Chicago",
"distance": "6.0 mi",
"address": "15 ACME Ave",
"city": "Chicago",
"state": "IL",
"zip": "60647",
"phone": "(555) 697-7381",
"country": "US",
"url": "",
"has_stock": 1,
"feature_constants": [
{
"key": "IN_STORE_PICKUP_AVAILABLE",
"value": "Store Pickup Available"
}
]
},
...
],
"session": {
"id": "abc999"
}
},
"msg": ""
}
This response will return all_upcs_carried
. This represents all of the UPC variants of the product/style that are available within the specified geographic region.
Additionally, the response will contain a markers
array which indicates all of the stores that carry one or more of the UPCs in all_upcs_carried
.
This is response is most useful when you need to enable the selection of product variants (ex. size and color combinations) on product display pages (PDPs). Armed with this data, you can now give your web site shoppers the freedom to choose variants on your PDP. When the shopper has chosen a specific variant and/or store from your UI, you will need to call the conversion/store_data
endpoint (see examples below) to get more detailed data about variant availability given their choice.
Locating a Single Product Variant at Multiple Stores
When you know that a UPC is in stock locally, you can use the UPC and geographic coordinates to return a list of stores that stock the item:
GET https://www.locally.com/headless/api/1.0/conversion/store_data
API REFERENCE: https://api.locally.com/reference/headlessapicontrollerconversion_store_data
This endpoint returns the stores that have the validated UPC in stock nearest to the shopper's geographical location.
Request:
curl 'https://www.locally.com/headless/api/1.0/conversion/store_data?company_id={{COMPANY_ID}}&upc={{UPC}}&style={{STYLE}}&map_center_lat={{MAP_CENTER_LAT}}&map_center_lng={{MAP_CENTER_LNG}}&map_distance_unit={{MAP_DISTANCE_UNIT}}&map_distance_diag=100' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
Please specify either the style or upc parameter. All other parameters are required. The required values (e.g. latitude, longitude, UPC) can be sourced from the /conversion/start
payload's response.
Response:
{
"success": true,
"data": {
"all_upcs_carried": [
000000000000,
...
],
"markers": [
{
"id": 37175,
"name": "ACME Outfitters Chicago",
"lat": "41.91136867",
"lng": "-87.67771437",
"address": "15 ACME Ave",
"city": "Chicago",
"state": "IL",
"zip": "60647",
"phone": "(555) 697-7381",
"country": "US",
"company_id": 999,
"image": "image.jpg",
"vendor_id": "",
"user_distance": 0,
"stock_status": 3,
"stocking_product": 1,
"stocking_variant": 1,
"acquisition_options": {
bopis: 1,
ropis: 1
},
"disclaimer": "Item is in Stock!",
"dow": 0,
"display_dow": [
{
"bil_hrs": "7am-8pm",
"label": "Monday",
"day_index": 0
}
],
"today_hours": "7am-8pm",
"hours_known": 1,
"is_open": 1,
"next_open": "",
"is_closing_soon": 0,
"phone_link": "tel:+15556977381",
"is_tmp_closed": 0,
"status_class": "success",
"status_label": "Open",
"qoh": 10,
"stock_status_constants": [
{
"key": "PRODUCT_YES_VARIANT_YES_BIL_YES",
"value": "Item is in Stock!"
}
],
"feature_constants": [
{
"key": "DELIVERY_AVAILABLE",
"value": "Same-day Local Delivery Available"
},
{
"key": "IN_STORE_PICKUP_AVAILABLE",
"value": "Store Pickup Available"
}
],
"web_address": "https:\/\/www.acmeco.com"
},
...
],
"total_marker_count": 100
}
}
The initial response will include the 10 closest locations that are either stocking the product or the brand. Additional information is included for each location to indicate the stock status and various paths to purchase for the given UPC.
Locating a Product or Variants at a Single Store
If you are interested in ongoing product availability for a specific store, you can query the conversion/store_data
endpoint in single store mode.
GET https://www.locally.com/headless/api/1.0/conversion/store_data
API REFERENCE: https://api.locally.com/reference/headlessapicontrollerconversion_store_data
Start by recording the specific data.markers[].id
in the result set using the guidance here https://api.locally.com/reference/create-a-product-locator#locating-a-product-at-multiple-stores. In the example the store ID is 37175
. We can target this specific store by setting the store ID as value for the only_store_id
query parameter.
Request:
curl 'https://www.locally.com/headless/api/1.0/conversion/store_data?only_store_id={{ONLY_STORE_ID}&}company_id={{COMPANY_ID}}&upc={{UPC}}}&map_distance_unit={{MAP_DISTANCE_UNIT}}&map_distance_diag=1' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
Note that map_center_lat
and map_center_lng
is not required when the only_store_id
parameter is present.
Response:
The response is a replica of the multi-store request, except that only one marker is returned.
Initializing the Conversion / Transaction for a Product
In order to return a list of available products and product variants nearest to the shopper, start by initializing the shopper’s session:
GET https://www.locally.com/headless/api/1.0/conversion/start
API REFERENCE: https://api.locally.com/reference/headlessapicontrollerconversion_start
This endpoint validates your product, UPC and style combination. It returns an authenticated / validated UPC and its geographical location.
Request:
curl 'https://www.locally.com/headless/api/1.0/conversion/start?style={{STYLE}}&upc={{UPC}}&product_id={{PRODUCT_ID}}&company_id={{COMPANY_ID}}' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
Apart from the required API token, please be sure to provide the company_id and either the style or upc parameter. The product_id parameter is optional.
Response:
{
"success": true,
"data": {
"style": "999",
"company_id": 999,
"upc": "000000000000",
"company_name": "ACME Outfitters Chicago",
"initial_store_id": 999,
"company_logo": "image.jpg",
"user_geo": {
"lat": "41.8756719",
"lng": "-87.6243469",
"city_label": "Chicago, IL",
"country": "US",
"distance_unit": "mi"
}
}
}
The results include a validated UPC of in the shopper's geographical location. If only the style parameter was defined, the UPC returned will be the most common local variant of the product. The location is automatically determined based on the shopper's location. See https://api.locally.com/reference/create-a-product-locator#manually-handling-location to manually set the location.
Manually Handling Location
All of the Locally Headless API endpoints will automatically attempt to geolocate the shopper based on their location on the first request. However, it is possible to set an alternative location prior to initialization and persist it for subsequent requests by utilizing sessions:
GET https://www.locally.com/headless/api/1.0/location/suggest
API REFERENCE: https://api.locally.com/reference/headlessapicontrollersuggest_locations
Request:
curl 'https://www.locally.com/headless/api/1.0/location/suggest?query=chicago' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
In this example we are asking the API for suggestions of locations matching the term "chicago".
Response:
{
"success": true,
"data": {
"query": "chicago",
"suggestions": [
{
"value": "Chicago, Illinois, United States",
"postcode": "",
"data": {
"lat": 41.875562,
"lng": -87.624421,
"relevance": 1
}
},
{
"value": "Chicagon, Michigan, United States",
"postcode": "",
"data": {
"lat": 46.095231,
"lng": -88.507357,
"relevance": 0.96
}
}
],
"from": [
"40.0292888",
"-105.3100174"
],
"session": {
"id": "abc999"
}
}
}
The response includes coordinates for locations that match the term "chicago".
GET https://www.locally.com/headless/api/1.0/location/switch/{{lat}}/{{lng}}
API REFERENCE: https://api.locally.com/reference/headlessapicontrollerswitch_location
We can now utilize the session ID, coordinates and URL-encoded location name returned in the location/suggest
payload to switch the shopper's location for the duration of their session.
Request:
curl 'https://www.locally.com/headless/api/1.0/location/switch/{{lat}}/{{lng}}?location_change_to_string={{url_encoded_location_na}}' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
--header 'Locally-Api-Session-Id: abc999'
Response:
{
"success": true,
"data": {
"city_label": "Chicago, IL",
"country": "US",
"zip_label": "60604",
"postal_code": "60604",
"lat": "41.87758900",
"lng": "-87.62818000",
"source": "region",
"base_url": "/in/chicago-il",
"distance_unit": "mi",
"session": {
"id": "abc999"
}
}
}
The response confirms a successful location change has been applied to this shopper's location. To persist the location in subsequent requests, we can now go through the normal initialization workflow, being mindful to pass the session ID e.g.
curl 'https://www.locally.com/headless/api/1.0/conversion/start?style={{STYLE}}&upc={{UPC}}&product_id={{PRODUCT_ID}}&company_id={{COMPANY_ID}}' \
--header 'Locally-Api-Token: {{API_TOKEN}}'
--header 'Locally-Api-Session-Id: abc999'