Only this pageAll pages
Powered by GitBook
1 of 27

Artos Software Docs

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

API Key

To integrate with STOQ's Back in Stock API, you'll need to obtain your API key. This key is essential for authenticating your API requests. Here's how to get it:

Steps to Get Your API Key

  1. Open the STOQ app inside your Shopify Admin panel

  2. Navigate to "Back in stock alerts > Integrations"

  3. Scroll down to find the "API Key" section

  4. Click the copy button to get your API key

Back in Stock API

Before diving into the API reference, it's important to understand the key term we use - Intent

Intents are essentially "waitlist requests" or "subscriptions" that customers create when they want to be notified with a back in stock alert.

  1. Core Purpose:

    • When a product is out of stock, customers can sign up to be notified when it becomes available again

    • Each intent represents a single customer's request to be notified about a specific product variant.

    • Intent is unique to a customer, product variant & market.

  2. What data is present in an Intent?

    • Customer Information: Each intent contains customer details like email, phone, and name

    • Product Information: Shopify product and product variant IDs

    • Notification Preference: Specifies how the customer wants to be notified (email or SMS)

  3. Lifecycle of an Intent:

    • Created when a customer signs up for notifications

    • Can be notified when the product becomes available

    • Can be blocked from sending notifications

  4. Compliance & Privacy:

    • Includes GDPR opt-in confirmation tracking

    • Tracks marketing preferences

    • Maintains unsubscribe status

Quantity: How many units the customer is interested in when the product is back in stock

Can be unsubscribed by the customer

  • Tracks notification history and opt-in status

  • List and filter Intents

    Get a specific Intent

    Create an Intent

    Create a new selling plan

    Delete a selling plan

    Transfer signups from one variant to another

    Remove product variants to a selling plan

    Delete intents (single or multiple)

    List and filter selling plans

    Get a specific selling plan

    Update a selling plan

    Update variant specific settings for a selling plan

    Get product variants associated with a selling plan

    Preorder Metafields

    Overview

    This document details the metafields used in the preorders system, explaining how they are structured and their relationships with shops and product variants. An important note here is that preorder offers on our dashboard are called selling plans in our backend system.

    Shop Level MetafieldsProduct Variant Level Metafields

    Add product variants to a selling plan

    Get products in demand report

    Update Selling Policy

    Notify multiple intents in bulk

    Preorders API

    Before diving into the API reference, it's important to understand the key term we use - Selling Plans

    What are Selling Plans?

    Selling Plans in the context of preorders are configurations that define how a preorder product is sold, billed, and delivered to customers.

    Send shipping update email

    Core Purpose:
    • Enable merchants to sell products before they're in stock or available for immediate shipping

    • Define payment schedules, delivery timelines, and inventory management for preordered items

    • Provide customization options for how preorders appear and function in the storefront

    What data is present in a Selling Plan?

    • Basic Information: Name, internal reference name, enabled status

    • Billing Configuration: When and how much to charge (at checkout or later), charge types (percentage or fixed amount)

    • Delivery Settings: When products will be delivered (exact date or interval after purchase)

    • Inventory Management: How inventory is reserved and which system manages it

    • Pricing Options: Discount amounts or percentages for preordered items

    • UI Customization: Button text, badge styling, shipping information text

    Variant Association:

    • Selling plans can be associated with product variants in three ways:

      • All products in the store

      • Products in a specific collection

      • Custom selection of individual variants

    • Each variant can have custom settings like shipping text and maximum preorder quantity

    Multi-Market Support:

    • Selling plans can be configured for specific markets in multi-market stores

    • Different markets may have different preorder terms or availability

    Notify a single Intent

    Market level product variant Metafields

    This document outlines the structure and usage of market-specific metafields for product variants. These metafields enable market-specific order limit tracking, and shipping information display.

    1. Market Preorder Count Metafield

    Configuration

    • Key: market_preorder_count

    • Type: json

    • Namespace: restockrocket_production

    Purpose

    • Tracks the current number of preorders for a variant per market

    • Used for market-specific inventory management

    • Automatically updated when orders are processed in different markets

    • Stored as a JSON object mapping market IDs to counts

    Accessing in Liquid

    2. Market Preorder Max Count Metafield

    Configuration

    • Key: market_preorder_max_count

    • Type: json

    • Namespace: restockrocket_production

    Purpose

    • Sets the maximum number of preorders allowed per market

    • Controls market-specific inventory policy switching

    • Triggers blocking orders when count reaches max in specific markets

    • Stored as a JSON object mapping market IDs to maximum counts

    Accessing in Liquid

    Example Usage: Market-Specific Preorder Count and Max Count

    3. Market Shipping Text Metafield

    Configuration

    • Key: market_shipping_text

    • Type: json

    • Namespace: restockrocket_production

    Purpose

    • Stores market-specific shipping/delivery timeline text

    • Allows different shipping information per market

    • Stored as a JSON object mapping market IDs to shipping text

    Accessing in Liquid

    Accessing via GraphQL

    Query for Market-Specific Metafields

    Query for Multiple Variants with Market Data

    Owner: Product Variant

    Owner: Product Variant

    Owner: Product Variant

    
    {% assign market_preorder_count = product_variant.metafields.restockrocket_production.market_preorder_count.value | json %}
    Example value of market_preroder_count =>
    { 
      "market_id_1": 1,
      "market_id_2": 5,
      "market_id_3": 3
    }
    
    {% assign market_preorder_max_count = product_variant.metafields.restockrocket_production.market_preorder_max_count.value | json %}
    
    Example value of market_preorder_max_count =>
    { 
      "market_id_1": 10,
      "market_id_2": 15,
      "market_id_3": 10
    }
    {% assign variant = product.selected_or_first_available_variant %}
    {% assign market_counts = variant.metafields.restockrocket_production.market_preorder_count.value | json %}
    {% assign market_max_counts = variant.metafields.restockrocket_production.market_preorder_max_count.value | json %}
    {% assign current_market = shop.market.id %}
    
    {% if market_max_counts[current_market] %}
      {% assign current_count = market_counts[current_market] %}
      {% assign max_count = market_max_counts[current_market] %}
      {% assign spots_remaining = max_count | minus: current_count %}
    
      {% if spots_remaining > 0 %}
        <div class="preorder-availability">
          <span class="spots-left">{{ spots_remaining }} spots remaining in your market</span>
          {% if spots_remaining < 5 %}
            <span class="low-stock-warning">Almost sold out in your region!</span>
          {% endif %}
        </div>
      {% else %}
        <div class="preorder-full">
          Preorder limit reached for your market
        </div>
      {% endif %}
    {% endif %}
    {% assign market_shipping_text = product_variant.metafields.restockrocket_production.market_shipping_text.value | json %}
    Example value of market_shipping_text =>
    {
      "market_id_1": "Ships in 1 week",
      "market_id_2": "Ships in 2 weeks",
      "market_id_3": "Ships in 4 days"
    }
    {
      productVariant(id: "gid://shopify/ProductVariant/YOUR_VARIANT_ID") {
        metafields(
          namespace: "restockrocket_production",
          keys: ["market_preorder_count", "market_preorder_max_count", "market_shipping_text"]
        ) {
          edges {
            node {
              id
              key
              value
              type
            }
          }
        }
      }
    }
    {
      product(id: "gid://shopify/Product/YOUR_PRODUCT_ID") {
        variants(first: 10) {
          edges {
            node {
              id
              title
              metafields(
                namespace: "restockrocket_production",
                keys: ["market_preorder_count", "market_preorder_max_count", "market_shipping_text"]
              ) {
                edges {
                  node {
                    id
                    key
                    value
                    type
                    # Example response for market_preorder_count:
                    # value: {"market_id_1": 45, "market_id_2": 20, "market_id_3": 15}
                    # Example response for market_preorder_max_count:
                    # value: {"market_id_1": 100, "market_id_2": 50, "market_id_3": 30}
                    # Example response for market_shipping_text:
                    # value: {"market_id_1": "Ships in 2 weeks", "market_id_2": "Ships in 3 weeks", "market_id_3": "Ships in 4 weeks"}
                  }
                }
              }
            }
          }
        }
      }
    }

    Product Variant Level Metafields

    1. Selling Plan IDs Metafield

    Configuration

    • Key: selling_plan_ids

    • Type: json

    • Namespace: restockrocket_production

    • Owner: Product Variant

    Purpose

    • Stores the list of selling plan IDs associated with a variant

    • Used to track which preorder plans are available for a variant

    • Enables quick lookup of available preorder options

    • Stored as a JSON array of selling plan IDs

    Accessing in Liquid

    2. Preorder Count Metafield

    Configuration

    • Key: preorder_count

    • Type: number_integer

    • Namespace: restockrocket_production

    Purpose

    • Tracks the current number of preorders for a specific variant

    • Used for inventory management and display

    • Automatically updated when orders are processed

    Accessing in Liquid

    3. Preorder Max Count Metafield

    Configuration

    • Key: preorder_max_count

    • Type: number_integer

    • Namespace: restockrocket_production

    Purpose

    • Sets the maximum number of preorders allowed for a variant

    • Controls inventory policy switching

    • Triggers blocking orders when count reaches max

    Accessing in Liquid

    Example Usage: Preorder Count and Max count

    4. Shipping Text Metafield

    Configuration

    • Key: shipping_text

    • Type: json

    • Namespace: restockrocket_production

    Purpose

    • Stores shipping/delivery timeline text for a product variant

    • Stored as a JSON object with market IDs as keys and shipping text as values

    Accessing in Liquid

    Here's an example of how to access the above metafields via GraphQL

    Accessing via GraphQL

    Simple examples of using STOQ's variant-level metafields with basic Shopify liquid

    1. Use Case: Show current preorder count and remaining spots.

    1. Use Case: Show shipping info specific to the selected variant.

    Shop Level Metafields

    Selling Plans Metafield

    Configuration

    • Key: selling_plans

    Owner: Product Variant
    Owner: Product Variant
    Owner: Product Variant
    Type: json
  • Namespace: restockrocket_production

  • Owner: Shop

  • Purpose

    Stores the complete configuration of all enabled selling plans (preorder offers) for a shop.

    Fields

    Accessing in Liquid

    Example: Working with Delivery Times

    Accessing via GraphQL

    This example demonstrates:

    • Converting the delivery time to a readable format

    • Calculating days remaining until delivery

    • Displaying a formatted delivery date

    • Replacing placeholders in shipping text

    • Adding conditional styling based on delivery status

    • Basic CSS styling for the delivery information

    Simple examples of using STOQ's shop-level metafields with Shopify liquid

    Example 1: Basic Preorder Badge

    Use Case: Show preorder badge when variant is part of a selling plan.

    Example 2: Preorder Button Text

    Use Case: Use custom button text from selling plan configuration.

    Example 3: Show Remaining Quantity

    Use Case: Display how many preorder spots are left.

    Example 4: Delivery Date Display

    Use Case: Show estimated delivery date from selling plan.

    
    {% assign selling_plan_ids = product_variant.metafields.restockrocket_production.selling_plan_ids.value | json %}
    {% assign preorder_count = product_variant.metafields.restockrocket_production.preorder_count %}
    {% assign preorder_max_count = product_variant.metafields.restockrocket_production.preorder_max_count %}
    {% assign variant = product.selected_or_first_available_variant %}
    {% assign preorder_count = variant.metafields.restockrocket_production.preorder_count.value | default: 0 %}
    {% assign preorder_max = variant.metafields.restockrocket_production.preorder_max_count.value %}
    
    {% if preorder_max %}
      {% assign spots_remaining = preorder_max | minus: preorder_count %}
    
      {% if spots_remaining > 0 %}
        <div class="preorder-availability">
          <span class="spots-left">{{ spots_remaining }} spots remaining</span>
          {% if spots_remaining < 5 %}
            <span class="low-stock-warning">Almost sold out!</span>
          {% endif %}
        </div>
      {% else %}
        <div class="preorder-full">
          Preorder limit reached
        </div>
      {% endif %}
    {% endif %}
    
    # Query to get metafields for a specific product variant
    {
      productVariant(id: "gid://shopify/ProductVariant/YOUR_VARIANT_ID") {
        metafields(
          namespace: "restockrocket_production",
          first: 10
        ) {
          edges {
            node {
              id
              namespace
              key
              value
              type
            }
          }
        }
      }
    }
    
    # Query to get specific metafields for multiple variants of a product
    {
      product(id: "gid://shopify/Product/YOUR_PRODUCT_ID") {
        variants(first: 10) {
          edges {
            node {
              id
              title
              metafields(
                namespace: "restockrocket_production",
                keys: ["preorder_count", "preorder_max_count", "shipping_text"]
              ) {
                edges {
                  node {
                    id
                    key
                    value
                    type
                  }
                }
              }
            }
          }
        }
      }
    }
    {% assign shipping_text = product_variant.metafields.restockrocket_production.shipping_text %}
    # Query to get metafields for a specific product variant
    {
      productVariant(id: "gid://shopify/ProductVariant/YOUR_VARIANT_ID") {
        metafields(
          namespace: "restockrocket_production",
          first: 10
        ) {
          edges {
            node {
              id
              namespace
              key
              value
              type
            }
          }
        }
      }
    }
    
    # Query to get specific metafields for multiple variants of a product
    {
      product(id: "gid://shopify/Product/YOUR_PRODUCT_ID") {
        variants(first: 10) {
          edges {
            node {
              id
              title
              metafields(
                namespace: "restockrocket_production",
                keys: ["preorder_count", "preorder_max_count", "shipping_text"]
              ) {
                edges {
                  node {
                    id
                    key
                    value
                    type
                  }
                }
              }
            }
          }
        }
      }
    }
    {% assign target_variant = product.selected_or_first_available_variant %}
    {% assign preorder_count = target_variant.metafields.restockrocket_production.preorder_count | default: 0 %}
    {% assign preorder_max_count = target_variant.metafields.restockrocket_production.preorder_max_count %}
    
    {% if preorder_max_count %}
      {% assign remaining = preorder_max_count | minus: preorder_count %}
    
      <div class="inventory-counter">
        <h4>Preorder Status</h4>
        <p><strong>{{ preorder_count }}</strong> preordered</p>
        <p><strong>{{ remaining }}</strong> remaining</p>
      </div>
    {% endif %}
    {% assign target_variant = product.selected_or_first_available_variant %}
    {% assign variant_shipping = target_variant.metafields.restockrocket_production.shipping_text.value %}
    
    <div class="variant-shipping">
      <h4>Shipping Information</h4>
    
      {% if variant_shipping %}
        {% for shipping_info in variant_shipping %}
          <div>
            <strong>{{ shipping_info[0] | upcase }}:</strong>
            <p>{{ shipping_info[1] }}</p>
          </div>
        {% endfor %}
      {% else %}
        <p>Standard shipping rates apply</p>
      {% endif %}
    </div>
    {
      "shopify_selling_plan_group_id": "string",  // Unique identifier for the selling plan group in Shopify
      "shopify_selling_plan_id": "string",        // Unique identifier for the specific selling plan in Shopify
      "enabled": boolean,                         // Whether the selling plan is active
      "variant_ids": ["string"],                 // List of product variant IDs associated with this plan
      "name": "string",                          // Display name of the selling plan
      "preorder_button_text": "string",          // Text shown on the preorder button
      "preorder_button_description": "string",    // Description shown below the preorder button
      "preorder_button_description_background_color": "string",  // Background color of the description box
      "preorder_button_description_text_color": "string",        // Text color of the description
      "preorder_button_description_border_radius": "number",     // Border radius of the description box
      "preorder_button_description_show_quantity_limit": boolean,  // Whether to show quantity limits
      "preorder_button_description_quantity_limit_suffix": "string",  // Text after quantity limit
      "preorder_button_description_shipping_text_prefix": "string",   // Text before shipping info
      "delivery_exact_time": "string",           // Exact time of delivery
      "quantity_limit_text": "string",           // Text explaining quantity limitations
      "preorder_button_description_show_shipping": boolean,  // Whether to show shipping info
      "preorder_shipping_text": "string",        // Shipping information for preorder items
      "shipping_applies_to_all_products": boolean,  // Whether shipping settings are global
      "shipping_text": "string",                 // General shipping information
      "payment_type": "string",                  // Type of payment (full/partial)
      "billing_checkout_charge_type": "string",  // How the charge is calculated
      "billing_checkout_charge_amount": "number", // Fixed amount for checkout charge
      "billing_checkout_charge_percentage": "number",  // Percentage amount for checkout
      "pricing_type": "string",                  // Type of pricing adjustment
      "pricing_amount": "number",                // Fixed amount for pricing
      "pricing_percentage": "number",            // Percentage for pricing
      "discount_text": "string",                 // Text explaining discounts
      "billing_title": "string",                 // Title for billing information
      "billing_description": "string",           // Detailed billing information
      "enable_billing_widget": boolean,          // Whether to show billing widget
      "inventory_provider": "string",            // Provider handling inventory
      "preorder_badge_enabled": boolean,         // Whether to show preorder badge
      "preorder_badge_text": "string",           // Text shown on the badge
      "preorder_badge_text_color": "string",     // Color of badge text
      "preorder_badge_background_color": "string",  // Background color of badge
      "translations": {                          // Translations for multilingual support
        "locale_code": {
          "shipping_text": "string",
          "billing_title": "string",
          "billing_description": "string",
          "discount_text": "string",
          "preorder_badge_text": "string",
          "preorder_button_description": "string",
          "quantity_limit_text": "string",
          "preorder_shipping_text": "string",
          "preorder_button_text": "string"
        }
      }
    }
    {% assign current_variant_id = product.selected_or_first_available_variant.id %}
    {% assign selling_plans = shop.metafields.restockrocket_production.selling_plans.value %}
      
    {% for plan in selling_plans %}
      {% if plan.enabled %}
        {% assign variant_ids = plan.variant_ids %}
        {% if variant_ids contains current_variant_id %}
          {% comment %}
            This variant is part of the selling plan
            You can now access plan details:
          {% endcomment %}
      
          <div class="preorder-button" style="background-color: {{ plan.preorder_badge_background_color }}">
            <span style="color: {{ plan.preorder_badge_text_color }}">
              {{ plan.preorder_badge_text }}
            </span>
          </div>
      
          {% if plan.preorder_button_description_show_quantity_limit %}
            {% assign preorder_count = product.selected_or_first_available_variant.metafields.restockrocket_production.preorder_count | default: 0 %}
            {% assign preorder_max_count = product.selected_or_first_available_variant.metafields.restockrocket_production.preorder_max_count %}
      
            {% if preorder_max_count %}
              {% assign remaining = preorder_max_count | minus: preorder_count %}
              <div class="quantity-limit">
                {{ remaining }}{{ plan.preorder_button_description_quantity_limit_suffix }}
              </div>
            {% endif %}
          {% endif %}
        {% endif %}
      {% endif %}
    {% endfor %}
    {% assign current_variant_id = product.selected_or_first_available_variant.id %}
    {% assign selling_plans = shop.metafields.restockrocket_production.selling_plans.value %}
    
    {% for plan in selling_plans %}
      {% if plan.enabled %}
        {% assign is_variant_in_plan = false %}
        {% for variant_id in plan.variant_ids %}
          {% if variant_id == current_variant_id %}
            {% assign is_variant_in_plan = true %}
            {% break %}
          {% endif %}
        {% endfor %}
    
        {% if is_variant_in_plan and plan.delivery_exact_time %}
          {% assign delivery_date = plan.delivery_exact_time | date: '%Y-%m-%d' | date: '%s' %}
          {% assign today_date = 'now' | date: '%Y-%m-%d' | date: '%s' %}
          {% assign seconds_diff = delivery_date | minus: today_date %}
          {% assign days_until_delivery = seconds_diff | divided_by: 86400 %}
    
          <div class="delivery-info">
            <h4>Delivery Information</h4>
    
            {% if days_until_delivery > 0 %}
              <p class="estimated-delivery">
                Estimated delivery: {{ plan.delivery_exact_time | date: '%B %d, %Y' }}
                <span class="days-left">({{ days_until_delivery }} days left)</span>
              </p>
    
              {% if plan.preorder_shipping_text %}
                {% assign formatted_date = plan.delivery_exact_time | date: '%B %d, %Y' %}
                {% capture date %}{{ formatted_date | escape }}{% endcapture %}
                <p class="shipping-note">
                  {{ plan.preorder_shipping_text | url_escape | replace: "%7B%7B%20date%20%7D%7D", date | replace: "%20", " " }}
                </p>
              {% endif %}
            {% else %}
              <p class="delivery-soon">
                Delivery date approaching
              </p>
            {% endif %}
          </div>
        {% endif %}
      {% endif %}
    {% endfor %}
    # Query to get shop selling plans metafield
    {
      shop {
        metafield(namespace: "restockrocket_production", key: "selling_plans") {
          id
          namespace
          key
          value
          type
        }
      }
    }
    
    # Query to get multiple shop metafields at once
    {
      shop {
        metafields(
          namespace: "restockrocket_production",
          first: 10
        ) {
          edges {
            node {
              id
              namespace
              key
              value
              type
            }
          }
        }
      }
    }
    {% assign current_variant_id = product.selected_or_first_available_variant.id %}
    {% assign selling_plans = shop.metafields.restockrocket_production.selling_plans.value %}
    
    {% for plan in selling_plans %}
      {% if plan.enabled and plan.preorder_badge_enabled %}
        {% if plan.variant_ids contains current_variant_id %}
          <div class="preorder-badge"
               style="background: {{ plan.preorder_badge_background_color }}; color: {{ plan.preorder_badge_text_color }};">
            {{ plan.preorder_badge_text }}
          </div>
        {% endif %}
      {% endif %}
    {% endfor %}
    {% assign current_variant_id = product.selected_or_first_available_variant.id %}
    {% assign selling_plans = shop.metafields.restockrocket_production.selling_plans.value %}
    {% assign button_text = "Preorder Now" %}
    
    {% for plan in selling_plans %}
      {% if plan.enabled and plan.variant_ids contains current_variant_id %}
        {% assign button_text = plan.preorder_button_text %}
        {% break %}
      {% endif %}
    {% endfor %}
    
    <button class="preorder-button">{{ button_text }}</button>
    {% assign current_variant = product.selected_or_first_available_variant %}
    {% assign selling_plans = shop.metafields.restockrocket_production.selling_plans.value %}
    
    {% for plan in selling_plans %}
      {% if plan.enabled and plan.variant_ids contains current_variant.id and plan.preorder_button_description_show_quantity_limit %}
        {% assign preorder_count = current_variant.metafields.restockrocket_production.preorder_count | default: 0 %}
        {% assign preorder_max_count = current_variant.metafields.restockrocket_production.preorder_max_count %}
    
        {% if preorder_max_count %}
          {% assign remaining = preorder_max_count | minus: preorder_count %}
          <div class="quantity-info">
            <p>{{ remaining }}{{ plan.preorder_button_description_quantity_limit_suffix | default: ' left' }}</p>
          </div>
        {% endif %}
      {% endif %}
    {% endfor %}
    
    <div data-gb-custom-block data-tag="assign"></div>
    
    <div data-gb-custom-block data-tag="assign"></div>
    
    <div data-gb-custom-block data-tag="for">
    
      
    
    <div data-gb-custom-block data-tag="if" data-expression='plan.enabled and plan.variant_ids contains current_variant_id and plan.delivery_exact_time'>
        <div class="delivery-info">
          <h4>Estimated Delivery</h4>
          <p>{{ plan.delivery_exact_time | date: '%B %d, %Y' }}</p>
    
          {% if plan.preorder_shipping_text %}
            <p>{{ plan.preorder_shipping_text | replace: '{{ date }}', plan.delivery_exact_time | date: '%B %d, %Y' }}</p>
          {% endif %}
        </div>
      </div>
    
    </div>

    JavaScript API

    STOQ provides a JavaScript API for custom integrations within your Shopify theme. This API is accessible through the window._RestockRocket object when our app loads into your theme.

    Available APIs

    Page Type
    Available APIs

    Product Page

    openModal, openInlineForm, removeInlineForm, renderButtonForVariant, getSellingPlan

    Collection, Home, and Custom Pages

    openModal

    All pages

    marketId

    stoq:loaded

    Event triggered when STOQ's app embed is loaded on any page supported by the app. Pages supported: Product, Collection, Home, Search

    openModal

    openModal(productData, variantId, customerData)

    Opens the 'Notify me' modal for a specific product. This is typically used for custom elements like quick add buttons.

    Parameters:

    • productData (Object): Contains product information

    • variantId (String): ID of the specific variant

    • customerData (Object): Contains customer information (Optional)

    Examples:

    Opening modal on a collection page:

    Opening modal on a product page:

    openInlineForm

    openInlineForm(productData, variantId, customerData, inlineFormContainer, inlineFormContainerInsertType)

    Shows the 'Notify me' modal as an Embedded form for a specific product variant. Use this API to show the Embedded Sign up form in a specific location when an out of stock variant is selected.

    Parameters:

    • productData (Object): Contains product information

    • variantId (String): ID of the specific variant

    • customerData (Object): Contains customer information (Optional)

    • inlineFormContainer: Selector for the container where you want to insert the form (Optional)

    • inlineFormContainerInsertType: How the form should be inserted into the container (Optional)

    Notes:

    • inlineFormContainer can be passed down in the function call, or you can set it up in-app. Chat with Support to get access to the relevant settings.

    • inlineFormContainerInsertType can be one of: beforebegin, afterbegin, beforeend, afterend. The default is 'beforeend'.

    Example:

    removeInlineForm

    Removes the Embedded form rendered using openInlineForm. Use this API to remove the Embedded Form after a successful submission or when a different variant is selected.

    Example:

    renderButtonForVariant

    renderButtonForVariant(variantId)

    Sets up or removes the button for a specific variant on the page. Useful when your theme has a custom variant selector.

    Parameters:

    • variantId (String): ID of the variant to render the button for.

    Example:

    getSellingPlan

    getSellingPlan(variantId)

    Retrieves the selling plan object for a given variant if a preorder is set up.

    Parameters:

    • variantId (String): ID of the variant to check for a selling plan.

    Returns:

    • (Object): The selling plan object if found, or null if no preorder is set up for the variant.

    Example:

    Example Response:

    Integration Examples

    Quick Add Button on Collection Page

    Notify Me Button on Product Page

    Custom Integration on Product Page

    These examples demonstrate how to integrate RestockRocket's API with buttons using onclick handlers and Shopify Liquid markup. The Liquid examples show how to access product and variant data directly from Shopify, which can then be passed to the RestockRocket API.

    Remember to adjust these examples to fit your specific theme structure and requirements.

    marketId

    This returns the market ID the store is being viewed as:

    All pages

    stoq:loaded

    window.addEventListener('stoq:loaded', (event) => {
      const { pageType, enabled, settings } = event.detail;
      if (pageType === 'product' && enabled) {
        console.log('Stoq loaded on product page', settings);
        // Handle product page customizations
      }
    });
    const addToCartBtn = document.getElementById('quick-add-btn');
    addToCartBtn.addEventListener('click', () => {
      const productData = { id: 1111, variants: [{ id: 2222, available: false }] };
      const variantId = '41XX';
      const customerData = { 
        shopify_customer_id: 9999,
        email: '[email protected]',
        phone: '8123999123', // phone number
        country_code: '1', // country code
        country: 'us' // 2 letter ISO country code
      } // Optional
      window._RestockRocket.openModal(productData, variantId, customerData);
    
      // Alternative: Using Liquid objects directly in Javascript
      // window._RestockRocket.openModal({{ product | json }}, '{{ product.selected_or_first_available_variant.id }}');
    });
    const notifyMeBtn = document.getElementById('notify-me-btn');
    notifyMeBtn.addEventListener('click', () => {
      // Default: Opens modal for the current product, it automatically gets the
      // product data and currently selected variant ID
      window._RestockRocket.openModal();
    });
    const addToCartBtn = document.getElementById('quick-add-btn');
    addToCartBtn.addEventListener('click', () => {
      const productData = { id: 1111, variants: [{ id: 2222, available: false }] };
      const variantId = '41XX';
      const customerData = { 
        shopify_customer_id: 9999,
        email: '[email protected]',
        phone: '8123999123',
        country_code: '1',
        country: 'us'
      };
      
      // Basic usage
      window._RestockRocket.openInlineForm(
        productData,
        variantId,
        customerData,
        '#my-custom-container', // CSS selector where form will be inserted
        'afterend' // Where to insert relative to selector: 'beforebegin', 'afterbegin', 'beforeend', 'afterend'
      );
    
      // Alternative: Using Liquid objects directly
      // window._RestockRocket.openInlineForm(
      //   {{ product | json }},
      //   '{{ product.selected_or_first_available_variant.id }}',
      //   null,
      //   '#my-custom-container'
      // );
    });
    window._RestockRocket.removeInlineForm();
    const variantSelector = document.getElementById('variant-selector');
    variantSelector.addEventListener('change', (event) => {
      const selectedVariantId = event.target.value;
      window._RestockRocket.renderButtonForVariant(selectedVariantId);
    });
    const variantId = '41XX';
    const sellingPlan = window._RestockRocket.getSellingPlan(variantId);
    
    if (sellingPlan) {
      console.log('Preorder selling planDetails:', sellingPlan);
    } else {
      console.log('No preorder set up for this variant');
    }
    {
      shopify_selling_plan_group_id: 123456789,
      shopify_selling_plan_id: 987654321,
      enabled: true,
      variant_ids: [11111, 22222, 33333, 44444],
      name: "Preorder Offer",
      billing_checkout_charge_amount: "100.0",
      billing_checkout_charge_percentage: "10.0",
      billing_checkout_charge_type: "percentage",
      billing_description: null,
      billing_title: "Full payment",
      discount_text: "Save {{ discount }}",
      enable_billing_widget: true,
      inventory_provider: "stoq",
      payment_type: "full",
      preorder_badge_background_color: "#000000",
      preorder_badge_enabled: true,
      preorder_badge_text: null,
      preorder_badge_text_color: "#FFFFFF",
      preorder_button_description: "Note: This is a preorder. Items will ship based on the estimated delivery date.",
      preorder_button_description_background_color: "#ffffff",
      preorder_button_description_border_radius: 20,
      preorder_button_description_quantity_limit_suffix: " units available for preorder",
      preorder_button_description_shipping_text_prefix: "Shipping: ",
      preorder_button_description_show_quantity_limit: true,
      preorder_button_description_show_shipping: true,
      preorder_button_description_text_color: "#000000",
      preorder_button_text: "Preorder Now",
      preorder_shipping_text: "Estimated shipping: {{ date }}",
      pricing_amount: null,
      pricing_percentage: null,
      pricing_type: "no_discount",
      quantity_limit_text: "{{ quantity }} stock left",
      shipping_applies_to_all_products: true,
      shipping_text: "Shipping date to be determined",
      translations: { /* language translations object */ }
    }
    
    <div data-gb-custom-block data-tag="for">
      <div class="product-item">
        <h2>{{ product.title }}</h2>
        <button class="quick-add-btn" 
          data-product-data="{{ product | json }}" 
          data-variant-id="{{ product.selected_or_first_available_variant.id }}"
        >
          Quick Add
        </button>
      </div>
    </div>
    
    <script>
      document.querySelectorAll('.quick-add-btn').forEach(button => {
        button.addEventListener('click', function() {
          const productData = this.getAttribute('data-product-data');
          const variantId = this.getAttribute('data-variant-id');
          
          window._RestockRocket.openModal(productData, variantId);
        });
      });
    </script>
    
    <div data-gb-custom-block data-tag="if">
      <button id="add-to-cart-button">Add to Cart</button>
      <div data-gb-custom-block data-tag="else"></div>
      <button id="notify-me-btn">Notify Me When Available</button>
    </div>
    
    <script>
      const notifyMeBtn = document.getElementById('notify-me-btn');
      
      <div data-gb-custom-block data-tag="if" data-0='false' data-1='false' data-2='false' data-3='false'>
        notifyMeBtn.addEventListener('click', function() {
          window._RestockRocket.openModal({{ product | json }}, '{{ product.selected_or_first_available_variant.id }}');
        });
      </div>
      
      // For themes with variant selectors
      document.addEventListener('variantChange', function(event) {
        const variant = event.detail.variant;
        window._RestockRocket.renderButtonForVariant(variant.id);
      });
    </script>
    <div id="product-form" data-product-id="{{ product.id }}">
      <select id="variant-selector">
        {% for variant in product.variants %}
          <option value="{{ variant.id }}" {% if variant == product.selected_or_first_available_variant %}selected="selected"{% endif %}>
            {{ variant.title }}
          </option>
        {% endfor %}
      </select>
      
      <button id="add-to-cart-btn" {% unless product.selected_or_first_available_variant.available %}style="display: none;"{% endunless %}>
        Add to Cart
      </button>
      
      <button id="notify-me-btn" {% if product.selected_or_first_available_variant.available %}style="display: none;"{% endif %}>
        Notify Me
      </button>
    </div>
    
    <script>
      const productForm = document.getElementById('product-form');
      const variantSelector = document.getElementById('variant-selector');
      const addToCartBtn = document.getElementById('add-to-cart-btn');
      const notifyMeBtn = document.getElementById('notify-me-btn');
      
      function updateButtons(variantId) {
        const selectedVariant = {{ product.variants | json }}
          .find(variant => variant.id.toString() === variantId);
        
        if (selectedVariant && selectedVariant.available) {
          addToCartBtn.style.display = 'block';
          notifyMeBtn.style.display = 'none';
        } else {
          addToCartBtn.style.display = 'none';
          notifyMeBtn.style.display = 'block';
        }
      }
      
      variantSelector.addEventListener('change', function() {
        const selectedVariantId = this.value;
        updateButtons(selectedVariantId);
        window._RestockRocket.renderButtonForVariant(selectedVariantId);
      });
      
      notifyMeBtn.addEventListener('click', function() {
        const productData = {{ product | json }};
        const variantId = variantSelector.value;
        window._RestockRocket.openModal(productData, variantId);
      });
      
      // Initial setup
      updateButtons(variantSelector.value);
    </script>
    window._RestockRocketConfig.marketId

    Create Customer Intent to Buy Product

    post

    Create a new intent for a customer to be notified when a product is back in stock. Unlike other API endpoints for Back in Stock, this API endpoint does not require an API Key.

    Header parameters
    X-Shopify-Shop-DomainstringRequired

    The Shopify shop domain (e.g. 'restock-rocket-demo.myshopify.com')

    Content-Typestring · enumRequired

    Must be application/json

    Possible values:
    Body
    post
    /intents.json
    Responses
    200

    Request processed but with errors

    application/json
    201

    Intent created successfully

    application/json
    400

    Bad request

    401

    Unauthorized

    {
      "errors": [
        "text"
      ]
    }
    POST /api/v1/intents.json HTTP/1.1
    Host: app.stoqapp.com
    X-Shopify-Shop-Domain: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 437
    
    {
      "intent": {
        "shopify_variant_id": 1,
        "shopify_product_id": 1,
        "shopify_market_id": 1,
        "channel": "email",
        "quantity": 1,
        "source": "api"
      },
      "customer": {
        "id": "text",
        "name": "text",
        "email": "text",
        "phone": "text",
        "push": "text",
        "country_code": "text",
        "country": "text",
        "accepts_marketing": true,
        "locale": "text",
        "shopify_market_id": 1,
        "shopify_customer_id": "text"
      },
      "product": {
        "variant_count": 1,
        "title": "text",
        "variant_title": "text",
        "vendor": "text",
        "sku": "text"
      }
    }

    List and filter intents

    get
    Authorizations
    X-Auth-TokenstringRequired
    Query parameters
    shopify_variant_idintegerOptional

    Filter by Shopify Variant ID

    shopify_product_idintegerOptional

    Filter by Shopify Product ID

    emailstringOptional

    Filter by customer email

    phonestringOptional

    Filter by customer phone

    start_datestring · dateOptional

    Filter by start date (YYYY-MM-DD)

    end_datestring · dateOptional

    Filter by end date (YYYY-MM-DD)

    notifiedbooleanOptional

    Filter by notification status (true = notified, false = not notified)

    pageintegerOptional

    Page number for pagination

    per_pageintegerOptional

    Number of items per page (maximum 500)

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    A paginated list of intents

    application/json
    400

    Bad request

    401

    Unauthorized

    get
    /intents

    Get a specific intent

    get
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Intent ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    Intent details

    application/json
    401

    Unauthorized

    404

    Intent not found

    get
    /intents/{id}

    Transfer signups from one variant to another

    post

    Transfer intents (signups) from a source variant to a target variant. This is useful when consolidating variants or when products are restructured. By default transfers pending intents, but can transfer sent or all intents based on intent_type parameter.

    Authorizations
    X-Auth-TokenstringRequired
    Body
    from_shopify_variant_idintegerRequired

    Shopify variant ID to transfer signups from

    from_shopify_product_idintegerRequired

    Shopify product ID of the source variant

    to_shopify_variant_idintegerRequired

    Shopify variant ID to transfer signups to

    to_shopify_product_idintegerRequired

    Shopify product ID of the target variant

    intent_typestring · enumOptional

    Type of intents to transfer (default is unsent/pending)

    Possible values:
    Responses
    200

    Transfer completed successfully

    400

    Bad request - invalid parameters

    application/json
    401

    Unauthorized

    422

    Transfer failed

    application/json
    post
    /intents/transfer_signups

    Delete intents (single or multiple)

    delete

    Delete one or more intents by their IDs. Only intents that have not been sent (notified_at is null) can be deleted. If any of the intents have been sent, the entire operation will fail and return a 422 error with the IDs of sent intents. You can pass a single intent ID in the array to delete just one intent.

    Authorizations
    X-Auth-TokenstringRequired
    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    intent_idsstring[]Required

    Array of intent IDs to delete

    Responses
    200

    All intents deleted successfully

    application/json
    400

    Bad request - invalid parameters

    application/json
    401

    Unauthorized

    404

    No valid intents found

    application/json
    422

    Cannot delete intents that have already been sent

    application/json
    delete
    /intents/bulk_destroy

    Get products in demand report

    get

    Retrieve a paginated list of product variants with demand metrics based on customer intents. Returns aggregated data showing total intents, pending intents, and last requested date for each variant. Results can be filtered by date range and sorted by different metrics.

    Authorizations
    X-Auth-TokenstringRequired
    Query parameters
    start_datestring · dateOptional

    Filter by start date (YYYY-MM-DD). Filters based on last_requested_at field.

    end_datestring · dateOptional

    Filter by end date (YYYY-MM-DD). Filters based on last_requested_at field.

    sort_bystring · enumOptional

    Sort results by pending intents, total intents, or last requested date

    Default: pendingPossible values:
    directionstring · enumOptional

    Sort direction (ascending or descending)

    Default: descPossible values:
    pageintegerOptional

    Page number for pagination

    Default: 1
    per_pageinteger · max: 500Optional

    Number of items per page (maximum 500)

    Default: 25
    intent_typestringOptional

    Filter by intent type (used when loading product data)

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    A paginated list of product variants with demand metrics

    application/json
    400

    Bad request - invalid parameters

    application/json
    401

    Unauthorized

    get
    /intents/products_in_demand

    Notify multiple intents in bulk

    post
    Authorizations
    X-Auth-TokenstringRequired
    Body
    intent_idsstring[]Optional

    Array of intent IDs

    allow_resendbooleanOptional

    Allow resending notifications

    Responses
    200

    All notifications sent successfully

    application/json
    207

    Partial success (some notifications failed)

    application/json
    400

    Bad request

    401

    Unauthorized

    post
    /intents/bulk_notify_intent

    Notify a single intent

    post
    Authorizations
    X-Auth-TokenstringRequired
    Body
    idstringOptional

    Intent ID

    allow_resendbooleanOptional

    Allow resending notification

    Responses
    200

    Notification sent successfully

    application/json
    401

    Unauthorized

    404

    Intent not found

    422

    Failed to notify intent

    post
    /intents/notify_intent

    No content

    {
      "intents": [
        {
          "id": "text",
          "blocked_at": "2025-12-15T07:01:52.307Z",
          "channel": "text",
          "email": "text",
          "notified_at": "2025-12-15T07:01:52.307Z",
          "optin_confirmed": true,
          "phone": "text",
          "quantity": 1,
          "sent_notifications_count": 1,
          "source": "text",
          "type": "text",
          "unsubscribed_at": "2025-12-15T07:01:52.307Z",
          "created_at": "2025-12-15T07:01:52.307Z",
          "updated_at": "2025-12-15T07:01:52.307Z",
          "customer_id": "text",
          "intent_trigger_id": "text",
          "product_variant_id": "text",
          "shop_id": "text",
          "shopify_inventory_item_id": 1,
          "shopify_market_id": 1,
          "shopify_product_id": 1,
          "shopify_variant_id": 1,
          "customer_name": "text",
          "contact": "text",
          "customer_unsubscribed_at": "2025-12-15T07:01:52.307Z",
          "accepts_marketing": true,
          "notifications_count": 1
        }
      ],
      "meta": {
        "total_count": 1,
        "page": 1,
        "per_page": 1,
        "total_pages": 1
      }
    }
    GET /api/v1/external/intents HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    GET /api/v1/external/intents/{id} HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    {
      "id": "text",
      "blocked_at": "2025-12-15T07:01:52.307Z",
      "channel": "text",
      "email": "text",
      "notified_at": "2025-12-15T07:01:52.307Z",
      "optin_confirmed": true,
      "phone": "text",
      "quantity": 1,
      "sent_notifications_count": 1,
      "source": "text",
      "type": "text",
      "unsubscribed_at": "2025-12-15T07:01:52.307Z",
      "created_at": "2025-12-15T07:01:52.307Z",
      "updated_at": "2025-12-15T07:01:52.307Z",
      "customer_id": "text",
      "intent_trigger_id": "text",
      "product_variant_id": "text",
      "shop_id": "text",
      "shopify_inventory_item_id": 1,
      "shopify_market_id": 1,
      "shopify_product_id": 1,
      "shopify_variant_id": 1,
      "customer_name": "text",
      "contact": "text",
      "customer_unsubscribed_at": "2025-12-15T07:01:52.307Z",
      "accepts_marketing": true,
      "notifications_count": 1
    }
    POST /api/v1/external/intents/transfer_signups HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: YOUR_API_KEY
    Content-Type: application/json
    Accept: */*
    Content-Length: 141
    
    {
      "from_shopify_variant_id": 123456789,
      "from_shopify_product_id": 555666777,
      "to_shopify_variant_id": 987654321,
      "to_shopify_product_id": 111222333
    }
    {
      "success": true,
      "deleted_count": 1
    }
    DELETE /api/v1/external/intents/bulk_destroy HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 55
    
    {
      "intent_ids": [
        "123e4567-e89b-12d3-a456-426614174000"
      ]
    }
    {
      "product_variants_in_demand": [
        {
          "shopify_variant_id": 123456789,
          "shopify_product_id": 987654321,
          "shopify_inventory_item_id": 555666777,
          "total": 45,
          "pending": 23,
          "last_requested_at": "2024-01-15T10:30:00Z",
          "product_data": {
            "id": 987654321,
            "title": "Sample Product",
            "vendor": "Sample Vendor",
            "variants": [
              {
                "id": 123456789,
                "title": "Medium / Red",
                "sku": "SAMPLE-M-RED"
              }
            ]
          },
          "variant_data": {
            "id": 123456789,
            "title": "Medium / Red",
            "sku": "SAMPLE-M-RED"
          }
        }
      ],
      "page": 1,
      "per_page": 25,
      "has_next_page": false,
      "has_prev_page": false
    }
    GET /api/v1/external/intents/products_in_demand HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    POST /api/v1/external/intents/bulk_notify_intent HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: YOUR_API_KEY
    Content-Type: application/json
    Accept: */*
    Content-Length: 43
    
    {
      "intent_ids": [
        "text"
      ],
      "allow_resend": true
    }
    {
      "success": [
        "text"
      ],
      "failed": [
        {
          "intent_id": "text",
          "error": "text"
        }
      ]
    }
    POST /api/v1/external/intents/notify_intent HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: YOUR_API_KEY
    Content-Type: application/json
    Accept: */*
    Content-Length: 33
    
    {
      "id": "text",
      "allow_resend": true
    }
    {
      "success": true,
      "intent_id": "text"
    }

    Create a new selling plan

    post
    Authorizations
    X-Auth-TokenstringRequired
    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    Responses
    201

    Selling plan created successfully

    application/json
    401

    Unauthorized

    422

    Validation errors

    application/json
    post
    /preorders

    Delete a selling plan (soft delete)

    delete
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    Selling plan deleted successfully

    application/json
    401

    Unauthorized

    404

    Selling plan not found

    422

    Failed to delete selling plan

    application/json
    delete
    /preorders/{id}

    Remove multiple product variants from a selling plan

    delete

    Remove multiple product variants from a selling plan. Optionally, you can also update the inventory policy of the removed variants in the same request to avoid making separate API calls.

    When inventory_policy is provided, the inventory policy update is performed synchronously (inline) for better performance and to avoid race conditions.

    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Query parameters
    shopify_variant_idsinteger[]Required

    Array of Shopify variant IDs to remove

    inventory_policystring · enumOptional

    Optional. Inventory policy to set for the removed variants. CONTINUE allows overselling, DENY prevents it.

    Possible values:
    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    Variants removed successfully

    application/json
    400

    Bad request - missing or invalid parameters

    application/json
    401

    Unauthorized

    404

    Selling plan or variants not found

    application/json
    422

    Failed to remove variants or invalid inventory policy

    application/json
    delete
    /preorders/{id}/remove_variant

    List and filter selling plans

    get
    Authorizations
    X-Auth-TokenstringRequired
    Query parameters
    namestringOptional

    Filter by selling plan name or internal name

    pageintegerOptional

    Page number for pagination

    per_pageintegerOptional

    Number of items per page

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    A paginated list of selling plans

    application/json
    400

    Bad request

    401

    Unauthorized

    get
    /preorders

    Get a specific selling plan

    get
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    Selling plan details

    application/json
    401

    Unauthorized

    404

    Selling plan not found

    get
    /preorders/{id}

    Update a selling plan

    put
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    Responses
    200

    Selling plan updated successfully

    application/json
    401

    Unauthorized

    404

    Selling plan not found

    422

    Validation errors

    application/json
    put
    /preorders/{id}

    Update variant-specific settings for a selling plan

    patch
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    shopify_variant_idintegerRequired

    Shopify variant ID to update settings for

    shipping_textstringOptional

    Custom shipping text for this variant

    preorder_max_countintegerOptional

    Maximum number of preorders allowed for this variant

    Responses
    200

    Variant settings updated successfully

    application/json
    400

    Bad request - missing required parameters or no settings to update

    application/json
    401

    Unauthorized

    404

    Selling plan or variant not found

    application/json
    422

    Failed to update variant settings

    application/json
    patch
    /preorders/{id}/update_variant_settings

    Get product variants associated with a selling plan

    get

    Retrieve product variants associated with a selling plan, including their preorder details and sales metrics.

    Filtering behavior:

    • No parameters: Returns all product variants in the selling plan

    • shopify_product_id: Returns all variants for that specific product

    • shopify_variant_id: Returns only that specific variant (single object response)

    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Query parameters
    shopify_product_idintegerOptional

    Filter by specific Shopify product ID to get all variants for that product

    shopify_variant_idintegerOptional

    Filter by specific Shopify variant ID to get only that variant (returns single object)

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Responses
    200

    Product variants with their preorder details and sales metrics

    application/json
    400

    Bad request - cannot filter by both product and variant ID

    application/json
    401

    Unauthorized

    404

    Selling plan not found or variant not found in this selling plan

    application/json
    get
    /preorders/{id}/product_variants

    Add multiple product variants to a selling plan

    post
    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    shopify_variant_idsinteger[]Required

    Array of Shopify variant IDs to add

    Responses
    200

    Variants added successfully

    application/json
    400

    Bad request - missing or invalid shopify_variant_ids

    application/json
    401

    Unauthorized

    404

    Selling plan not found

    422

    Some variants already added or other error

    application/json
    post
    /preorders/{id}/add_variant

    Queue a bulk update of inventory policy for multiple variants

    post

    Queues a background job to update the inventory policy for multiple variants. The operation is performed asynchronously to handle large numbers of variants efficiently. Updates are processed in batches of up to 1000 variants to stay within message size limits.

    Authorizations
    X-Auth-TokenstringRequired
    Path parameters
    idstringRequired

    Selling plan ID

    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    shopify_variant_idsinteger[]Required

    Array of Shopify variant IDs to update

    inventory_policystring · enumRequired

    The inventory policy to set for the variants

    Possible values:
    Responses
    200

    Inventory policy update has been queued successfully

    application/json
    400

    Bad request - missing or invalid parameters

    application/json
    401

    Unauthorized

    404

    Selling plan not found

    application/json
    422

    Invalid inventory policy

    application/json
    post
    /preorders/{id}/bulk_toggle_inventory_policy

    Send shipping update emails to multiple orders

    post

    Send shipping update emails to multiple preorders. You can specify orders using either:

    • STOQ internal order IDs (UUIDs) via order_ids

    • Shopify order IDs via shopify_order_ids

    You must provide one or the other, but not both.

    Authorizations
    X-Auth-TokenstringRequired
    Header parameters
    X-Auth-TokenstringRequired

    API key for authentication

    Body
    order_idsstring · uuid[]Optional

    Array of STOQ internal order UUIDs to send shipping updates to (mutually exclusive with shopify_order_ids)

    shopify_order_idsinteger[]Optional

    Array of Shopify order IDs to send shipping updates to (mutually exclusive with order_ids)

    subjectstringRequired

    Email subject line

    headerstringRequired

    Email header text

    descriptionstringRequired

    Email body description

    post
    /preorders/send_shipping_update
    Responses
    200

    Shipping update emails queued successfully

    application/json
    400

    Bad request - missing required parameters or invalid input

    application/json
    401

    Unauthorized

    404

    No valid orders found

    application/json
    POST /api/v1/external/preorders/send_shipping_update HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 242
    
    {
      "order_ids": [
        "550e8400-e29b-41d4-a716-446655440000",
        "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
      ],
      "subject": "Shipping Update",
      "header": "Your order is on its way!",
      "description": "We wanted to let you know that your preorder will be shipping soon."
    }
    {
      "success": true,
      "message": "Shipping update emails will be sent",
      "orders_count": 2
    }
    {
      "id": "text",
      "name": "text",
      "internal_name": "text",
      "enabled": true,
      "billing_type": "exact_time",
      "billing_at": "2025-12-15T07:01:52.307Z",
      "billing_after_n_intervals": 1,
      "billing_after_interval_type": "day",
      "billing_checkout_charge_amount": 1,
      "billing_checkout_charge_percentage": 1,
      "billing_checkout_charge_type": "percentage",
      "billing_title": "text",
      "billing_description": "text",
      "delivery_type": "anchor",
      "delivery_at": "2025-12-15T07:01:52.307Z",
      "delivery_after_n_intervals": 1,
      "delivery_after_interval_type": "day",
      "inventory_reserve_type": "on_sale",
      "inventory_provider": "stoq",
      "pricing_type": "percentage",
      "pricing_amount": 1,
      "pricing_percentage": 1,
      "quantity_limit_text": "text",
      "preorder_button_text": "text",
      "preorder_button_text_color": "text",
      "preorder_button_background_color": "text",
      "preorder_button_colors_enabled": true,
      "preorder_discounted_price_enabled": true,
      "preorder_button_description": "text",
      "preorder_button_description_background_color": "text",
      "preorder_button_description_border_radius": "text",
      "preorder_button_description_quantity_limit_suffix": "text",
      "preorder_button_description_shipping_text_prefix": "text",
      "preorder_button_description_show_quantity_limit": true,
      "preorder_button_description_show_shipping": true,
      "preorder_button_description_text_color": "text",
      "preorder_badge_enabled": true,
      "preorder_badge_text": "text",
      "preorder_badge_text_color": "text",
      "preorder_badge_background_color": "text",
      "preorder_shipping_text": "text",
      "shipping_text": "text",
      "shipping_line_item_property_enabled": true,
      "shipping_applies_to_all_products": true,
      "discount_text": "text",
      "preorder_tags": "text",
      "product_variants_source": "all",
      "product_variants_source_id": 1,
      "selling_plan_product_variants_count": 1,
      "shopify_selling_plan_id": 1,
      "shopify_selling_plan_group_id": 1,
      "use_shopify_selling_plan": true,
      "shop_id": 1,
      "market_id": 1,
      "created_at": "2025-12-15T07:01:52.307Z",
      "updated_at": "2025-12-15T07:01:52.307Z",
      "discarded_at": "2025-12-15T07:01:52.307Z",
      "ongoing_job": true,
      "shopify_variant_ids": [
        1
      ]
    }
    POST /api/v1/external/preorders HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 1758
    
    {
      "selling_plan": {
        "name": "text",
        "internal_name": "text",
        "enabled": true,
        "billing_type": "exact_time",
        "billing_at": "2025-12-15T07:01:52.307Z",
        "billing_after_n_intervals": 1,
        "billing_after_interval_type": "day",
        "billing_checkout_charge_amount": 1,
        "billing_checkout_charge_percentage": 1,
        "billing_checkout_charge_type": "percentage",
        "billing_title": "text",
        "billing_description": "text",
        "delivery_type": "anchor",
        "delivery_at": "2025-12-15T07:01:52.307Z",
        "delivery_after_n_intervals": 1,
        "delivery_after_interval_type": "day",
        "inventory_reserve_type": "on_sale",
        "inventory_provider": "stoq",
        "pricing_type": "percentage",
        "pricing_amount": 1,
        "pricing_percentage": 1,
        "quantity_limit_text": "text",
        "preorder_button_text": "text",
        "preorder_button_text_color": "text",
        "preorder_button_background_color": "text",
        "preorder_button_colors_enabled": true,
        "preorder_discounted_price_enabled": true,
        "preorder_button_description": "text",
        "preorder_button_description_background_color": "text",
        "preorder_button_description_border_radius": "text",
        "preorder_button_description_quantity_limit_suffix": "text",
        "preorder_button_description_shipping_text_prefix": "text",
        "preorder_button_description_show_quantity_limit": true,
        "preorder_button_description_show_shipping": true,
        "preorder_button_description_text_color": "text",
        "preorder_badge_enabled": true,
        "preorder_badge_text": "text",
        "preorder_badge_text_color": "text",
        "preorder_badge_background_color": "text",
        "preorder_shipping_text": "text",
        "shipping_text": "text",
        "shipping_line_item_property_enabled": true,
        "shipping_applies_to_all_products": true,
        "discount_text": "text",
        "preorder_tags": "text",
        "product_variants_source": "all",
        "product_variants_source_id": 1,
        "markets_enabled": true,
        "shopify_market_ids": [
          1
        ],
        "auto_collect_payment": true,
        "use_shopify_selling_plan": true
      }
    }
    DELETE /api/v1/external/preorders/{id} HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    {
      "success": true,
      "message": "text"
    }
    {
      "success": true,
      "message": "Variants removed from selling plan",
      "variants_removed": [
        1234567,
        2345678
      ]
    }
    DELETE /api/v1/external/preorders/{id}/remove_variant?shopify_variant_ids=1 HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    GET /api/v1/external/preorders HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    {
      "selling_plans": [
        {
          "id": "text",
          "name": "text",
          "internal_name": "text",
          "enabled": true,
          "selling_plan_product_variants_count": 1,
          "created_at": "2025-12-15T07:01:52.307Z",
          "updated_at": "2025-12-15T07:01:52.307Z",
          "shopify_variant_ids": [
            1
          ]
        }
      ],
      "meta": {
        "total_count": 1,
        "page": 1,
        "per_page": 1,
        "total_pages": 1
      }
    }
    GET /api/v1/external/preorders/{id} HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    {
      "id": "text",
      "name": "text",
      "internal_name": "text",
      "enabled": true,
      "billing_type": "exact_time",
      "billing_at": "2025-12-15T07:01:52.307Z",
      "billing_after_n_intervals": 1,
      "billing_after_interval_type": "day",
      "billing_checkout_charge_amount": 1,
      "billing_checkout_charge_percentage": 1,
      "billing_checkout_charge_type": "percentage",
      "billing_title": "text",
      "billing_description": "text",
      "delivery_type": "anchor",
      "delivery_at": "2025-12-15T07:01:52.307Z",
      "delivery_after_n_intervals": 1,
      "delivery_after_interval_type": "day",
      "inventory_reserve_type": "on_sale",
      "inventory_provider": "stoq",
      "pricing_type": "percentage",
      "pricing_amount": 1,
      "pricing_percentage": 1,
      "quantity_limit_text": "text",
      "preorder_button_text": "text",
      "preorder_button_text_color": "text",
      "preorder_button_background_color": "text",
      "preorder_button_colors_enabled": true,
      "preorder_discounted_price_enabled": true,
      "preorder_button_description": "text",
      "preorder_button_description_background_color": "text",
      "preorder_button_description_border_radius": "text",
      "preorder_button_description_quantity_limit_suffix": "text",
      "preorder_button_description_shipping_text_prefix": "text",
      "preorder_button_description_show_quantity_limit": true,
      "preorder_button_description_show_shipping": true,
      "preorder_button_description_text_color": "text",
      "preorder_badge_enabled": true,
      "preorder_badge_text": "text",
      "preorder_badge_text_color": "text",
      "preorder_badge_background_color": "text",
      "preorder_shipping_text": "text",
      "shipping_text": "text",
      "shipping_line_item_property_enabled": true,
      "shipping_applies_to_all_products": true,
      "discount_text": "text",
      "preorder_tags": "text",
      "product_variants_source": "all",
      "product_variants_source_id": 1,
      "selling_plan_product_variants_count": 1,
      "shopify_selling_plan_id": 1,
      "shopify_selling_plan_group_id": 1,
      "use_shopify_selling_plan": true,
      "shop_id": 1,
      "market_id": 1,
      "created_at": "2025-12-15T07:01:52.307Z",
      "updated_at": "2025-12-15T07:01:52.307Z",
      "discarded_at": "2025-12-15T07:01:52.307Z",
      "ongoing_job": true,
      "shopify_variant_ids": [
        1
      ]
    }
    {
      "id": "text",
      "name": "text",
      "internal_name": "text",
      "enabled": true,
      "billing_type": "exact_time",
      "billing_at": "2025-12-15T07:01:52.307Z",
      "billing_after_n_intervals": 1,
      "billing_after_interval_type": "day",
      "billing_checkout_charge_amount": 1,
      "billing_checkout_charge_percentage": 1,
      "billing_checkout_charge_type": "percentage",
      "billing_title": "text",
      "billing_description": "text",
      "delivery_type": "anchor",
      "delivery_at": "2025-12-15T07:01:52.307Z",
      "delivery_after_n_intervals": 1,
      "delivery_after_interval_type": "day",
      "inventory_reserve_type": "on_sale",
      "inventory_provider": "stoq",
      "pricing_type": "percentage",
      "pricing_amount": 1,
      "pricing_percentage": 1,
      "quantity_limit_text": "text",
      "preorder_button_text": "text",
      "preorder_button_text_color": "text",
      "preorder_button_background_color": "text",
      "preorder_button_colors_enabled": true,
      "preorder_discounted_price_enabled": true,
      "preorder_button_description": "text",
      "preorder_button_description_background_color": "text",
      "preorder_button_description_border_radius": "text",
      "preorder_button_description_quantity_limit_suffix": "text",
      "preorder_button_description_shipping_text_prefix": "text",
      "preorder_button_description_show_quantity_limit": true,
      "preorder_button_description_show_shipping": true,
      "preorder_button_description_text_color": "text",
      "preorder_badge_enabled": true,
      "preorder_badge_text": "text",
      "preorder_badge_text_color": "text",
      "preorder_badge_background_color": "text",
      "preorder_shipping_text": "text",
      "shipping_text": "text",
      "shipping_line_item_property_enabled": true,
      "shipping_applies_to_all_products": true,
      "discount_text": "text",
      "preorder_tags": "text",
      "product_variants_source": "all",
      "product_variants_source_id": 1,
      "selling_plan_product_variants_count": 1,
      "shopify_selling_plan_id": 1,
      "shopify_selling_plan_group_id": 1,
      "use_shopify_selling_plan": true,
      "shop_id": 1,
      "market_id": 1,
      "created_at": "2025-12-15T07:01:52.307Z",
      "updated_at": "2025-12-15T07:01:52.307Z",
      "discarded_at": "2025-12-15T07:01:52.307Z",
      "ongoing_job": true,
      "shopify_variant_ids": [
        1
      ]
    }
    PUT /api/v1/external/preorders/{id} HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 1758
    
    {
      "selling_plan": {
        "name": "text",
        "internal_name": "text",
        "enabled": true,
        "billing_type": "exact_time",
        "billing_at": "2025-12-15T07:01:52.307Z",
        "billing_after_n_intervals": 1,
        "billing_after_interval_type": "day",
        "billing_checkout_charge_amount": 1,
        "billing_checkout_charge_percentage": 1,
        "billing_checkout_charge_type": "percentage",
        "billing_title": "text",
        "billing_description": "text",
        "delivery_type": "anchor",
        "delivery_at": "2025-12-15T07:01:52.307Z",
        "delivery_after_n_intervals": 1,
        "delivery_after_interval_type": "day",
        "inventory_reserve_type": "on_sale",
        "inventory_provider": "stoq",
        "pricing_type": "percentage",
        "pricing_amount": 1,
        "pricing_percentage": 1,
        "quantity_limit_text": "text",
        "preorder_button_text": "text",
        "preorder_button_text_color": "text",
        "preorder_button_background_color": "text",
        "preorder_button_colors_enabled": true,
        "preorder_discounted_price_enabled": true,
        "preorder_button_description": "text",
        "preorder_button_description_background_color": "text",
        "preorder_button_description_border_radius": "text",
        "preorder_button_description_quantity_limit_suffix": "text",
        "preorder_button_description_shipping_text_prefix": "text",
        "preorder_button_description_show_quantity_limit": true,
        "preorder_button_description_show_shipping": true,
        "preorder_button_description_text_color": "text",
        "preorder_badge_enabled": true,
        "preorder_badge_text": "text",
        "preorder_badge_text_color": "text",
        "preorder_badge_background_color": "text",
        "preorder_shipping_text": "text",
        "shipping_text": "text",
        "shipping_line_item_property_enabled": true,
        "shipping_applies_to_all_products": true,
        "discount_text": "text",
        "preorder_tags": "text",
        "product_variants_source": "all",
        "product_variants_source_id": 1,
        "markets_enabled": true,
        "shopify_market_ids": [
          1
        ],
        "auto_collect_payment": true,
        "use_shopify_selling_plan": true
      }
    }
    {
      "success": true,
      "message": "text",
      "variant": {
        "shopify_variant_id": 1,
        "shipping_text": "text",
        "preorder_max_count": 1
      }
    }
    PATCH /api/v1/external/preorders/{id}/update_variant_settings HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 70
    
    {
      "shopify_variant_id": 1,
      "shipping_text": "text",
      "preorder_max_count": 1
    }
    {
      "selling_plan_id": "abc-123-def-456",
      "selling_plan_name": "Summer Preorder",
      "currency": "USD",
      "product_variants": [
        {
          "shopify_product_id": 7891011,
          "shopify_variant_id": 1234567,
          "product_title": "Summer T-Shirt",
          "variant_title": "Large / Blue",
          "preorder_units_sold": 2,
          "preorder_max_count": 10,
          "shipping_text": "Ships in 2-3 weeks"
        }
      ],
      "meta": {
        "total_variants": 1,
        "total_units_sold": 2
      }
    }
    GET /api/v1/external/preorders/{id}/product_variants HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Accept: */*
    
    {
      "success": true,
      "message": "text",
      "variants_added": [
        1
      ]
    }
    POST /api/v1/external/preorders/{id}/add_variant HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 27
    
    {
      "shopify_variant_ids": [
        1
      ]
    }
    {
      "success": true,
      "message": "Inventory policy update has been queued",
      "variants_queued": [
        1
      ]
    }
    POST /api/v1/external/preorders/{id}/bulk_toggle_inventory_policy HTTP/1.1
    Host: app.stoqapp.com
    X-Auth-Token: text
    Content-Type: application/json
    Accept: */*
    Content-Length: 57
    
    {
      "shopify_variant_ids": [
        1
      ],
      "inventory_policy": "CONTINUE"
    }