get
https://www.locally.com/headless/api/1.0/conversion/shipping
Get shipping options for a product. Returns affiliate (buy online) and/or Locally network shipping options based on the type parameter. Requires either product_id, style or upc. When type is 'default', returns both affiliate and Locally options. Provide lat and lng together to order results by distance.
Request Parameters
🏷️ header · unmarked parameters are query params
| Parameter | Type | Required | Description |
|---|---|---|---|
Locally-Api-Token 🏷️ | string | Yes | Locally API token must be passed in the header to authenticate the API consumer. |
company_id | integer | Yes | The ID of the company. |
upc | string | No | The UPC of the product. Either upc or product_id is required. |
product_id | integer | No | The ID of the product. Either upc or product_id is required. |
country | string | No | Country code for filtering. Falls back to session geo country if not provided. |
lat | number | No | Latitude for distance-based ordering. Must be provided together with lng. |
lng | number | No | Longitude for distance-based ordering. Must be provided together with lat. |
style | string | No | Style number — the brand's style identifier as stored in Locally. Used to resolve product_id when product_id is not provided. Resolves within the company_id scope, so for cross-brand lookups the company_id must belong to the product owner. Use upc or product_id if the owner is unknown. |
type | string | No | Type of shipping options to return. One of: default, affiliate, locally. Defaults to default. |
Example Request
curl --get 'https://www.locally.com/headless/api/1.0/conversion/shipping' \
--header 'Locally-Api-Token: {{API_TOKEN}}' \
--data-urlencode 'company_id={{COMPANY_ID}}' \
--data-urlencode 'upc={{UPC}}' \
--data-urlencode 'lat=41.8756719' \
--data-urlencode 'lng=-87.6243469' \
--data-urlencode 'type=default'const params = new URLSearchParams({
company_id: '{{COMPANY_ID}}',
upc: '{{UPC}}',
lat: '41.8756719',
lng: '-87.6243469',
type: 'default'
});
const response = await fetch(
`https://www.locally.com/headless/api/1.0/conversion/shipping?${params}`,
{
headers: {
'Locally-Api-Token': '{{API_TOKEN}}'
}
}
);
const data = await response.json();import requests
response = requests.get(
'https://www.locally.com/headless/api/1.0/conversion/shipping',
params={
'company_id': '{{COMPANY_ID}}',
'upc': '{{UPC}}',
'lat': 41.8756719,
'lng': -87.6243469,
'type': 'default'
},
headers={'Locally-Api-Token': '{{API_TOKEN}}'}
)
data = response.json()type accepts default, affiliate, or locally. Note that type=affiliate returns a differently shaped payload (buy_online_options) than the other two — see the second response tab below.
Example Response
{
"success": true,
"data": {
"shipping_options": [
{
"id": 37175,
"type": "LOCALLY",
"name": "ACME Outfitters Chicago",
"logo": "acme-outfitters-chicago.png",
"logoUrl": "https://media2.locally.com/logo-270x270/acme-outfitters-chicago.png",
"status": "IN_STOCK",
"price": "129.99",
"currency": "$",
"url": "https://www.locally.com/add-to-cart/000000000000/37175"
},
{
"id": 37176,
"type": "LOCALLY",
"name": "ACME Outfitters Evanston",
"logo": "acme-outfitters-evanston.png",
"logoUrl": "https://media2.locally.com/logo-270x270/acme-outfitters-evanston.png",
"status": "IN_STOCK",
"price": "129.99",
"currency": "$",
"url": "https://www.locally.com/add-to-cart/000000000000/37176"
},
{
"id": 412,
"type": "AFFILIATE",
"name": "acme.com",
"logo": "acme-com.png",
"logoUrl": "https://s3.amazonaws.com/media.locally.net/logo-240x100/acme-com.png",
"status": "In Stock",
"price": "129.99",
"currency": "$",
"url": "https://www.acme.com/products/trail-runner"
}
],
"upcs": [
{
"code": "000000000000",
"n_locations": 2,
"single_store_max_qty": 4,
"locations": [
{
"id": 37175,
"name": "15 ACME Ave",
"zip": "60647",
"phone": "(312) 555-0142",
"country": "US",
"city": "Chicago",
"state": "IL",
"distance": 6.02,
"distance_unit": "mi",
"logo": "acme-outfitters-chicago.png",
"logoUrl": "https://media2.locally.com/logo-270x270/acme-outfitters-chicago.png",
"qty": 4
},
{
"id": 37176,
"name": "980 ACME Blvd",
"zip": "60201",
"phone": "(847) 555-0182",
"country": "US",
"city": "Evanston",
"state": "IL",
"distance": 13.87,
"distance_unit": "mi",
"logo": "acme-outfitters-evanston.png",
"logoUrl": "https://media2.locally.com/logo-270x270/acme-outfitters-evanston.png",
"qty": 2
}
]
}
],
"session": {
"id": "abc999"
}
},
"msg": ""
}{
"success": true,
"data": {
"buy_online_options": [
{
"id": 412,
"name": "acme.com",
"logoUrl": "https://s3.amazonaws.com/media.locally.net/logo-240x100/acme-com.png",
"logo": "acme-com.png",
"url": "https://www.acme.com/products/trail-runner",
"status": "In Stock",
"price": "129.99",
"currency": "$"
}
],
"session": {
"id": "abc999"
}
},
"msg": ""
}Response Explanation
success— Boolean outcome of the call. Whenfalse, the response also carries a top-levelerror_codeand explanatorymsg— always checksuccess, not just the HTTP status.data.shipping_options[].type—LOCALLYmarks a retailer in the Locally network that can ship the item;AFFILIATEmarks the brand's own buy-online link.type=locallyortype=affiliaterequests return one kind only.data.shipping_options[].id— ForLOCALLYentries the store ID — it matchesmarkers[].idin Get inventory data; forAFFILIATEentries the affiliate link's own ID.data.shipping_options[].status—LOCALLYentries always report the constantIN_STOCK;AFFILIATEentries pass through the affiliate feed's free-text status — hence the different casing (In Stock).data.shipping_options[].price— A string, not a number: two decimals with thousands commas and any trailing.00stripped.currencyis the display symbol ($), not an ISO code.data.shipping_options[].url— ForLOCALLY, a locally.comadd-to-cart/{upc}/{store_id}deep link that starts a cart at that store; forAFFILIATE, the brand's own product page.data.upcs[].n_locations— Distinct stores able to ship this UPC;single_store_max_qtyis the largest quantity any one of them can ship.data.upcs[].locations[]— Per-store shipping candidates — sorted bydistancewhenlat/lngwere provided (distance_unitfollows the store's country), otherwise by quantity. Populated only for single-UPC requests; comma-separatedupclists return counts only.data.upcs[].locations[].name— Quirk: holds the store's street address, not its display name — the display name for the sameidlives inshipping_options[].name.data.buy_online_options[]— Shape returned whentype=affiliate: the brand's buy-online links for the shopper's country (countryfalls back to session geo), after the brand's buy-online control rules run.data.session.id— Locally session ID, returned on every response. Replay it via theLocally-Api-Session-Idheader to persist the shopper's session between calls; expired IDs are transparently replaced with fresh ones.msg— Human-readable error text; empty string on success. In production, unexpected server errors are masked asApp server errorwith alookupreference — see Handling Errors in Production.
200Successful
400Bad Request
401Unauthorized
402Request Failed
403Forbidden
404Not Found
429Too Many Requests
500Server Error

