STOQ API v1
v1.0.0Contact: support@stoqapp.com
https://app.stoqapp.com/api/v1ProductionBack in Stock
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)
- Quantity: How many units the customer is interested in when the product is back in stock
- 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
- Can be unsubscribed by the customer
- Tracks notification history and opt-in status
- Compliance & Privacy:
- Includes GDPR opt-in confirmation tracking
- Tracks marketing preferences
- Maintains unsubscribe status
Preorders
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.
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
Authentication
ApiKeyAuthapiKeyAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
API Key: X-Auth-Token in header
Back in Stock
Create Customer Intent to Buy Product
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.
Body
intentobjectrequiredcustomerobjectrequiredproductobjectProduct data is only needed if you have optin confirmation or alerts to your shop set up
Parameters
X-Shopify-Shop-DomainstringrequiredheaderThe Shopify shop domain (e.g. 'restock-rocket-demo.myshopify.com')
Content-Typestringapplication/jsonrequiredheaderMust be application/json
Response
Request processed but with errors
Intent created successfully
Bad request
Unauthorized
curl -X POST 'https://app.stoqapp.com/api/v1/intents.json' \
-H 'Content-Type: application/json' \
-d '{
"intent": {
"shopify_variant_id": 43900910010503,
"shopify_product_id": 7891234567890,
"channel": "email",
"quantity": 1,
"source": "api"
},
"customer": {
"email": "shopper@example.com",
"name": "Alex Shopper",
"accepts_marketing": true,
"country": "us"
}
}'const response = await fetch('https://app.stoqapp.com/api/v1/intents.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"intent": {
"shopify_variant_id": 43900910010503,
"shopify_product_id": 7891234567890,
"channel": "email",
"quantity": 1,
"source": "api"
},
"customer": {
"email": "shopper@example.com",
"name": "Alex Shopper",
"accepts_marketing": true,
"country": "us"
}
}),
});
const data = await response.json();import requests
payload = {
"intent": {
"shopify_variant_id": 43900910010503,
"shopify_product_id": 7891234567890,
"channel": "email",
"quantity": 1,
"source": "api"
},
"customer": {
"email": "shopper@example.com",
"name": "Alex Shopper",
"accepts_marketing": True,
"country": "us"
}
}
response = requests.post('https://app.stoqapp.com/api/v1/intents.json', json=payload)
data = response.json(){
"intent": {
"shopify_variant_id": 43900910010503,
"shopify_product_id": 7891234567890,
"channel": "email",
"quantity": 1,
"source": "api"
},
"customer": {
"email": "shopper@example.com",
"name": "Alex Shopper",
"accepts_marketing": true,
"country": "us"
}
}{
"errors": [
"string"
]
}{
"intents": [
{
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"channel": "email",
"email": "shopper@example.com",
"phone": null,
"quantity": 1,
"notified_at": null,
"optin_confirmed": true,
"source": "api",
"type": "restock",
"sent_notifications_count": 0,
"created_at": "2026-06-20T14:30:00Z",
"updated_at": "2026-06-20T14:30:00Z",
"customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
"shopify_product_id": 7891234567890,
"shopify_variant_id": 43900910010503,
"accepts_marketing": true
}
],
"errors": []
}Delete intents (single or multiple)
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.
Body
intent_idsArray<string>requiredArray of intent IDs to delete
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
Response
All intents deleted successfully
Bad request - invalid parameters
Unauthorized
No valid intents found
Cannot delete intents that have already been sent
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X DELETE 'https://app.stoqapp.com/api/v1/intents/bulk_destroy' \
-H 'Content-Type: application/json' \
-d '{
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
]
}'const response = await fetch('https://app.stoqapp.com/api/v1/intents/bulk_destroy', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
]
}),
});
const data = await response.json();import requests
payload = {
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
]
}
response = requests.delete('https://app.stoqapp.com/api/v1/intents/bulk_destroy', json=payload)
data = response.json(){
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
]
}{
"success": true,
"deleted_count": 2
}{
"error": "string"
}{
"error": "string"
}{
"error": "string",
"sent_intent_ids": [
"string"
]
}Get a specific intent
Retrieve a single back-in-stock intent (signup) by its STOQ ID. Returns the full intent record — the customer contact details, channel, requested quantity, and notification status. Returns 404 if no intent with that ID exists for the authenticated shop.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathIntent ID
Response
Intent details
Unauthorized
Intent not found
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/intents/{id}'const response = await fetch('https://app.stoqapp.com/api/v1/intents/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/intents/{id}')
data = response.json(){
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"channel": "email",
"email": "shopper@example.com",
"phone": null,
"quantity": 1,
"notified_at": null,
"optin_confirmed": true,
"source": "api",
"type": "restock",
"sent_notifications_count": 0,
"created_at": "2026-06-20T14:30:00Z",
"updated_at": "2026-06-20T14:30:00Z",
"customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
"shopify_product_id": 7891234567890,
"shopify_variant_id": 43900910010503,
"accepts_marketing": true
}Get products in demand report
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.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
start_datestring<date>queryFilter by start date (YYYY-MM-DD). Filters based on last_requested_at field.
end_datestring<date>queryFilter by end date (YYYY-MM-DD). Filters based on last_requested_at field.
sort_bystringpendingtotallast_requested_atpendingquerySort results by pending intents, total intents, or last requested date
directionstringascdescdescquerySort direction (ascending or descending)
pageinteger1queryPage number for pagination
per_pageinteger<= 50025queryNumber of items per page (maximum 500)
intent_typestringqueryFilter by intent type (used when loading product data)
Response
A paginated list of product variants with demand metrics
Bad request - invalid parameters
Unauthorized
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/intents/products_in_demand'const response = await fetch('https://app.stoqapp.com/api/v1/intents/products_in_demand', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/intents/products_in_demand')
data = response.json(){
"product_variants_in_demand": [
{
"shopify_variant_id": 43900910010503,
"shopify_product_id": 7891234567890,
"total": 42,
"pending": 37,
"last_requested_at": "2026-06-24T09:12:00Z",
"variant_data": {
"id": 43900910010503,
"title": "Medium / Red",
"sku": "TSHIRT-M-RED"
},
"product_data": {
"id": 7891234567890,
"title": "Classic T-Shirt",
"vendor": "Acme"
}
}
],
"page": 1,
"per_page": 25,
"has_next_page": true,
"has_prev_page": false
}{
"error": "string"
}List and filter intents
List back-in-stock intents (signups) for the shop, newest first. Supports filtering by Shopify product or variant, customer email or phone, creation date range, and notification status, with page-based pagination (up to 500 per page). Returns the matching intents alongside pagination metadata.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
shopify_variant_idintegerqueryFilter by Shopify Variant ID
shopify_product_idintegerqueryFilter by Shopify Product ID
emailstringqueryFilter by customer email
phonestringqueryFilter by customer phone
start_datestring<date>queryFilter by start date (YYYY-MM-DD)
end_datestring<date>queryFilter by end date (YYYY-MM-DD)
notifiedbooleanqueryFilter by notification status (true = notified, false = not notified)
pageintegerqueryPage number for pagination
per_pageintegerqueryNumber of items per page (maximum 500)
Response
A paginated list of intents
Bad request
Unauthorized
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/intents'const response = await fetch('https://app.stoqapp.com/api/v1/intents', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/intents')
data = response.json(){
"intents": [
{
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"channel": "email",
"email": "shopper@example.com",
"phone": null,
"quantity": 1,
"notified_at": null,
"optin_confirmed": true,
"source": "api",
"type": "restock",
"sent_notifications_count": 0,
"created_at": "2026-06-20T14:30:00Z",
"updated_at": "2026-06-20T14:30:00Z",
"customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
"shopify_product_id": 7891234567890,
"shopify_variant_id": 43900910010503,
"accepts_marketing": true
}
],
"meta": {
"total_count": 128,
"page": 1,
"per_page": 25,
"total_pages": 6
}
}Notify a single intent
Send the back-in-stock notification for a single intent immediately, regardless of current inventory. By default an intent that has already been notified will not be sent again; set allow_resend to true to force a resend. Returns 404 if the intent does not exist and 422 if the notification could not be sent.
Body
idstringIntent ID
allow_resendbooleanAllow resending notification
Response
Notification sent successfully
Unauthorized
Intent not found
Failed to notify intent
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/intents/notify_intent' \
-H 'Content-Type: application/json' \
-d '{
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"allow_resend": false
}'const response = await fetch('https://app.stoqapp.com/api/v1/intents/notify_intent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"allow_resend": false
}),
});
const data = await response.json();import requests
payload = {
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"allow_resend": False
}
response = requests.post('https://app.stoqapp.com/api/v1/intents/notify_intent', json=payload)
data = response.json(){
"id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"allow_resend": false
}{
"success": true,
"intent_id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70"
}Notify multiple intents in bulk
Send back-in-stock notifications for multiple intents in one request. Each intent is processed independently; the response reports which succeeded and which failed, returning 207 when only some succeed. Set allow_resend to true to re-notify intents that were already sent.
Body
intent_idsArray<string>Array of intent IDs
allow_resendbooleanAllow resending notifications
Response
All notifications sent successfully
Partial success (some notifications failed)
Bad request
Unauthorized
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/intents/bulk_notify_intent' \
-H 'Content-Type: application/json' \
-d '{
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
],
"allow_resend": false
}'const response = await fetch('https://app.stoqapp.com/api/v1/intents/bulk_notify_intent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
],
"allow_resend": false
}),
});
const data = await response.json();import requests
payload = {
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
],
"allow_resend": False
}
response = requests.post('https://app.stoqapp.com/api/v1/intents/bulk_notify_intent', json=payload)
data = response.json(){
"intent_ids": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
"1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
],
"allow_resend": false
}{
"success": [
"8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70"
],
"failed": [
{
"intent_id": "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809",
"error": "Already notified"
}
]
}{
"success": [
"string"
],
"failed": [
{
"intent_id": "string",
"error": "string"
}
]
}Transfer signups from one variant to another
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.
Body
from_shopify_variant_idintegerrequiredShopify variant ID to transfer signups from
from_shopify_product_idintegerrequiredShopify product ID of the source variant
to_shopify_variant_idintegerrequiredShopify variant ID to transfer signups to
to_shopify_product_idintegerrequiredShopify product ID of the target variant
intent_typestringunsentsentallType of intents to transfer (default is unsent/pending)
Response
Transfer completed successfully
Bad request - invalid parameters
Unauthorized
Transfer failed
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/intents/transfer_signups' \
-H 'Content-Type: application/json' \
-d '{
"from_shopify_variant_id": 43900910010503,
"from_shopify_product_id": 7891234567890,
"to_shopify_variant_id": 43900910010999,
"to_shopify_product_id": 7891234567890,
"intent_type": "unsent"
}'const response = await fetch('https://app.stoqapp.com/api/v1/intents/transfer_signups', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from_shopify_variant_id": 43900910010503,
"from_shopify_product_id": 7891234567890,
"to_shopify_variant_id": 43900910010999,
"to_shopify_product_id": 7891234567890,
"intent_type": "unsent"
}),
});
const data = await response.json();import requests
payload = {
"from_shopify_variant_id": 43900910010503,
"from_shopify_product_id": 7891234567890,
"to_shopify_variant_id": 43900910010999,
"to_shopify_product_id": 7891234567890,
"intent_type": "unsent"
}
response = requests.post('https://app.stoqapp.com/api/v1/intents/transfer_signups', json=payload)
data = response.json(){
"from_shopify_variant_id": 43900910010503,
"from_shopify_product_id": 7891234567890,
"to_shopify_variant_id": 43900910010999,
"to_shopify_product_id": 7891234567890,
"intent_type": "unsent"
}{
"error": "string"
}{
"errors": {}
}Preorders
Add multiple product variants to a selling plan
Attach one or more Shopify product variants to a selling plan so they become available for preorder. Pass the variant IDs in shopify_variant_ids; any that are already attached are reported back under existing_variants with a 422. Returns the list of variant IDs that were newly added.
Body
shopify_variant_idsArray<integer>requiredArray of Shopify variant IDs to add
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
Variants added successfully
Bad request - missing or invalid shopify_variant_ids
Unauthorized
Selling plan not found
Some variants already added or other error
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant' \
-H 'Content-Type: application/json' \
-d '{
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}),
});
const data = await response.json();import requests
payload = {
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}
response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant', json=payload)
data = response.json(){
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}{
"success": true,
"message": "2 variants added to selling plan",
"variants_added": [
43900910010503,
43900910010999
]
}{
"error": "string"
}{
"error": "string",
"existing_variants": [
0
]
}List and filter selling plans
List the shop's preorder selling plans, newest first, with page-based pagination. Optionally filter by name (matches the display or internal name). Returns a lightweight representation of each plan plus pagination metadata; use Get a Specific Selling Plan for the full object.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
namestringqueryFilter by selling plan name or internal name
pageintegerqueryPage number for pagination
per_pageintegerqueryNumber of items per page
Response
A paginated list of selling plans
Bad request
Unauthorized
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/external/preorders')
data = response.json(){
"selling_plans": [
{
"id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"selling_plan_product_variants_count": 12,
"created_at": "2026-06-20T10:00:00Z",
"updated_at": "2026-06-24T08:30:00Z",
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}
],
"meta": {
"total_count": 3,
"page": 1,
"per_page": 25,
"total_pages": 1
}
}Create a new selling plan
Create a new preorder selling plan. The selling_plan object defines billing, delivery, discount, button, badge, and fulfillment behavior; only the fields you set are applied and the rest fall back to defaults. Returns the created selling plan, including its STOQ ID, on success.
Body
selling_planSellingPlanInputInput schema for creating or updating selling plans
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
Response
Selling plan created successfully
Unauthorized
Validation errors
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders' \
-H 'Content-Type: application/json' \
-d '{
"selling_plan": {
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"product_variants_source": "custom"
}
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"selling_plan": {
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"product_variants_source": "custom"
}
}),
});
const data = await response.json();import requests
payload = {
"selling_plan": {
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": True,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": True,
"preorder_badge_text": "Preorder",
"product_variants_source": "custom"
}
}
response = requests.post('https://app.stoqapp.com/api/v1/external/preorders', json=payload)
data = response.json(){
"selling_plan": {
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"product_variants_source": "custom"
}
}{
"id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"selling_plan_product_variants_count": 0,
"shopify_selling_plan_id": null,
"shopify_selling_plan_group_id": null,
"shop_id": 43,
"created_at": "2026-06-20T10:00:00Z",
"updated_at": "2026-06-24T08:30:00Z",
"ongoing_job": false,
"shopify_variant_ids": []
}{
"errors": {}
}Get a specific selling plan
Retrieve a single preorder selling plan by its STOQ ID, including the full billing, delivery, pricing, button, badge, fulfillment, and market configuration, the count of attached variants, and the associated Shopify selling-plan IDs. Returns 404 if no plan with that ID exists for the shop.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
Selling plan details
Unauthorized
Selling plan not found
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders/{id}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/external/preorders/{id}')
data = response.json(){
"id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": true,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Preorder now",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"selling_plan_product_variants_count": 12,
"shopify_selling_plan_id": 645123456,
"shopify_selling_plan_group_id": 9912345,
"shop_id": 43,
"created_at": "2026-06-20T10:00:00Z",
"updated_at": "2026-06-24T08:30:00Z",
"ongoing_job": false,
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}Update a selling plan
Update an existing preorder selling plan. Supply a selling_plan object with the fields you want to change; omitted fields are left unchanged. Returns the updated selling plan, or 422 with validation errors if the changes are invalid.
Body
selling_planSellingPlanInputInput schema for creating or updating selling plans
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
Selling plan updated successfully
Unauthorized
Selling plan not found
Validation errors
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X PUT 'https://app.stoqapp.com/api/v1/external/preorders/{id}' \
-H 'Content-Type: application/json' \
-d '{
"selling_plan": {
"enabled": false,
"preorder_button_text": "Coming soon"
}
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"selling_plan": {
"enabled": false,
"preorder_button_text": "Coming soon"
}
}),
});
const data = await response.json();import requests
payload = {
"selling_plan": {
"enabled": False,
"preorder_button_text": "Coming soon"
}
}
response = requests.put('https://app.stoqapp.com/api/v1/external/preorders/{id}', json=payload)
data = response.json(){
"selling_plan": {
"enabled": false,
"preorder_button_text": "Coming soon"
}
}{
"id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
"name": "Summer Preorder",
"internal_name": "summer-2026",
"enabled": false,
"billing_type": "time_after_checkout",
"billing_checkout_charge_type": "percentage",
"billing_checkout_charge_percentage": 20,
"delivery_type": "asap",
"pricing_type": "no_discount",
"preorder_button_text": "Coming soon",
"preorder_badge_enabled": true,
"preorder_badge_text": "Preorder",
"selling_plan_product_variants_count": 12,
"shopify_selling_plan_id": 645123456,
"shopify_selling_plan_group_id": 9912345,
"shop_id": 43,
"created_at": "2026-06-20T10:00:00Z",
"updated_at": "2026-06-24T08:30:00Z",
"ongoing_job": false,
"shopify_variant_ids": [
43900910010503,
43900910010999
]
}{
"errors": {}
}Delete a selling plan (soft delete)
Soft-delete a preorder selling plan by ID. The plan is discarded (its discarded_at is set) and detached from the storefront, but historical preorder data is preserved. Returns 404 if the plan does not exist and 422 if it could not be deleted.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
Selling plan deleted successfully
Unauthorized
Selling plan not found
Failed to delete selling plan
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X DELETE 'https://app.stoqapp.com/api/v1/external/preorders/{id}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
method: 'DELETE',
});
const data = await response.json();import requests
response = requests.delete('https://app.stoqapp.com/api/v1/external/preorders/{id}')
data = response.json(){
"success": true,
"message": "Selling plan deleted"
}{
"error": "string"
}Get product variants associated with a selling plan
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)
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
shopify_product_idintegerqueryFilter by specific Shopify product ID to get all variants for that product
shopify_variant_idintegerqueryFilter by specific Shopify variant ID to get only that variant (returns single object)
Response
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
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants')
data = response.json(){
"selling_plan_id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
"selling_plan_name": "Summer Preorder",
"currency": "USD",
"product_variants": [
{
"shopify_product_id": 7891234567890,
"shopify_variant_id": 43900910010503,
"product_title": "Classic T-Shirt",
"variant_title": "Medium / Red",
"preorder_units_sold": 18,
"preorder_max_count": 100,
"shipping_text": "Ships July 2026"
}
],
"meta": {
"total_variants": 12,
"total_units_sold": 140
}
}{
"error": "string"
}{
"error": "string"
}Remove multiple product variants from a 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.
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
shopify_variant_idsArray<integer>requiredqueryArray of Shopify variant IDs to remove
inventory_policystringCONTINUEDENYqueryOptional. Inventory policy to set for the removed variants. CONTINUE allows overselling, DENY prevents it.
Response
Variants removed successfully
Bad request - missing or invalid parameters
Unauthorized
Selling plan or variants not found
Failed to remove variants or invalid inventory policy
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X DELETE 'https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant', {
method: 'DELETE',
});
const data = await response.json();import requests
response = requests.delete('https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant')
data = response.json(){
"success": true,
"message": "1 variant removed",
"variants_removed": [
43900910010503
],
"inventory_policy_updated": true,
"inventory_policy": "DENY"
}{
"error": "string"
}{
"error": "string"
}{
"error": "string"
}Send shipping update emails to multiple orders
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.
Body
order_idsArray<string>Array of STOQ internal order UUIDs to send shipping updates to (mutually exclusive with shopify_order_ids)
shopify_order_idsArray<integer>Array of Shopify order IDs to send shipping updates to (mutually exclusive with order_ids)
subjectstringrequiredEmail subject line
headerstringrequiredEmail header text
descriptionstringrequiredEmail body description
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
Response
Shipping update emails queued successfully
Bad request - missing required parameters or invalid input
Unauthorized
No valid orders found
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update' \
-H 'Content-Type: application/json' \
-d '{
"shopify_order_ids": [
5012345678901,
5012345678902
],
"subject": "Your preorder has shipped",
"header": "Good news!",
"description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shopify_order_ids": [
5012345678901,
5012345678902
],
"subject": "Your preorder has shipped",
"header": "Good news!",
"description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}),
});
const data = await response.json();import requests
payload = {
"shopify_order_ids": [
5012345678901,
5012345678902
],
"subject": "Your preorder has shipped",
"header": "Good news!",
"description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}
response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update', json=payload)
data = response.json(){
"shopify_order_ids": [
5012345678901,
5012345678902
],
"subject": "Your preorder has shipped",
"header": "Good news!",
"description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}{
"success": true,
"message": "Shipping updates queued",
"orders_count": 2
}{
"error": "string"
}{
"error": "string"
}Queue a bulk update of inventory policy for multiple variants
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.
Body
shopify_variant_idsArray<integer>requiredArray of Shopify variant IDs to update
inventory_policystringCONTINUEDENYrequiredThe inventory policy to set for the variants
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
Inventory policy update has been queued successfully
Bad request - missing or invalid parameters
Unauthorized
Selling plan not found
Invalid inventory policy
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy' \
-H 'Content-Type: application/json' \
-d '{
"shopify_variant_ids": [
43900910010503,
43900910010999
],
"inventory_policy": "CONTINUE"
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shopify_variant_ids": [
43900910010503,
43900910010999
],
"inventory_policy": "CONTINUE"
}),
});
const data = await response.json();import requests
payload = {
"shopify_variant_ids": [
43900910010503,
43900910010999
],
"inventory_policy": "CONTINUE"
}
response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy', json=payload)
data = response.json(){
"shopify_variant_ids": [
43900910010503,
43900910010999
],
"inventory_policy": "CONTINUE"
}{
"success": true,
"message": "Inventory policy update queued",
"variants_queued": [
43900910010503,
43900910010999
]
}{
"error": "string"
}{
"error": "string"
}{
"error": "string"
}Update variant-specific settings for a selling plan
Update per-variant preorder settings within a selling plan, such as the variant's custom shipping_text and preorder_max_count (the cap on preorder units). Identify the variant with shopify_variant_id; only the settings you include are changed. Returns the updated variant settings.
Body
shopify_variant_idintegerrequiredShopify variant ID to update settings for
shipping_textstringCustom shipping text for this variant
preorder_max_countintegerMaximum number of preorders allowed for this variant
Parameters
X-Auth-TokenstringrequiredheaderAPI key for authentication
idstringrequiredpathSelling plan ID
Response
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
Authorization
ApiKeyAuthapiKey in headerAuthenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.
curl -X PATCH 'https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings' \
-H 'Content-Type: application/json' \
-d '{
"shopify_variant_id": 43900910010503,
"shipping_text": "Ships July 2026",
"preorder_max_count": 100
}'const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shopify_variant_id": 43900910010503,
"shipping_text": "Ships July 2026",
"preorder_max_count": 100
}),
});
const data = await response.json();import requests
payload = {
"shopify_variant_id": 43900910010503,
"shipping_text": "Ships July 2026",
"preorder_max_count": 100
}
response = requests.patch('https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings', json=payload)
data = response.json(){
"shopify_variant_id": 43900910010503,
"shipping_text": "Ships July 2026",
"preorder_max_count": 100
}{
"success": true,
"message": "Variant settings updated",
"variant": {
"shopify_variant_id": 43900910010503,
"shipping_text": "Ships July 2026",
"preorder_max_count": 100
}
}{
"error": "string"
}{
"error": "string"
}{
"error": "string",
"details": [
"string"
]
}Models
Intent
objectidstringUnique identifier for the intent
blocked_atstring<date-time> | nullTimestamp when the intent was blocked from sending
channelstringCommunication channel used for notifications (e.g., Email, SMS)
emailstringCustomer's email address for notifications
notified_atstring<date-time> | nullTimestamp of the notification sent
optin_confirmedbooleanWhether the customer has confirmed their GDPR opt-in for notifications
phonestringCustomer's phone number for SMS notifications
quantityintegerRequested quantity of the product when back in stock
sent_notifications_countintegerNumber of notifications sent for this intent
sourcestringtypestringType of the intent (e.g., restock, wishlist_reminder)
unsubscribed_atstring<date-time> | nullTimestamp when the customer unsubscribed from notifications
created_atstring<date-time>Timestamp when the intent was created
updated_atstring<date-time>Timestamp when the intent was last updated
customer_idstringUnique identifier for the customer
intent_trigger_idstring | nullIdentifier for the trigger that created this intent
product_variant_idstring | nullInternal product variant identifier
shop_idstringUnique identifier for the shop
shopify_inventory_item_idinteger | nullShopify's inventory item identifier
shopify_market_idinteger | nullShopify's market identifier for multi-market stores
shopify_product_idinteger | nullShopify's product identifier
shopify_variant_idinteger | nullShopify's variant identifier
customer_namestring | nullCustomer's full name
contactstring | nullCustomer's contact information
customer_unsubscribed_atstring<date-time> | nullTimestamp when the customer unsubscribed from all notifications
accepts_marketingboolean | nullWhether the customer has opted in to receive marketing communications
notifications_countinteger | nullTotal number of notifications sent for this intent
{
"id": "string",
"blocked_at": "2024-01-15T09:30:00Z",
"channel": "string",
"email": "string",
"notified_at": "2024-01-15T09:30:00Z",
"optin_confirmed": true,
"phone": "string",
"quantity": 0,
"sent_notifications_count": 0,
"source": "string",
"type": "string",
"unsubscribed_at": "2024-01-15T09:30:00Z",
"created_at": "2024-01-15T09:30:00Z",
"updated_at": "2024-01-15T09:30:00Z",
"customer_id": "string",
"intent_trigger_id": "string",
"product_variant_id": "string",
"shop_id": "string",
"shopify_inventory_item_id": 0,
"shopify_market_id": 0,
"shopify_product_id": 0,
"shopify_variant_id": 0,
"customer_name": "string",
"contact": "string",
"customer_unsubscribed_at": "2024-01-15T09:30:00Z",
"accepts_marketing": true,
"notifications_count": 0
}ProductVariantDemand
objectProduct variant with demand metrics and product data
shopify_variant_idintegerShopify variant identifier
shopify_product_idintegerShopify product identifier
shopify_inventory_item_idinteger | nullShopify inventory item identifier
totalintegerTotal number of intents (both pending and sent) for this variant
pendingintegerNumber of pending (unsent) intents for this variant
last_requested_atstring<date-time> | nullTimestamp of the most recent intent created for this variant
product_dataobject | nullShopify product data including variants
variant_dataobject | nullSpecific variant data for this demand entry
{
"shopify_variant_id": 0,
"shopify_product_id": 0,
"shopify_inventory_item_id": 0,
"total": 0,
"pending": 0,
"last_requested_at": "2024-01-15T09:30:00Z",
"product_data": {
"id": 0,
"title": "string",
"vendor": "string",
"variants": [
{
"id": 0,
"title": "string",
"sku": "string"
}
]
},
"variant_data": {
"id": 0,
"title": "string",
"sku": "string"
}
}SellingPlanInput
objectInput schema for creating or updating selling plans
namestringDisplay name of the selling plan
internal_namestringInternal name for the selling plan
enabledbooleanWhether the selling plan is enabled
billing_typestringexact_timeno_remaining_balancetime_after_checkoutType of billing for the selling plan
billing_atstring<date-time>Exact billing time if billing_type is exact_time
billing_after_n_intervalsintegerNumber of intervals after checkout to bill
billing_after_interval_typestringdayType of interval for billing
billing_checkout_charge_amountnumberFixed amount to charge at checkout
billing_checkout_charge_percentagenumberPercentage to charge at checkout
billing_checkout_charge_typestringpercentagepriceType of checkout charge
billing_titlestringTitle for billing section
billing_descriptionstringDescription for billing section
delivery_typestringanchorasapexact_timeunknownType of delivery for the selling plan
delivery_atstring<date-time>Exact delivery time if delivery_type is exact_time
delivery_after_n_intervalsintegerNumber of intervals after checkout for delivery
delivery_after_interval_typestringdayType of interval for delivery
inventory_reserve_typestringon_saleon_fulfillmentWhen to reserve inventory
inventory_providerstringstoqshopifyInventory provider
pricing_typestringpercentagepricefixed_amountno_discountType of pricing discount
pricing_amountnumberFixed discount amount
pricing_percentagenumberPercentage discount
quantity_limit_textstringText to display for quantity limits
preorder_button_textstringText for the preorder button
preorder_button_text_colorstringText color for the preorder button
preorder_button_background_colorstringBackground color for the preorder button
preorder_button_colors_enabledbooleanWhether custom colors are enabled for the preorder button
preorder_discounted_price_enabledbooleanWhether to show discounted price on the preorder button
preorder_button_descriptionstringDescription text for the preorder button
preorder_button_description_background_colorstringBackground color for the preorder button description
preorder_button_description_border_radiusstringBorder radius for the preorder button description
preorder_button_description_quantity_limit_suffixstringSuffix text for quantity limit in button description
preorder_button_description_shipping_text_prefixstringPrefix text for shipping information in button description
preorder_button_description_show_quantity_limitbooleanWhether to show quantity limit in button description
preorder_button_description_show_shippingbooleanWhether to show shipping information in button description
preorder_button_description_text_colorstringText color for the preorder button description
preorder_badge_enabledbooleanWhether preorder badge is enabled
preorder_badge_textstringText for the preorder badge
preorder_badge_text_colorstringText color for the preorder badge
preorder_badge_background_colorstringBackground color for the preorder badge
preorder_shipping_textstringShipping text specific to preorders
shipping_textstringShipping information text
shipping_line_item_property_enabledbooleanWhether to enable shipping line item properties
shipping_applies_to_all_productsbooleanWhether shipping settings apply to all products
discount_textstringDiscount information text
preorder_tagsstringTags to apply to preorder items
product_variants_sourcestringallcollectioncustomSource of product variants for this selling plan
product_variants_source_idintegerID of the source (e.g., collection ID)
markets_enabledbooleanWhether market-specific settings are enabled for this selling plan
shopify_market_idsArray<integer>List of Shopify market IDs where this selling plan is available. Required if markets_enabled is true.
auto_collect_paymentbooleanWhether to automatically collect payment when the order is ready to fulfill
use_shopify_selling_planbooleanWhether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.
enable_billing_widgetbooleanWhether to display the payment/billing widget on the product page
split_fulfillments_enabledbooleanWhether to enable split fulfillments for preorders. When enabled, preorder items can be shipped separately from regular items in the same order.
require_preorder_acknowledgementbooleanWhether customers must accept terms and conditions before adding a preorder item to their cart.
preorder_acknowledgement_textstringThe terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.
allow_mixed_cartbooleanWhether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.
mixed_cart_error_messagestringError message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).
preorder_min_quantityintegerMinimum quantity required per order for preorder items. When set, customers must purchase at least this many units.
preorder_max_quantityintegerMaximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.
payment_line_item_property_enabledbooleanWhether to add payment information as a line item property (e.g., "Payment - Pay in full").
custom_line_item_property_textstringCustom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.
auto_collect_payment_on_fulfillmentbooleanWhether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).
hold_fulfillments_enabledbooleanWhether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.
hold_fulfillments_reason_notestringThe reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).
disable_button_until_acknowledgedbooleanWhether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).
{
"name": "string",
"internal_name": "string",
"enabled": true,
"billing_type": "exact_time",
"billing_at": "2024-01-15T09:30:00Z",
"billing_after_n_intervals": 0,
"billing_after_interval_type": "day",
"billing_checkout_charge_amount": 0,
"billing_checkout_charge_percentage": 0,
"billing_checkout_charge_type": "percentage",
"billing_title": "string",
"billing_description": "string",
"delivery_type": "anchor",
"delivery_at": "2024-01-15T09:30:00Z",
"delivery_after_n_intervals": 0,
"delivery_after_interval_type": "day",
"inventory_reserve_type": "on_sale",
"inventory_provider": "stoq",
"pricing_type": "percentage",
"pricing_amount": 0,
"pricing_percentage": 0,
"quantity_limit_text": "string",
"preorder_button_text": "string",
"preorder_button_text_color": "string",
"preorder_button_background_color": "string",
"preorder_button_colors_enabled": true,
"preorder_discounted_price_enabled": true,
"preorder_button_description": "string",
"preorder_button_description_background_color": "string",
"preorder_button_description_border_radius": "string",
"preorder_button_description_quantity_limit_suffix": "string",
"preorder_button_description_shipping_text_prefix": "string",
"preorder_button_description_show_quantity_limit": true,
"preorder_button_description_show_shipping": true,
"preorder_button_description_text_color": "string",
"preorder_badge_enabled": true,
"preorder_badge_text": "string",
"preorder_badge_text_color": "string",
"preorder_badge_background_color": "string",
"preorder_shipping_text": "string",
"shipping_text": "string",
"shipping_line_item_property_enabled": true,
"shipping_applies_to_all_products": true,
"discount_text": "string",
"preorder_tags": "string",
"product_variants_source": "all",
"product_variants_source_id": 0,
"markets_enabled": true,
"shopify_market_ids": [
0
],
"auto_collect_payment": true,
"use_shopify_selling_plan": true,
"enable_billing_widget": true,
"split_fulfillments_enabled": true,
"require_preorder_acknowledgement": true,
"preorder_acknowledgement_text": "string",
"allow_mixed_cart": true,
"mixed_cart_error_message": "string",
"preorder_min_quantity": 0,
"preorder_max_quantity": 0,
"payment_line_item_property_enabled": true,
"custom_line_item_property_text": "string",
"auto_collect_payment_on_fulfillment": true,
"hold_fulfillments_enabled": true,
"hold_fulfillments_reason_note": "string",
"disable_button_until_acknowledged": true
}SellingPlan
objectidstringUnique identifier for the selling plan
namestringDisplay name of the selling plan
internal_namestringInternal name for the selling plan
enabledbooleanWhether the selling plan is enabled
billing_typestringexact_timeno_remaining_balancetime_after_checkoutType of billing for the selling plan
billing_atstring<date-time> | nullExact billing time if billing_type is exact_time
billing_after_n_intervalsinteger | nullNumber of intervals after checkout to bill
billing_after_interval_typestringdayType of interval for billing
billing_checkout_charge_amountnumber | nullFixed amount to charge at checkout
billing_checkout_charge_percentagenumber | nullPercentage to charge at checkout
billing_checkout_charge_typestringpercentagepriceType of checkout charge
billing_titlestringTitle for billing section
billing_descriptionstringDescription for billing section
delivery_typestringanchorasapexact_timeunknownType of delivery for the selling plan
delivery_atstring<date-time> | nullExact delivery time if delivery_type is exact_time
delivery_after_n_intervalsinteger | nullNumber of intervals after checkout for delivery
delivery_after_interval_typestringdayType of interval for delivery
inventory_reserve_typestringon_saleon_fulfillmentWhen to reserve inventory
inventory_providerstringstoqshopifyInventory provider
pricing_typestringpercentagepricefixed_amountno_discountType of pricing discount
pricing_amountnumber | nullFixed discount amount
pricing_percentagenumber | nullPercentage discount
quantity_limit_textstringText to display for quantity limits
preorder_button_textstringText for the preorder button
preorder_button_text_colorstringText color for the preorder button
preorder_button_background_colorstringBackground color for the preorder button
preorder_button_colors_enabledbooleanWhether custom colors are enabled for the preorder button
preorder_discounted_price_enabledbooleanWhether to show discounted price on the preorder button
preorder_button_descriptionstringDescription text for the preorder button
preorder_button_description_background_colorstringBackground color for the preorder button description
preorder_button_description_border_radiusstringBorder radius for the preorder button description
preorder_button_description_quantity_limit_suffixstringSuffix text for quantity limit in button description
preorder_button_description_shipping_text_prefixstringPrefix text for shipping information in button description
preorder_button_description_show_quantity_limitbooleanWhether to show quantity limit in button description
preorder_button_description_show_shippingbooleanWhether to show shipping information in button description
preorder_button_description_text_colorstringText color for the preorder button description
preorder_badge_enabledbooleanWhether preorder badge is enabled
preorder_badge_textstringText for the preorder badge
preorder_badge_text_colorstringText color for the preorder badge
preorder_badge_background_colorstringBackground color for the preorder badge
preorder_shipping_textstringShipping text specific to preorders
shipping_textstringShipping information text
shipping_line_item_property_enabledbooleanWhether to enable shipping line item properties
shipping_applies_to_all_productsbooleanWhether shipping settings apply to all products
discount_textstringDiscount information text
preorder_tagsstringTags to apply to preorder items
product_variants_sourcestringallcollectioncustomSource of product variants for this selling plan
product_variants_source_idinteger | nullID of the source (e.g., collection ID)
selling_plan_product_variants_countintegerNumber of product variants associated with this selling plan
shopify_selling_plan_idinteger | nullShopify selling plan ID
shopify_selling_plan_group_idinteger | nullShopify selling plan group ID
use_shopify_selling_planbooleanWhether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.
enable_billing_widgetbooleanWhether to display the payment/billing widget on the product page
split_fulfillments_enabledbooleanWhether to enable split fulfillments for preorders. When enabled, preorders will be separted into its own fulfillment order.
require_preorder_acknowledgementbooleanWhether customers must accept terms and conditions before adding a preorder item to their cart.
preorder_acknowledgement_textstringThe terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.
allow_mixed_cartbooleanWhether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.
mixed_cart_error_messagestringError message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).
preorder_min_quantityinteger | nullMinimum quantity required per order for preorder items. When set, customers must purchase at least this many units.
preorder_max_quantityinteger | nullMaximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.
payment_line_item_property_enabledbooleanWhether to add payment information as a line item property (e.g., "Payment - Pay in full").
custom_line_item_property_textstring | nullCustom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.
auto_collect_payment_on_fulfillmentbooleanWhether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).
hold_fulfillments_enabledbooleanWhether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.
hold_fulfillments_reason_notestringThe reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).
disable_button_until_acknowledgedbooleanWhether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).
shop_idintegerShop ID this selling plan belongs to
market_idinteger | nullMarket ID for multi-market stores
created_atstring<date-time>Timestamp when the selling plan was created
updated_atstring<date-time>Timestamp when the selling plan was last updated
discarded_atstring<date-time> | nullTimestamp when the selling plan was soft deleted
ongoing_jobbooleanWhether there is an ongoing job for this selling plan
shopify_variant_idsArray<integer>List of Shopify variant IDs associated with this selling plan
{
"id": "string",
"name": "string",
"internal_name": "string",
"enabled": true,
"billing_type": "exact_time",
"billing_at": "2024-01-15T09:30:00Z",
"billing_after_n_intervals": 0,
"billing_after_interval_type": "day",
"billing_checkout_charge_amount": 0,
"billing_checkout_charge_percentage": 0,
"billing_checkout_charge_type": "percentage",
"billing_title": "string",
"billing_description": "string",
"delivery_type": "anchor",
"delivery_at": "2024-01-15T09:30:00Z",
"delivery_after_n_intervals": 0,
"delivery_after_interval_type": "day",
"inventory_reserve_type": "on_sale",
"inventory_provider": "stoq",
"pricing_type": "percentage",
"pricing_amount": 0,
"pricing_percentage": 0,
"quantity_limit_text": "string",
"preorder_button_text": "string",
"preorder_button_text_color": "string",
"preorder_button_background_color": "string",
"preorder_button_colors_enabled": true,
"preorder_discounted_price_enabled": true,
"preorder_button_description": "string",
"preorder_button_description_background_color": "string",
"preorder_button_description_border_radius": "string",
"preorder_button_description_quantity_limit_suffix": "string",
"preorder_button_description_shipping_text_prefix": "string",
"preorder_button_description_show_quantity_limit": true,
"preorder_button_description_show_shipping": true,
"preorder_button_description_text_color": "string",
"preorder_badge_enabled": true,
"preorder_badge_text": "string",
"preorder_badge_text_color": "string",
"preorder_badge_background_color": "string",
"preorder_shipping_text": "string",
"shipping_text": "string",
"shipping_line_item_property_enabled": true,
"shipping_applies_to_all_products": true,
"discount_text": "string",
"preorder_tags": "string",
"product_variants_source": "all",
"product_variants_source_id": 0,
"selling_plan_product_variants_count": 0,
"shopify_selling_plan_id": 0,
"shopify_selling_plan_group_id": 0,
"use_shopify_selling_plan": true,
"enable_billing_widget": true,
"split_fulfillments_enabled": true,
"require_preorder_acknowledgement": true,
"preorder_acknowledgement_text": "string",
"allow_mixed_cart": true,
"mixed_cart_error_message": "string",
"preorder_min_quantity": 0,
"preorder_max_quantity": 0,
"payment_line_item_property_enabled": true,
"custom_line_item_property_text": "string",
"auto_collect_payment_on_fulfillment": true,
"hold_fulfillments_enabled": true,
"hold_fulfillments_reason_note": "string",
"disable_button_until_acknowledged": true,
"shop_id": 0,
"market_id": 0,
"created_at": "2024-01-15T09:30:00Z",
"updated_at": "2024-01-15T09:30:00Z",
"discarded_at": "2024-01-15T09:30:00Z",
"ongoing_job": true,
"shopify_variant_ids": [
0
]
}SellingPlanProductVariantsResponse
objectselling_plan_idstringID of the selling plan
selling_plan_namestringName of the selling plan
currencystringShop currency code
product_variantsArray<ProductVariantDetails>List of product variants associated with this selling plan
metaobject{
"selling_plan_id": "string",
"selling_plan_name": "string",
"currency": "string",
"product_variants": [
{
"shopify_product_id": 0,
"shopify_variant_id": 0,
"product_title": "string",
"variant_title": "string",
"preorder_units_sold": 0,
"preorder_max_count": 0,
"shipping_text": "string"
}
],
"meta": {
"total_variants": 0,
"total_units_sold": 0
}
}ProductVariantDetails
objectshopify_product_idintegerShopify product ID
shopify_variant_idintegerShopify variant ID
product_titlestringProduct title
variant_titlestringVariant title (null for single-variant products)
preorder_units_soldintegerTotal units sold through preorders for this variant
preorder_max_countinteger | nullMaximum number of preorders allowed for this variant
shipping_textstring | nullCustom shipping text configured for this variant in the selling plan
{
"shopify_product_id": 0,
"shopify_variant_id": 0,
"product_title": "string",
"variant_title": "string",
"preorder_units_sold": 0,
"preorder_max_count": 0,
"shipping_text": "string"
}SellingPlanSingleVariantResponse
objectselling_plan_idstringID of the selling plan
selling_plan_namestringName of the selling plan
currencystringShop currency code
product_variantProductVariantDetailsmetaobject{
"selling_plan_id": "string",
"selling_plan_name": "string",
"currency": "string",
"product_variant": {
"shopify_product_id": 0,
"shopify_variant_id": 0,
"product_title": "string",
"variant_title": "string",
"preorder_units_sold": 0,
"preorder_max_count": 0,
"shipping_text": "string"
},
"meta": {
"total_units_sold": 0
}
}SellingPlanList
objectSimplified selling plan object for list views
idstringUnique identifier for the selling plan
namestringDisplay name of the selling plan
internal_namestringInternal name for the selling plan
enabledbooleanWhether the selling plan is enabled
selling_plan_product_variants_countintegerNumber of product variants associated with this selling plan
created_atstring<date-time>Timestamp when the selling plan was created
updated_atstring<date-time>Timestamp when the selling plan was last updated
shopify_variant_idsArray<integer>List of Shopify variant IDs associated with this selling plan
{
"id": "string",
"name": "string",
"internal_name": "string",
"enabled": true,
"selling_plan_product_variants_count": 0,
"created_at": "2024-01-15T09:30:00Z",
"updated_at": "2024-01-15T09:30:00Z",
"shopify_variant_ids": [
0
]
}