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...
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:
Open the STOQ app inside your Shopify Admin panel
Navigate to "Back in stock alerts > Integrations"
Scroll down to find the "API Key" section
Click the copy button to get your API key

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.
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.
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)
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
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
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 MetafieldsEnable 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
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
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
Selling plans can be configured for specific markets in multi-market stores
Different markets may have different preorder terms or availability
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.
Key: market_preorder_count
Type: json
Namespace: restockrocket_production
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
Key: market_preorder_max_count
Type: json
Namespace: restockrocket_production
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
Key: market_shipping_text
Type: json
Namespace: restockrocket_production
Stores market-specific shipping/delivery timeline text
Allows different shipping information per market
Stored as a JSON object mapping market IDs to shipping text
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"}
}
}
}
}
}
}
}
}Key: selling_plan_ids
Type: json
Namespace: restockrocket_production
Owner: Product Variant
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
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
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
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
Use Case: Show current preorder count and remaining spots.
Use Case: Show shipping info specific to the selected variant.
jsonNamespace: 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
Use Case: Show preorder badge when variant is part of a selling plan.
Use Case: Use custom button text from selling plan configuration.
Use Case: Display how many preorder spots are left.
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>Product Page
openModal, openInlineForm, removeInlineForm, renderButtonForVariant, getSellingPlan
Collection, Home, and Custom Pages
openModal
All pages
marketId
Event triggered when STOQ's app embed is loaded on any page supported by the app. Pages supported: Product, Collection, Home, Search
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:
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:
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:
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:
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:
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.
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.marketIdCreate 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.
The Shopify shop domain (e.g. 'restock-rocket-demo.myshopify.com')
Must be application/json
Request processed but with errors
Intent created successfully
Bad request
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"
}
}Filter by Shopify Variant ID
Filter by Shopify Product ID
Filter by customer email
Filter by customer phone
Filter by start date (YYYY-MM-DD)
Filter by end date (YYYY-MM-DD)
Filter by notification status (true = notified, false = not notified)
Page number for pagination
Number of items per page (maximum 500)
API key for authentication
A paginated list of intents
Bad request
Unauthorized
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.
Shopify variant ID to transfer signups from
Shopify product ID of the source variant
Shopify variant ID to transfer signups to
Shopify product ID of the target variant
Type of intents to transfer (default is unsent/pending)
Transfer completed successfully
Bad request - invalid parameters
Unauthorized
Transfer failed
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.
API key for authentication
Array of intent IDs to delete
All intents deleted successfully
Bad request - invalid parameters
Unauthorized
No valid intents found
Cannot delete intents that have already been sent
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.
Filter by start date (YYYY-MM-DD). Filters based on last_requested_at field.
Filter by end date (YYYY-MM-DD). Filters based on last_requested_at field.
Sort results by pending intents, total intents, or last requested date
pendingPossible values: Sort direction (ascending or descending)
descPossible values: Page number for pagination
1Number of items per page (maximum 500)
25Filter by intent type (used when loading product data)
API key for authentication
A paginated list of product variants with demand metrics
Bad request - invalid parameters
Unauthorized
Array of intent IDs
Allow resending notifications
All notifications sent successfully
Partial success (some notifications failed)
Bad request
Unauthorized
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"
}Selling plan ID
API key for authentication
Selling plan deleted successfully
Unauthorized
Selling plan not found
Failed to delete selling plan
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.
Selling plan ID
Array of Shopify variant IDs to remove
Optional. Inventory policy to set for the removed variants. CONTINUE allows overselling, DENY prevents it.
API key for authentication
Variants removed successfully
Bad request - missing or invalid parameters
Unauthorized
Selling plan or variants not found
Failed to remove variants or invalid inventory policy
Filter by selling plan name or internal name
Page number for pagination
Number of items per page
API key for authentication
A paginated list of selling plans
Bad request
Unauthorized
Selling plan ID
API key for authentication
Selling plan updated successfully
Unauthorized
Selling plan not found
Validation errors
Selling plan ID
API key for authentication
Shopify variant ID to update settings for
Custom shipping text for this variant
Maximum number of preorders allowed for this variant
Variant settings updated successfully
Bad request - missing required parameters or no settings to update
Unauthorized
Selling plan or variant not found
Failed to update variant settings
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)
Selling plan ID
Filter by specific Shopify product ID to get all variants for that product
Filter by specific Shopify variant ID to get only that variant (returns single object)
API key for authentication
Product variants with their preorder details and sales metrics
Bad request - cannot filter by both product and variant ID
Unauthorized
Selling plan not found or variant not found in this selling plan
Selling plan ID
API key for authentication
Array of Shopify variant IDs to add
Variants added successfully
Bad request - missing or invalid shopify_variant_ids
Unauthorized
Selling plan not found
Some variants already added or other error
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.
Selling plan ID
API key for authentication
Array of Shopify variant IDs to update
The inventory policy to set for the variants
Inventory policy update has been queued successfully
Bad request - missing or invalid parameters
Unauthorized
Selling plan not found
Invalid inventory policy
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.
API key for authentication
Array of STOQ internal order UUIDs to send shipping updates to (mutually exclusive with shopify_order_ids)
Array of Shopify order IDs to send shipping updates to (mutually exclusive with order_ids)
Email subject line
Email header text
Email body description
Shipping update emails queued successfully
Bad request - missing required parameters or invalid input
Unauthorized
No valid orders found
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"
}