Store & Delivery
Everything you need to set up the store picker, display store details, and configure delivery options.
What you'll learn
- How multi-store groups work and how to build a store picker
- How to fetch store details, settings, and configuration
- How delivery methods (pickup vs delivery) are determined
- How to read store schedules and time-slot availabilities
- How to list available payment options
- How to display promotional banners, social links, and custom pages
Prerequisites
- A Store UUID (staging:
e87437f2-3e35-4738-af5e-6307e368255c) - A Group UUID for multi-store setups (sent via
X-Groupheader) - cURL or any HTTP client
All endpoints in this guide use the jwt_optional_authenticated pipeline — no login token is required for read operations.
Store Picker (Multi-Store Groups)
Stores can belong to a group — a collection of locations that share branding and configuration. The store picker lets customers choose which location to browse.
How it works
- The frontend sends the group identifier via the
X-Groupheader GET /api/v1/groups/storesreturns all active stores in that group- The customer selects a store, and subsequent requests use that store's UUID in the
X-Storeheader
GET /api/v1/groups/stores
Headers: X-Group (required)
cURL
curl -X GET https://ecom-api.staging.blaze.me/api/v1/groups/stores \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Group: YOUR_GROUP_UUID"
JavaScript (fetch)
const GROUP_UUID = "YOUR_GROUP_UUID";
const BASE_URL = "https://ecom-api.staging.blaze.me";
const response = await fetch(`${BASE_URL}/api/v1/groups/stores`, {
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
"X-Group": GROUP_UUID,
},
});
const { data } = await response.json();
// Build the store picker from the list
data.forEach((store) => {
console.log(`${store.attributes.name} — ${store.attributes.address}`);
});
Response
{
"data": [
{
"id": "e87437f2-3e35-4738-af5e-6307e368255c",
"type": "stores",
"attributes": {
"name": "Downtown Dispensary",
"address": {
"address": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"zip_code": "90001",
"country": "US",
"lat": 34.0522,
"lng": -118.2437
},
"uuid": "e87437f2-3e35-4738-af5e-6307e368255c",
"timezone": "America/Los_Angeles",
"is_active": true,
"allow_pickup": true,
"allow_deliveries": true,
"thumbnail": "https://images.example.com/store-logo.png",
"license_number": "C10-0000001-LIC",
"is_demo": false,
"merchant_id": "merchant-123"
}
},
{
"id": "b1234567-abcd-efgh-ijkl-000000000002",
"type": "stores",
"attributes": {
"name": "Westside Location",
"address": { "...": "..." },
"is_active": true,
"allow_pickup": true,
"allow_deliveries": false
}
}
]
}
Tip: Use
allow_pickupandallow_deliveriesto show the correct delivery method options for each store in your picker UI.
Store Details
Once a store is selected, fetch its full details.
GET /api/v1/store
Headers: X-Store (required)
cURL
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
JavaScript (fetch)
const STORE_UUID = "e87437f2-3e35-4738-af5e-6307e368255c";
const BASE_URL = "https://ecom-api.staging.blaze.me";
const response = await fetch(`${BASE_URL}/api/v1/store`, {
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
"X-Store": STORE_UUID,
},
});
const { data } = await response.json();
console.log(data.attributes.name);
console.log(data.attributes.timezone);
Response
{
"data": {
"id": "e87437f2-3e35-4738-af5e-6307e368255c",
"type": "stores",
"attributes": {
"name": "Downtown Dispensary",
"uuid": "e87437f2-3e35-4738-af5e-6307e368255c",
"env": "staging",
"address": {
"address": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"zip_code": "90001",
"country": "US",
"lat": 34.0522,
"lng": -118.2437
},
"timezone": "America/Los_Angeles",
"is_active": true,
"allow_pickup": true,
"allow_deliveries": true,
"license_number": "C10-0000001-LIC",
"is_demo": false,
"merchant_id": "merchant-123",
"thumbnail": "https://images.example.com/store-logo.png"
},
"relationships": {
"site": { "data": { "id": "...", "type": "store_sites" } },
"group": { "data": { "id": "...", "type": "groups" } }
}
}
}
Key attributes:
allow_pickup/allow_deliveries— determines which delivery methods are availabletimezone— IANA timezone, important for interpreting schedules and availability slotsis_active— whether the store is currently active and accepting ordersaddress— full address object with coordinates for map rendering
Store Settings
GET /api/v1/store/settings
Returns the combined store and site settings for the current store. This includes feature flags, UI configuration, and operational settings used by the storefront.
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/settings \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
GET /api/v2/store/settings
The v2 endpoint returns full settings — an aggregated response including the store group's stores, their individual settings, and group-level settings. This is typically used by the storefront to bootstrap the entire application state in a single call.
curl -X GET https://ecom-api.staging.blaze.me/api/v2/store/settings \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Store Configuration
GET /api/v1/store/configuration
Returns store configuration including the associated group and site information. This is primarily used by Mission Control (the admin dashboard).
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/configuration \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Delivery Methods: Pickup vs Delivery
The store's allow_pickup and allow_deliveries attributes determine which fulfillment methods are available. These flags affect:
- Which schedules are relevant (
pickupordelivery) - Which availability windows to show
- Which payment options are returned (some are delivery-type specific)
When building the checkout flow, pass the delivery_type query parameter to endpoints that support it:
pickup— customer picks up at the storescheduled_delivery— store delivers to the customer's address
Delivery Address Requirements
This section covers the full delivery address flow: what fields are required, how to validate an address, and what errors to expect.
Address Fields by Delivery Mode
Pickup — no customer address is needed. The store's own address is used automatically when the delivery specification type is pickup.
Delivery — a customer address is required. The exact fields depend on the store's delivery configuration:
- Always required:
zip_code - Required for full address validation:
address,city,state,zip_code,country lat/lng(geo data): required when the store uses region geo-zone restrictions (theuse_region_geo_zones_restrictionssetting). When enabled, the API uses geographic coordinates to determine whether the address falls within a delivery region polygon. Without this setting, onlyzip_codeis checked against the store's delivery zones.state: required whencountryisUSorCAcountry: defaults toUSif omitted
Tip: Check the store settings endpoint (
GET /api/v2/store/settings) for theuse_region_geo_zones_restrictionsflag to determine whether your integration needs to collect lat/lng from users.
Delivery Specification Structure
The delivery_specification object is set on the cart during creation or update. It tells the API how the order will be fulfilled.
{
"delivery_specification": {
"type": "delivery",
"mode": "asap",
"address": {
"address": "123 Main St",
"address_line2": "Apt 4B",
"city": "Los Angeles",
"state": "CA",
"zip_code": "90001",
"country": "US",
"lat": 34.0522,
"lng": -118.2437
},
"scheduled_start_time": null,
"scheduled_end_time": null,
"delivery_inventories": []
}
}
Fields:
type(required) —pickup,delivery, orkioskmode(required) —asap,scheduled, orexpressasap— deliver/pick up as soon as possiblescheduled— deliver/pick up at a chosen time slot (requiresscheduled_start_timeandscheduled_end_time)express— express delivery (requires geo-zone support and available express inventory)
address— the delivery address object (required whentypeisdelivery; ignored forpickupsince the store address is used)scheduled_start_time/scheduled_end_time— ISO 8601 datetime, required whenmodeisscheduleddelivery_inventories— optional array of inventory IDs to restrict which inventory fulfills the order (used with express delivery)
Address Validation Flow
Before setting the delivery specification on a cart, validate that the store delivers to the customer's address:
- User enters address → call
POST /api/v3/deliveries/stores(or v4) with the address - If deliverable → the response returns stores that can deliver. Set the
delivery_specificationon the cart viaPUT /api/v4/carts/{cart_uuid}/delivery-specificationor include it during cart creation/update - If not deliverable → the response returns an error with code
no_deliveries_at_location
v3 vs v4: Use v3 when you don't need express delivery or geo-zone support. Use v4 when the store has
use_region_geo_zones_restrictionsenabled or when you need express/scheduled mode filtering. The v4 response includes richer data likeunavailable_reason,alternative_mode, and inventory details.
Verify Delivery Address
cURL
curl -X POST https://ecom-api.staging.blaze.me/api/v4/deliveries/stores \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c" \
-d '{
"data": {
"type": "addresses",
"attributes": {
"address": {
"address": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"zip_code": "90001",
"country": "US",
"lat": 34.0522,
"lng": -118.2437
},
"preferred_inventories": null,
"mode": null
}
}
}'
JavaScript (fetch)
const STORE_UUID = "e87437f2-3e35-4738-af5e-6307e368255c";
const BASE_URL = "https://ecom-api.staging.blaze.me";
async function verifyDeliveryAddress(address) {
const response = await fetch(`${BASE_URL}/api/v4/deliveries/stores`, {
method: "POST",
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
"X-Store": STORE_UUID,
},
body: JSON.stringify({
data: {
type: "addresses",
attributes: {
address: {
address: address.street,
city: address.city,
state: address.state,
zip_code: address.zipCode,
country: address.country,
lat: address.latitude,
lng: address.longitude,
},
preferred_inventories: null,
mode: null,
},
},
}),
});
const result = await response.json();
if (!response.ok) {
// Handle no_deliveries_at_location or missing_zip_code errors
throw new Error(
result.errors?.[0]?.detail || "Address verification failed",
);
}
return result.data; // Array of delivery_stores
}
Set Delivery Specification on Cart
cURL
curl -X PUT https://ecom-api.staging.blaze.me/api/v4/carts/CART_UUID/delivery-specification \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c" \
-d '{
"data": {
"id": "CART_UUID",
"type": "carts",
"attributes": {
"delivery_specification": {
"type": "delivery",
"mode": "scheduled",
"address": {
"address": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"zip_code": "90001",
"country": "US",
"lat": 34.0522,
"lng": -118.2437
},
"scheduled_start_time": "2026-06-01T10:00:00",
"scheduled_end_time": "2026-06-01T13:00:00"
}
}
}
}'
JavaScript (fetch)
async function setDeliverySpecification(cartUuid, spec) {
const response = await fetch(
`${BASE_URL}/api/v4/carts/${cartUuid}/delivery-specification`,
{
method: "PUT",
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
"X-Store": STORE_UUID,
},
body: JSON.stringify({
data: {
id: cartUuid,
type: "carts",
attributes: {
delivery_specification: {
type: spec.type, // "pickup" or "delivery"
mode: spec.mode, // "asap", "scheduled", or "express"
address: spec.address, // full address object
scheduled_start_time: spec.scheduledStartTime || null,
scheduled_end_time: spec.scheduledEndTime || null,
delivery_inventories: spec.deliveryInventories || [],
},
},
},
}),
},
);
return response.json();
}
Region-Based Delivery
Stores can define delivery regions — geographic zones (polygons) that determine:
- Whether the store delivers to a given address
- Which inventory is used to fulfill the order (different regions can have different product availability and pricing)
- Delivery fees that may vary by region
When use_region_geo_zones_restrictions is enabled, the API uses the lat/lng coordinates to check if the address falls within a delivery region polygon (PostGIS ST_Contains). Without this setting, the API checks zip_code against a list of zip codes associated with each delivery region.
Region-based delivery affects:
- Product availability — products may only be available in certain regions
- Express delivery — only available in regions with inventories marked
available_for_express - Delivery fees — may differ per region
Error Scenarios
These errors can occur during address validation or when setting the delivery specification:
| Error Code | HTTP Status | Message | When It Occurs |
|---|---|---|---|
missing_zip_code |
400 | Zip code is required. | zip_code not provided in the delivery address |
invalid_zip_code |
400 | Zip code is invalid for {country}. | zip_code format doesn't match the country (US or CA) |
missing_address |
400 | Address is required. | Delivery type requires an address but none was provided |
geo_data_required |
400 | Delivery address geo location data is required for this delivery mode. | Store uses geo-zone restrictions but lat/lng were not provided |
zip_code_required |
400 | Delivery address Zip Code is required for this delivery mode. | Delivery mode requires a zip code but none was provided |
no_deliveries_at_location |
400 | Sorry, we don't deliver to that location. | Address is outside all delivery zones for the store group |
no_delivery_fee |
400 | We don't do deliveries to that location. | Address is in a zone but no delivery fee could be calculated (store blocks orders without a fee) |
Schedules
Schedules define the store's operating hours for each delivery method, broken down by weekday.
GET /api/v1/store/schedules/{schedule_type}
Path parameters:
schedule_type—pickupordelivery
cURL
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/schedules/pickup \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
JavaScript (fetch)
const STORE_UUID = "e87437f2-3e35-4738-af5e-6307e368255c";
const BASE_URL = "https://ecom-api.staging.blaze.me";
async function getSchedules(type) {
const response = await fetch(`${BASE_URL}/api/v1/store/schedules/${type}`, {
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
"X-Store": STORE_UUID,
},
});
return response.json();
}
// Fetch both schedule types
const pickupSchedules = await getSchedules("pickup");
const deliverySchedules = await getSchedules("delivery");
Response
{
"data": [
{
"id": "monday",
"type": "schedules",
"attributes": {
"weekday": "monday",
"start_time": "09:00:00",
"end_time": "21:00:00",
"schedule_type": "pickup",
"is_active": true
}
},
{
"id": "tuesday",
"type": "schedules",
"attributes": {
"weekday": "tuesday",
"start_time": "09:00:00",
"end_time": "21:00:00",
"schedule_type": "pickup",
"is_active": true
}
},
{
"id": "sunday",
"type": "schedules",
"attributes": {
"weekday": "sunday",
"start_time": null,
"end_time": null,
"schedule_type": "pickup",
"is_active": false
}
}
]
}
Note: A schedule with
is_active: falsemeans the store is closed on that day for that delivery type.
Availability Windows
While schedules define the store's general hours, availabilities return the actual bookable time slots for upcoming days. Use these to let customers pick a delivery or pickup window.
GET /api/v1/store/availabilities/{schedule_type}
Path parameters:
schedule_type—pickupordelivery
Query parameters (optional):
filter[since]— start date (ISO 8601, e.g.2026-05-30). Defaults to today in the store's timezonefilter[until]— end date. Defaults to 7 days aftersincefilter[has_available_slots]—trueto only return days with open slotspage[size]— limit the number of resultszip_code— filter availability by delivery zip codecoords— filter by geographic coordinates (for express delivery)
curl -X GET "https://ecom-api.staging.blaze.me/api/v1/store/availabilities/delivery?filter[since]=2026-05-30&filter[until]=2026-06-05" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Response
{
"meta": {
"settings": {
"delivery_type": "delivery",
"timezone_id": "America/Los_Angeles",
"since": "2026-05-30",
"until": "2026-06-05"
}
},
"data": [
{
"id": "2026-05-30",
"type": "availabilities",
"attributes": {
"date": "2026-05-30",
"weekday": "saturday",
"slots": [
{
"start_time": "09:00:00",
"end_time": "12:00:00",
"available": true
},
{
"start_time": "12:00:00",
"end_time": "15:00:00",
"available": true
},
{
"start_time": "15:00:00",
"end_time": "18:00:00",
"available": false
}
]
}
}
]
}
The meta.settings object contains the scheduling configuration (slot duration, lead time, etc.) along with the store's timezone.
Payment Options
GET /api/v1/store/payment-options
Returns the payment methods available for the store. Results can vary based on delivery type and device.
Query parameters (optional):
delivery_type—pickuporscheduled_delivery; defaults topickupzip_code— providing a zip code automatically sets delivery type todeliverycoords— providing coordinates (express delivery) sets delivery type todelivery
curl -X GET "https://ecom-api.staging.blaze.me/api/v1/store/payment-options?delivery_type=pickup" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Response
{
"data": [
{
"id": "1",
"type": "store_payment_options",
"attributes": {
"payment_option": "cash",
"name": "Cash",
"is_active": true,
"external_service": null,
"allows_tips": false,
"allows_promotions": false,
"supports_tips": false,
"supports_promotions": false,
"delivery_types": ["pickup", "delivery"]
}
},
{
"id": "2",
"type": "store_payment_options",
"attributes": {
"payment_option": "debit",
"name": "Debit Card",
"is_active": true,
"external_service": "aeropay",
"allows_tips": true,
"allows_promotions": true,
"supports_tips": true,
"supports_promotions": true,
"delivery_types": ["pickup", "delivery"]
}
}
]
}
Key attributes:
payment_option— the payment type identifier (e.g.cash,debit,credit)external_service— the payment provider if applicable (e.g.aeropay,merrco)delivery_types— which fulfillment methods this payment option supportsallows_tips/allows_promotions— whether tips or promotions are enabled for this optionpromotional_banner— optional banner to show alongside the payment option
Promotional Banners
GET /api/v1/store/site/promotional-banners
Returns active banners for the storefront hero carousel or announcements.
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/site/promotional-banners \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Response
{
"data": [
{
"id": "1",
"type": "promotional_banners",
"attributes": {
"title": "Summer Sale",
"description": "20% off all edibles this weekend",
"destination_url": "/products?category=edibles",
"desktop_image_url": "https://images.example.com/banner-desktop.jpg",
"mobile_image_url": "https://images.example.com/banner-mobile.jpg",
"position": 1,
"is_active": true,
"active_from": "2026-05-01T00:00:00Z",
"active_until": "2026-06-30T23:59:59Z",
"sales_channels": ["web", "mobile"]
}
}
]
}
Use desktop_image_url and mobile_image_url for responsive rendering. The position field determines the display order. Filter by sales_channels to show only relevant banners for the current platform.
Social Networks
GET /api/v1/store/socials
Returns the store's social media links.
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/socials \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Response
{
"data": [
{
"id": "instagram",
"type": "store_social_networks",
"attributes": {
"name": "instagram",
"link": "https://instagram.com/mystore",
"is_active": true
}
},
{
"id": "twitter",
"type": "store_social_networks",
"attributes": {
"name": "twitter",
"link": "https://twitter.com/mystore",
"is_active": true
}
}
]
}
Only display social links where is_active is true.
Custom Pages
GET /api/v1/store/pages
Returns custom content pages (e.g. About Us, Terms of Service) that can appear in the footer, header, or sidebar.
curl -X GET https://ecom-api.staging.blaze.me/api/v1/store/pages \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-H "X-Store: e87437f2-3e35-4738-af5e-6307e368255c"
Response
{
"data": [
{
"id": "1",
"type": "store_pages",
"attributes": {
"name": "About Us",
"link": "/about-us",
"page_type": "custom",
"description": "<p>Welcome to our store...</p>",
"show_in_footer": true,
"show_in_header": false,
"show_in_side_bar": false,
"show_in_app": true,
"is_active": true,
"is_external": false,
"override_page": null,
"group_page": false
}
},
{
"id": "2",
"type": "store_pages",
"attributes": {
"name": "Terms of Service",
"link": "/terms-of-service",
"page_type": "custom",
"show_in_footer": true,
"show_in_header": false,
"show_in_side_bar": false,
"show_in_app": false,
"is_active": true,
"is_external": false,
"override_page": null,
"group_page": true
}
}
]
}
Key attributes:
show_in_footer/show_in_header/show_in_side_bar— controls where the page link appearsis_external— iftrue,linkis a full URL; otherwise it's an internal pathgroup_page— iftrue, this page is shared across all stores in the groupdescription— HTML content of the page
Endpoint Reference
| Endpoint | Description |
|---|---|
GET /api/v1/groups/stores |
List stores in a group (store picker) |
GET /api/v1/store |
Store details |
GET /api/v1/store/settings |
Store + site settings |
GET /api/v2/store/settings |
Full settings (stores + group settings) |
GET /api/v1/store/configuration |
Store configuration with group/site |
GET /api/v1/store/schedules/{schedule_type} |
Schedules by type (pickup/delivery) |
GET /api/v1/store/availabilities/{schedule_type} |
Time-slot availabilities |
GET /api/v1/store/payment-options |
Available payment methods |
GET /api/v1/store/site/promotional-banners |
Promotional banners |
GET /api/v1/store/socials |
Social network links |
GET /api/v1/store/pages |
Custom pages |
What's Next
- Browse products: See the Quick Start guide for product listing and filtering
- Authentication: See the Authentication guide for login and JWT tokens
- Cart & Checkout: Use the time slots from
/store/availabilities/{type}when building the delivery specification for the cart