Building a Headless Storefront

A complete, step-by-step guide for building a cannabis ecommerce storefront using the Blaze ECOM API. Each step includes a ready-to-paste prompt for your AI coding agent.

What you'll build

  • A fully functional headless storefront with store selection, product browsing, cart, checkout, payments, and user accounts
  • Each section maps API endpoints to frontend pages and components
  • Every step links to the relevant API Reference operations and detailed guides

Prerequisites

  • Familiarity with the Quick Start and General Concepts
  • A frontend framework (React/Next.js, Vue/Nuxt, or similar)
  • The staging server URL: https://ecom-api.staging.blaze.me
  • The staging store UUID: e87437f2-3e35-4738-af5e-6307e368255c
  • Load docs/api/llms-full.txt as context in your AI agent (see AI Agent Integration)

Architecture Overview

Every storefront page maps to one or more API endpoints:

Page Endpoints Auth Required
Store Picker GET /api/v1/groups/stores No
Home / Landing GET /api/v1/store, GET /api/v1/store/site/promotional-banners No
Product Listing GET /api/v1/products, GET /api/v2/products/filters No
Product Detail GET /api/v2/products/{id} No
Categories GET /api/v2/products/categories No
Login / Register POST /api/v1/auth/login, POST /api/v1/auth/register No
Cart POST /api/v5/carts, GET /api/v5/carts/{uuid} Yes
Checkout POST /api/v5/carts/{cart_uuid}/valid, POST /api/v4/orders Yes
Payments POST /api/v1/store/payments/{service}/sessions, POST /api/v1/store/payments/{service}/orders/{uuid}/pay Yes
User Profile GET /api/v1/users/me Yes
Order History GET /api/v1/orders Yes
Deals GET /api/v1/store/deals/promotions No

Step 1: Store Setup

Fetch the store's details, configuration, and delivery options. This data drives the entire storefront — name, logo, operating hours, delivery methods, and payment options.

Key Endpoints

What to build

  • Store context provider (React Context / Pinia / etc.) that loads store data on app init
  • Age gate modal (if store requires age verification)
  • Delivery method picker (pickup vs delivery)
  • Operating hours display

cURL Example

curl 'https://ecom-api.staging.blaze.me/api/v1/store' \
  --header 'X-Store: e87437f2-3e35-4738-af5e-6307e368255c'

🤖 Prompt for your AI agent:

Using the Blaze ECOM API, build a store initialization module that:

  1. Fetches store details from GET /api/v1/store with the X-Store header
  2. Fetches store settings from GET /api/v1/store/settings
  3. Stores the data in a React Context provider (or your framework's state management)
  4. Shows an age gate modal if the store requires age verification (check settings.age_verification_enabled)
  5. Renders the store name, logo, and address in the header

Use the staging server: https://ecom-api.staging.blaze.me Store UUID: e87437f2-3e35-4738-af5e-6307e368255c All responses use JSON format — data is in response.data.attributes.

📖 Deep dive: Store & Delivery guide


Step 2: Product Catalog

Build the product browsing experience — categories, filters, product listing, and product detail pages.

Key Endpoints

What to build

  • Category sidebar / navigation
  • Filter panel (type, brand, potency, price range, weight)
  • Product grid/list with pagination
  • Product detail page with images, description, variants, pricing
  • Sort controls (name, price, THC, popularity)

cURL Example

# List products with filters
curl 'https://ecom-api.staging.blaze.me/api/v1/products?limit=20&offset=0&category=flower&order=price_asc' \
  --header 'X-Store: e87437f2-3e35-4738-af5e-6307e368255c'

# Get product detail (use v2 for enriched response)
curl 'https://ecom-api.staging.blaze.me/api/v2/products/blue-dream' \
  --header 'X-Store: e87437f2-3e35-4738-af5e-6307e368255c'

🤖 Prompt for your AI agent:

Build a product catalog with these components:

  1. CategoryNav: Fetch categories from GET /api/v2/products/categories and render a sidebar
  2. FilterPanel: Fetch available filters from GET /api/v2/products/filters and render checkboxes/sliders for type, brand, potency_thc, price range
  3. ProductGrid: Fetch products from GET /api/v1/products with query params for filters, pagination (limit=20, offset), and sort order. Display name, image (first photo_url), price, THC/CBD percentages
  4. ProductDetail: Fetch from GET /api/v2/products/{id}. Show full description, all images, variants with weight/price, inventory status

Filter params: category, type, brand_id, potency_thc_min/max, potency_cbd_min/max, price_min/max, weight, order (name_asc, price_asc, price_desc, thc_desc) Response format: JSON — products in response.data, each product's fields in .attributes Pagination: use limit and offset query params, total count in response.meta.total

📖 Deep dive: Products Catalog guide


Step 3: Search & Discovery

Add search, sponsored content, and recommendations to help users discover products.

Key Endpoints

What to build

  • Search bar with debounced API calls
  • Search results page (reuses ProductGrid with search param)
  • "Recommended for You" section on home page
  • Sponsored product badges on listing pages

🤖 Prompt for your AI agent:

Add search and discovery features:

  1. SearchBar: Debounced text input that calls GET /api/v1/products with the search query param. Show results using the ProductGrid component
  2. RecommendedSection: On the home page, fetch user top picks from POST /api/v1/products/recommendations/user-top-picks (send empty body for anonymous, or include JWT for personalized results). Display as a horizontal carousel
  3. ShowcasedGroups: Fetch from GET /api/v1/products/showcased. Each group has a name and products array — render as sections on the home page

The search param is added to the products endpoint: GET /api/v1/products?search=blue+dream&limit=20

📖 Deep dive: Ads & Recommendations guide


Step 4: Authentication

Build login, registration, and phone verification flows.

Key Endpoints

What to build

  • Login page (email/phone + password)
  • Registration page with phone verification
  • Password recovery flow
  • Auth context/store that persists the JWT and refreshes it
  • Protected route wrapper for authenticated pages

cURL Example

# Login
curl -X POST 'https://ecom-api.staging.blaze.me/api/v1/auth/login' \
  --header 'X-Store: e87437f2-3e35-4738-af5e-6307e368255c' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
    "data": {
      "type": "auth",
      "attributes": {
        "email": "user@example.com",
        "password": "password123"
      }
    }
  }'

🤖 Prompt for your AI agent:

Build authentication flows:

  1. LoginPage: Form with email/phone + password. POST to /api/v1/auth/login with JSON body. Store the JWT from response.data.attributes.token in localStorage and auth context
  2. RegisterPage: Form with first_name, last_name, email, phone, password. POST to /api/v1/auth/register. After success, redirect to phone verification
  3. PhoneVerification: Two-step: POST /api/v1/auth/verification to send code, then POST /api/v1/auth/verification-check with the code
  4. AuthProvider: React Context that stores JWT, adds Authorization: Bearer {token} to all authenticated requests, and clears on logout
  5. ProtectedRoute: Wrapper that redirects to login if no JWT is present

Request format: JSON { "data": { "type": "auth", "attributes": { ... } } } Content-Type: application/vnd.api+json

📖 Deep dive: Authentication guide


Step 5: Cart & Checkout

Build the shopping cart — add items, update quantities, set delivery, validate, and create orders.

Key Endpoints

What to build

  • Add-to-cart button on product pages
  • Cart drawer/page showing items, quantities, subtotal
  • Quantity +/- controls and remove button
  • Delivery method selector (pickup vs delivery)
  • Delivery address form (for delivery orders)
  • Checkout flow: validate → then either hand off to Blaze-hosted checkout (the default — see the Checkout Handoff guide) or, if you are a certified partner, select payment and create the order yourself

cURL Example

# Create cart with first item
curl -X POST 'https://ecom-api.staging.blaze.me/api/v5/carts' \
  --header 'X-Store: e87437f2-3e35-4738-af5e-6307e368255c' \
  --header 'Authorization: Bearer YOUR_JWT' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
    "data": {
      "type": "carts",
      "attributes": {
        "items": [{
          "product_id": "PRODUCT_UUID",
          "quantity": 1
        }]
      }
    }
  }'

🤖 Prompt for your AI agent:

Build a shopping cart system:

  1. AddToCart: When user clicks "Add to Cart" on a product, POST to /api/v5/carts (if no cart exists) or POST to /api/v5/carts/{cart_uuid}/items (if cart exists). Store cart UUID in state
  2. CartDrawer: Fetch cart from GET /api/v5/carts/{uuid}. Show each item with name, quantity, price. Calculate subtotal from the cart's totals attribute
  3. QuantityControls: PATCH /api/v5/carts/{cart_uuid}/items/{item_uuid} to update quantity. DELETE to remove
  4. DeliverySelector: Show pickup/delivery toggle. For delivery, show address form. PUT to /api/v4/carts/{cart_uuid}/delivery-specification with delivery_type and address fields
  5. Checkout: POST /api/v5/carts/{cart_uuid}/valid to validate. If valid, POST /api/v4/orders to create the order. Handle validation errors (out_of_stock, minimum_order_not_met, etc.)

All cart endpoints require JWT auth. Use v5 for carts, v4 for orders and delivery-specification. Delivery types: "pickup", "delivery". For delivery, include zip_code at minimum.

📖 Deep dive: Cart & Checkout guide


Step 6: Payments

Integrate payment processing — list payment options, create sessions, and pay for orders.

Key Endpoints

What to build

  • Payment method selector (based on store's available providers)
  • Saved cards list with add/remove
  • Payment session initialization (for Adyen, Aeropay, etc.)
  • Pay button that submits payment and handles success/failure
  • Optional tip screen after order completion

🤖 Prompt for your AI agent:

Build the payment flow:

  1. PaymentMethodPicker: Fetch available methods from GET /api/v1/store/payment-options. Filter to enabled providers. Display provider name and type
  2. SavedCards: Fetch user's saved sources from GET /api/v1/store/payments/{service}/sources. Show card last-4, brand, expiry. Allow delete via DELETE /api/v1/store/payments/{service}/sources/{id}
  3. PaymentSession: For providers needing client-side tokenization, POST to /api/v1/store/payments/{service}/sessions to get a session token
  4. PayOrder: POST to /api/v1/store/payments/{service}/orders/{order_uuid}/pay with the source_id or token. Handle success (redirect to confirmation) and error states
  5. TipScreen: After successful payment, show tip options. POST to /api/v1/store/payments/{service}/tip

The {service} path param is the payment provider slug (e.g., "adyen", "aeropay", "merrco"). Get the available providers from the store's payment-options endpoint.

📖 Deep dive: Payments guide


Step 7: User Account

Build the user profile, billing management, loyalty tracking, and order history.

Key Endpoints

What to build

  • Profile page with editable name, email, phone
  • Billing address form
  • Loyalty dashboard (points balance, tier, progress)
  • Rewards list with redemption
  • Order history with status tracking
  • Order detail page

🤖 Prompt for your AI agent:

Build user account pages:

  1. ProfilePage: Fetch from GET /api/v1/users/me. Show editable form for first_name, last_name, email, phone. Save via PUT /api/v1/users/me
  2. BillingPage: Fetch from GET /api/v1/users/me/billing. Address form. Save via PUT /api/v1/users/me/billing
  3. LoyaltyDashboard: Fetch from GET /api/v3/users/me/loyalty. Show points balance, tier name, points to next tier. Fetch rewards from GET /api/v1/users/me/rewards
  4. OrderHistory: Fetch from GET /api/v1/orders with pagination. Show order date, status, total, item count. Click through to order detail via GET /api/v1/orders/{uuid}

All endpoints require JWT auth. Response format: JSON .

📖 Deep dive: User Accounts guide


Step 8: Recommendations & Ads

Add personalized recommendations and sponsored content to increase engagement and revenue.

Key Endpoints

What to build

  • "Recommended for You" carousel on home page
  • "You might also like" section on product detail
  • "Frequently Bought Together" on product detail
  • Cart upsell suggestions (shown when viewing cart)
  • Sponsored product badges (distinguish from organic)

🤖 Prompt for your AI agent:

Add recommendation components:

  1. UserTopPicks: POST to /api/v1/products/recommendations/user-top-picks (empty body for anonymous, with JWT for personalized). Render as horizontal product carousel on home page
  2. FrequentlyBoughtTogether: On product detail, POST to /api/v1/products/recommendations/frequently-bought-together/{product_id}. Show as "Pairs well with" section
  3. CartToppers: When cart drawer opens, POST to /api/v1/products/recommendations/cart-toppers with the current cart items in the body. Show as "Add these too?" suggestions
  4. For sponsored variants, use the sponsored-user-top-picks and sponsored-cart-toppers endpoints. Include ad client data in the request body. Mark sponsored items with a "Sponsored" badge

All recommendation endpoints accept POST with optional body. Response is an array of products in JSON format.

📖 Deep dive: Ads & Recommendations guide


Deployment Considerations

Environment Configuration

// Use environment variables for API config
const API_CONFIG = {
  baseUrl:
    process.env.NEXT_PUBLIC_API_URL || "https://ecom-api.staging.blaze.me",
  storeId:
    process.env.NEXT_PUBLIC_STORE_ID || "e87437f2-3e35-4738-af5e-6307e368255c",
};

// Create a reusable fetch wrapper
async function apiRequest(path, options = {}) {
  const headers = {
    "X-Store": API_CONFIG.storeId,
    "Content-Type": "application/vnd.api+json",
    ...options.headers,
  };

  // Add auth if available
  const token = localStorage.getItem("jwt_token");
  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(`${API_CONFIG.baseUrl}${path}`, {
    ...options,
    headers,
  });

  if (!response.ok) {
    const error = await response.json();
    throw new ApiError(error);
  }

  return response.json();
}

CORS

The API supports CORS for browser-based requests. No proxy is needed for client-side applications.

Rate Limiting

The API enforces rate limits per IP. See the Rate Limiting guide for thresholds and retry strategies. Use exponential backoff with the Retry-After header.

API Versioning

This guide uses the recommended API versions per domain:

Domain Version Why
Products (detail, categories, brands, filters) v2 Enriched responses with variants, counts
Products (listing, types, tags) v1 Only version available
Carts v5 Latest with improved validation
Order creation v4 Returns the order synchronously
Delivery specification v4 Supports geo-zone delivery
Loyalty v3 Points and tier support
Everything else v1 Stable, production-proven

See the API Versioning guide for the full strategy.


What's Next?